LCOV - code coverage report
Current view: top level - gcc/config/i386 - i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.1 % 12274 10933
Test Date: 2025-03-08 13:07:09 Functions: 95.7 % 446 427
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Subroutines used for code generation on IA-32.
       2                 :             :    Copyright (C) 1988-2025 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify
       7                 :             : it under the terms of the GNU General Public License as published by
       8                 :             : the Free Software Foundation; either version 3, or (at your option)
       9                 :             : any later version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful,
      12                 :             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :             : GNU General Public License for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #define INCLUDE_STRING
      21                 :             : #define IN_TARGET_CODE 1
      22                 :             : 
      23                 :             : #include "config.h"
      24                 :             : #include "system.h"
      25                 :             : #include "coretypes.h"
      26                 :             : #include "backend.h"
      27                 :             : #include "rtl.h"
      28                 :             : #include "tree.h"
      29                 :             : #include "memmodel.h"
      30                 :             : #include "gimple.h"
      31                 :             : #include "cfghooks.h"
      32                 :             : #include "cfgloop.h"
      33                 :             : #include "df.h"
      34                 :             : #include "tm_p.h"
      35                 :             : #include "stringpool.h"
      36                 :             : #include "expmed.h"
      37                 :             : #include "optabs.h"
      38                 :             : #include "regs.h"
      39                 :             : #include "emit-rtl.h"
      40                 :             : #include "recog.h"
      41                 :             : #include "cgraph.h"
      42                 :             : #include "diagnostic.h"
      43                 :             : #include "cfgbuild.h"
      44                 :             : #include "alias.h"
      45                 :             : #include "fold-const.h"
      46                 :             : #include "attribs.h"
      47                 :             : #include "calls.h"
      48                 :             : #include "stor-layout.h"
      49                 :             : #include "varasm.h"
      50                 :             : #include "output.h"
      51                 :             : #include "insn-attr.h"
      52                 :             : #include "flags.h"
      53                 :             : #include "except.h"
      54                 :             : #include "explow.h"
      55                 :             : #include "expr.h"
      56                 :             : #include "cfgrtl.h"
      57                 :             : #include "common/common-target.h"
      58                 :             : #include "langhooks.h"
      59                 :             : #include "reload.h"
      60                 :             : #include "gimplify.h"
      61                 :             : #include "dwarf2.h"
      62                 :             : #include "tm-constrs.h"
      63                 :             : #include "cselib.h"
      64                 :             : #include "sched-int.h"
      65                 :             : #include "opts.h"
      66                 :             : #include "tree-pass.h"
      67                 :             : #include "context.h"
      68                 :             : #include "pass_manager.h"
      69                 :             : #include "target-globals.h"
      70                 :             : #include "gimple-iterator.h"
      71                 :             : #include "gimple-fold.h"
      72                 :             : #include "tree-vectorizer.h"
      73                 :             : #include "shrink-wrap.h"
      74                 :             : #include "builtins.h"
      75                 :             : #include "rtl-iter.h"
      76                 :             : #include "tree-iterator.h"
      77                 :             : #include "dbgcnt.h"
      78                 :             : #include "case-cfn-macros.h"
      79                 :             : #include "dojump.h"
      80                 :             : #include "fold-const-call.h"
      81                 :             : #include "tree-vrp.h"
      82                 :             : #include "tree-ssanames.h"
      83                 :             : #include "selftest.h"
      84                 :             : #include "selftest-rtl.h"
      85                 :             : #include "print-rtl.h"
      86                 :             : #include "intl.h"
      87                 :             : #include "ifcvt.h"
      88                 :             : #include "symbol-summary.h"
      89                 :             : #include "sreal.h"
      90                 :             : #include "ipa-cp.h"
      91                 :             : #include "ipa-prop.h"
      92                 :             : #include "ipa-fnsummary.h"
      93                 :             : #include "wide-int-bitmask.h"
      94                 :             : #include "tree-vector-builder.h"
      95                 :             : #include "debug.h"
      96                 :             : #include "dwarf2out.h"
      97                 :             : #include "i386-options.h"
      98                 :             : #include "i386-builtins.h"
      99                 :             : #include "i386-expand.h"
     100                 :             : #include "i386-features.h"
     101                 :             : #include "function-abi.h"
     102                 :             : #include "rtl-error.h"
     103                 :             : 
     104                 :             : /* This file should be included last.  */
     105                 :             : #include "target-def.h"
     106                 :             : 
     107                 :             : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
     108                 :             : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
     109                 :             : 
     110                 :             : 
     111                 :             : #ifndef CHECK_STACK_LIMIT
     112                 :             : #define CHECK_STACK_LIMIT (-1)
     113                 :             : #endif
     114                 :             : 
     115                 :             : /* Return index of given mode in mult and division cost tables.  */
     116                 :             : #define MODE_INDEX(mode)                                        \
     117                 :             :   ((mode) == QImode ? 0                                         \
     118                 :             :    : (mode) == HImode ? 1                                       \
     119                 :             :    : (mode) == SImode ? 2                                       \
     120                 :             :    : (mode) == DImode ? 3                                       \
     121                 :             :    : 4)
     122                 :             : 
     123                 :             : 
     124                 :             : /* Set by -mtune.  */
     125                 :             : const struct processor_costs *ix86_tune_cost = NULL;
     126                 :             : 
     127                 :             : /* Set by -mtune or -Os.  */
     128                 :             : const struct processor_costs *ix86_cost = NULL;
     129                 :             : 
     130                 :             : /* In case the average insn count for single function invocation is
     131                 :             :    lower than this constant, emit fast (but longer) prologue and
     132                 :             :    epilogue code.  */
     133                 :             : #define FAST_PROLOGUE_INSN_COUNT 20
     134                 :             : 
     135                 :             : /* Names for 8 (low), 8 (high), and 16-bit registers, respectively.  */
     136                 :             : static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
     137                 :             : static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
     138                 :             : static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
     139                 :             : 
     140                 :             : /* Array of the smallest class containing reg number REGNO, indexed by
     141                 :             :    REGNO.  Used by REGNO_REG_CLASS in i386.h.  */
     142                 :             : 
     143                 :             : enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
     144                 :             : {
     145                 :             :   /* ax, dx, cx, bx */
     146                 :             :   AREG, DREG, CREG, BREG,
     147                 :             :   /* si, di, bp, sp */
     148                 :             :   SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
     149                 :             :   /* FP registers */
     150                 :             :   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
     151                 :             :   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
     152                 :             :   /* arg pointer, flags, fpsr, frame */
     153                 :             :   NON_Q_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
     154                 :             :   /* SSE registers */
     155                 :             :   SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS,
     156                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     157                 :             :   /* MMX registers */
     158                 :             :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     159                 :             :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     160                 :             :   /* REX registers */
     161                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     162                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     163                 :             :   /* SSE REX registers */
     164                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     165                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     166                 :             :   /* AVX-512 SSE registers */
     167                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     168                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     169                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     170                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     171                 :             :   /* Mask registers.  */
     172                 :             :   ALL_MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     173                 :             :   MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     174                 :             :   /* REX2 registers */
     175                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     176                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     177                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     178                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     179                 :             : };
     180                 :             : 
     181                 :             : /* The "default" register map used in 32bit mode.  */
     182                 :             : 
     183                 :             : unsigned int const debugger_register_map[FIRST_PSEUDO_REGISTER] =
     184                 :             : {
     185                 :             :   /* general regs */
     186                 :             :   0, 2, 1, 3, 6, 7, 4, 5,
     187                 :             :   /* fp regs */
     188                 :             :   12, 13, 14, 15, 16, 17, 18, 19,
     189                 :             :   /* arg, flags, fpsr, frame */
     190                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     191                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     192                 :             :   /* SSE */
     193                 :             :   21, 22, 23, 24, 25, 26, 27, 28,
     194                 :             :   /* MMX */
     195                 :             :   29, 30, 31, 32, 33, 34, 35, 36,
     196                 :             :   /* extended integer registers */
     197                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     198                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     199                 :             :   /* extended sse registers */
     200                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     201                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     202                 :             :   /* AVX-512 registers 16-23 */
     203                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     204                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     205                 :             :   /* AVX-512 registers 24-31 */
     206                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     207                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     208                 :             :   /* Mask registers */
     209                 :             :   93, 94, 95, 96, 97, 98, 99, 100
     210                 :             : };
     211                 :             : 
     212                 :             : /* The "default" register map used in 64bit mode.  */
     213                 :             : 
     214                 :             : unsigned int const debugger64_register_map[FIRST_PSEUDO_REGISTER] =
     215                 :             : {
     216                 :             :   /* general regs */
     217                 :             :   0, 1, 2, 3, 4, 5, 6, 7,
     218                 :             :   /* fp regs */
     219                 :             :   33, 34, 35, 36, 37, 38, 39, 40,
     220                 :             :   /* arg, flags, fpsr, frame */
     221                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     222                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     223                 :             :   /* SSE */
     224                 :             :   17, 18, 19, 20, 21, 22, 23, 24,
     225                 :             :   /* MMX */
     226                 :             :   41, 42, 43, 44, 45, 46, 47, 48,
     227                 :             :   /* extended integer registers */
     228                 :             :   8, 9, 10, 11, 12, 13, 14, 15,
     229                 :             :   /* extended SSE registers */
     230                 :             :   25, 26, 27, 28, 29, 30, 31, 32,
     231                 :             :   /* AVX-512 registers 16-23 */
     232                 :             :   67, 68, 69, 70, 71, 72, 73, 74,
     233                 :             :   /* AVX-512 registers 24-31 */
     234                 :             :   75, 76, 77, 78, 79, 80, 81, 82,
     235                 :             :   /* Mask registers */
     236                 :             :   118, 119, 120, 121, 122, 123, 124, 125,
     237                 :             :   /* rex2 extend interger registers */
     238                 :             :   130, 131, 132, 133, 134, 135, 136, 137,
     239                 :             :   138, 139, 140, 141, 142, 143, 144, 145
     240                 :             : };
     241                 :             : 
     242                 :             : /* Define the register numbers to be used in Dwarf debugging information.
     243                 :             :    The SVR4 reference port C compiler uses the following register numbers
     244                 :             :    in its Dwarf output code:
     245                 :             :         0 for %eax (gcc regno = 0)
     246                 :             :         1 for %ecx (gcc regno = 2)
     247                 :             :         2 for %edx (gcc regno = 1)
     248                 :             :         3 for %ebx (gcc regno = 3)
     249                 :             :         4 for %esp (gcc regno = 7)
     250                 :             :         5 for %ebp (gcc regno = 6)
     251                 :             :         6 for %esi (gcc regno = 4)
     252                 :             :         7 for %edi (gcc regno = 5)
     253                 :             :    The following three DWARF register numbers are never generated by
     254                 :             :    the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
     255                 :             :    believed these numbers have these meanings.
     256                 :             :         8  for %eip    (no gcc equivalent)
     257                 :             :         9  for %eflags (gcc regno = 17)
     258                 :             :         10 for %trapno (no gcc equivalent)
     259                 :             :    It is not at all clear how we should number the FP stack registers
     260                 :             :    for the x86 architecture.  If the version of SDB on x86/svr4 were
     261                 :             :    a bit less brain dead with respect to floating-point then we would
     262                 :             :    have a precedent to follow with respect to DWARF register numbers
     263                 :             :    for x86 FP registers, but the SDB on x86/svr4 was so completely
     264                 :             :    broken with respect to FP registers that it is hardly worth thinking
     265                 :             :    of it as something to strive for compatibility with.
     266                 :             :    The version of x86/svr4 SDB I had does (partially)
     267                 :             :    seem to believe that DWARF register number 11 is associated with
     268                 :             :    the x86 register %st(0), but that's about all.  Higher DWARF
     269                 :             :    register numbers don't seem to be associated with anything in
     270                 :             :    particular, and even for DWARF regno 11, SDB only seemed to under-
     271                 :             :    stand that it should say that a variable lives in %st(0) (when
     272                 :             :    asked via an `=' command) if we said it was in DWARF regno 11,
     273                 :             :    but SDB still printed garbage when asked for the value of the
     274                 :             :    variable in question (via a `/' command).
     275                 :             :    (Also note that the labels SDB printed for various FP stack regs
     276                 :             :    when doing an `x' command were all wrong.)
     277                 :             :    Note that these problems generally don't affect the native SVR4
     278                 :             :    C compiler because it doesn't allow the use of -O with -g and
     279                 :             :    because when it is *not* optimizing, it allocates a memory
     280                 :             :    location for each floating-point variable, and the memory
     281                 :             :    location is what gets described in the DWARF AT_location
     282                 :             :    attribute for the variable in question.
     283                 :             :    Regardless of the severe mental illness of the x86/svr4 SDB, we
     284                 :             :    do something sensible here and we use the following DWARF
     285                 :             :    register numbers.  Note that these are all stack-top-relative
     286                 :             :    numbers.
     287                 :             :         11 for %st(0) (gcc regno = 8)
     288                 :             :         12 for %st(1) (gcc regno = 9)
     289                 :             :         13 for %st(2) (gcc regno = 10)
     290                 :             :         14 for %st(3) (gcc regno = 11)
     291                 :             :         15 for %st(4) (gcc regno = 12)
     292                 :             :         16 for %st(5) (gcc regno = 13)
     293                 :             :         17 for %st(6) (gcc regno = 14)
     294                 :             :         18 for %st(7) (gcc regno = 15)
     295                 :             : */
     296                 :             : unsigned int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER] =
     297                 :             : {
     298                 :             :   /* general regs */
     299                 :             :   0, 2, 1, 3, 6, 7, 5, 4,
     300                 :             :   /* fp regs */
     301                 :             :   11, 12, 13, 14, 15, 16, 17, 18,
     302                 :             :   /* arg, flags, fpsr, frame */
     303                 :             :   IGNORED_DWARF_REGNUM, 9,
     304                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     305                 :             :   /* SSE registers */
     306                 :             :   21, 22, 23, 24, 25, 26, 27, 28,
     307                 :             :   /* MMX registers */
     308                 :             :   29, 30, 31, 32, 33, 34, 35, 36,
     309                 :             :   /* extended integer registers */
     310                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     311                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     312                 :             :   /* extended sse registers */
     313                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     314                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     315                 :             :   /* AVX-512 registers 16-23 */
     316                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     317                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     318                 :             :   /* AVX-512 registers 24-31 */
     319                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     320                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     321                 :             :   /* Mask registers */
     322                 :             :   93, 94, 95, 96, 97, 98, 99, 100
     323                 :             : };
     324                 :             : 
     325                 :             : /* Define parameter passing and return registers.  */
     326                 :             : 
     327                 :             : static int const x86_64_int_parameter_registers[6] =
     328                 :             : {
     329                 :             :   DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
     330                 :             : };
     331                 :             : 
     332                 :             : static int const x86_64_ms_abi_int_parameter_registers[4] =
     333                 :             : {
     334                 :             :   CX_REG, DX_REG, R8_REG, R9_REG
     335                 :             : };
     336                 :             : 
     337                 :             : static int const x86_64_int_return_registers[4] =
     338                 :             : {
     339                 :             :   AX_REG, DX_REG, DI_REG, SI_REG
     340                 :             : };
     341                 :             : 
     342                 :             : /* Define the structure for the machine field in struct function.  */
     343                 :             : 
     344                 :             : struct GTY(()) stack_local_entry {
     345                 :             :   unsigned short mode;
     346                 :             :   unsigned short n;
     347                 :             :   rtx rtl;
     348                 :             :   struct stack_local_entry *next;
     349                 :             : };
     350                 :             : 
     351                 :             : /* Which cpu are we scheduling for.  */
     352                 :             : enum attr_cpu ix86_schedule;
     353                 :             : 
     354                 :             : /* Which cpu are we optimizing for.  */
     355                 :             : enum processor_type ix86_tune;
     356                 :             : 
     357                 :             : /* Which instruction set architecture to use.  */
     358                 :             : enum processor_type ix86_arch;
     359                 :             : 
     360                 :             : /* True if processor has SSE prefetch instruction.  */
     361                 :             : unsigned char ix86_prefetch_sse;
     362                 :             : 
     363                 :             : /* Preferred alignment for stack boundary in bits.  */
     364                 :             : unsigned int ix86_preferred_stack_boundary;
     365                 :             : 
     366                 :             : /* Alignment for incoming stack boundary in bits specified at
     367                 :             :    command line.  */
     368                 :             : unsigned int ix86_user_incoming_stack_boundary;
     369                 :             : 
     370                 :             : /* Default alignment for incoming stack boundary in bits.  */
     371                 :             : unsigned int ix86_default_incoming_stack_boundary;
     372                 :             : 
     373                 :             : /* Alignment for incoming stack boundary in bits.  */
     374                 :             : unsigned int ix86_incoming_stack_boundary;
     375                 :             : 
     376                 :             : /* True if there is no direct access to extern symbols.  */
     377                 :             : bool ix86_has_no_direct_extern_access;
     378                 :             : 
     379                 :             : /* Calling abi specific va_list type nodes.  */
     380                 :             : tree sysv_va_list_type_node;
     381                 :             : tree ms_va_list_type_node;
     382                 :             : 
     383                 :             : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
     384                 :             : char internal_label_prefix[16];
     385                 :             : int internal_label_prefix_len;
     386                 :             : 
     387                 :             : /* Fence to use after loop using movnt.  */
     388                 :             : tree x86_mfence;
     389                 :             : 
     390                 :             : /* Register class used for passing given 64bit part of the argument.
     391                 :             :    These represent classes as documented by the PS ABI, with the exception
     392                 :             :    of SSESF, SSEDF classes, that are basically SSE class, just gcc will
     393                 :             :    use SF or DFmode move instead of DImode to avoid reformatting penalties.
     394                 :             : 
     395                 :             :    Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
     396                 :             :    whenever possible (upper half does contain padding).  */
     397                 :             : enum x86_64_reg_class
     398                 :             :   {
     399                 :             :     X86_64_NO_CLASS,
     400                 :             :     X86_64_INTEGER_CLASS,
     401                 :             :     X86_64_INTEGERSI_CLASS,
     402                 :             :     X86_64_SSE_CLASS,
     403                 :             :     X86_64_SSEHF_CLASS,
     404                 :             :     X86_64_SSESF_CLASS,
     405                 :             :     X86_64_SSEDF_CLASS,
     406                 :             :     X86_64_SSEUP_CLASS,
     407                 :             :     X86_64_X87_CLASS,
     408                 :             :     X86_64_X87UP_CLASS,
     409                 :             :     X86_64_COMPLEX_X87_CLASS,
     410                 :             :     X86_64_MEMORY_CLASS
     411                 :             :   };
     412                 :             : 
     413                 :             : #define MAX_CLASSES 8
     414                 :             : 
     415                 :             : /* Table of constants used by fldpi, fldln2, etc....  */
     416                 :             : static REAL_VALUE_TYPE ext_80387_constants_table [5];
     417                 :             : static bool ext_80387_constants_init;
     418                 :             : 
     419                 :             : 
     420                 :             : static rtx ix86_function_value (const_tree, const_tree, bool);
     421                 :             : static bool ix86_function_value_regno_p (const unsigned int);
     422                 :             : static unsigned int ix86_function_arg_boundary (machine_mode,
     423                 :             :                                                 const_tree);
     424                 :             : static rtx ix86_static_chain (const_tree, bool);
     425                 :             : static int ix86_function_regparm (const_tree, const_tree);
     426                 :             : static void ix86_compute_frame_layout (void);
     427                 :             : static tree ix86_canonical_va_list_type (tree);
     428                 :             : static unsigned int split_stack_prologue_scratch_regno (void);
     429                 :             : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
     430                 :             : 
     431                 :             : static bool ix86_can_inline_p (tree, tree);
     432                 :             : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
     433                 :             : 
     434                 :             : typedef enum ix86_flags_cc
     435                 :             : {
     436                 :             :   X86_CCO = 0, X86_CCNO, X86_CCB, X86_CCNB,
     437                 :             :   X86_CCE, X86_CCNE, X86_CCBE, X86_CCNBE,
     438                 :             :   X86_CCS, X86_CCNS, X86_CCP, X86_CCNP,
     439                 :             :   X86_CCL, X86_CCNL, X86_CCLE, X86_CCNLE
     440                 :             : } ix86_cc;
     441                 :             : 
     442                 :             : static const char *ix86_ccmp_dfv_mapping[] =
     443                 :             : {
     444                 :             :   "{dfv=of}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     445                 :             :   "{dfv=zf}", "{dfv=}", "{dfv=cf, zf}", "{dfv=}",
     446                 :             :   "{dfv=sf}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     447                 :             :   "{dfv=sf}", "{dfv=sf, of}", "{dfv=sf, of, zf}", "{dfv=sf, of}"
     448                 :             : };
     449                 :             : 
     450                 :             : 
     451                 :             : /* Whether -mtune= or -march= were specified */
     452                 :             : int ix86_tune_defaulted;
     453                 :             : int ix86_arch_specified;
     454                 :             : 
     455                 :             : /* Return true if a red-zone is in use.  We can't use red-zone when
     456                 :             :    there are local indirect jumps, like "indirect_jump" or "tablejump",
     457                 :             :    which jumps to another place in the function, since "call" in the
     458                 :             :    indirect thunk pushes the return address onto stack, destroying
     459                 :             :    red-zone.
     460                 :             : 
     461                 :             :    TODO: If we can reserve the first 2 WORDs, for PUSH and, another
     462                 :             :    for CALL, in red-zone, we can allow local indirect jumps with
     463                 :             :    indirect thunk.  */
     464                 :             : 
     465                 :             : bool
     466                 :     9482940 : ix86_using_red_zone (void)
     467                 :             : {
     468                 :     9482940 :   return (TARGET_RED_ZONE
     469                 :     8559374 :           && !TARGET_64BIT_MS_ABI
     470                 :    17739932 :           && (!cfun->machine->has_local_indirect_jump
     471                 :       47998 :               || cfun->machine->indirect_branch_type == indirect_branch_keep));
     472                 :             : }
     473                 :             : 
     474                 :             : /* Return true, if profiling code should be emitted before
     475                 :             :    prologue. Otherwise it returns false.
     476                 :             :    Note: For x86 with "hotfix" it is sorried.  */
     477                 :             : static bool
     478                 :     4306413 : ix86_profile_before_prologue (void)
     479                 :             : {
     480                 :     4306413 :   return flag_fentry != 0;
     481                 :             : }
     482                 :             : 
     483                 :             : /* Update register usage after having seen the compiler flags.  */
     484                 :             : 
     485                 :             : static void
     486                 :      877033 : ix86_conditional_register_usage (void)
     487                 :             : {
     488                 :      877033 :   int i, c_mask;
     489                 :             : 
     490                 :             :   /* If there are no caller-saved registers, preserve all registers.
     491                 :             :      except fixed_regs and registers used for function return value
     492                 :             :      since aggregate_value_p checks call_used_regs[regno] on return
     493                 :             :      value.  */
     494                 :      877033 :   if (cfun
     495                 :       64156 :       && (cfun->machine->call_saved_registers
     496                 :       64156 :           == TYPE_NO_CALLER_SAVED_REGISTERS))
     497                 :      378510 :     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     498                 :      374440 :       if (!fixed_regs[i] && !ix86_function_value_regno_p (i))
     499                 :      337800 :         call_used_regs[i] = 0;
     500                 :             : 
     501                 :             :   /* For 32-bit targets, disable the REX registers.  */
     502                 :      877033 :   if (! TARGET_64BIT)
     503                 :             :     {
     504                 :      137952 :       for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
     505                 :      122624 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     506                 :      137952 :       for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
     507                 :      122624 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     508                 :      260576 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     509                 :      245248 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     510                 :             :     }
     511                 :             : 
     512                 :             :   /*  See the definition of CALL_USED_REGISTERS in i386.h.  */
     513                 :      877033 :   c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT_MS_ABI);
     514                 :             : 
     515                 :      877033 :   CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
     516                 :             : 
     517                 :    81564069 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     518                 :             :     {
     519                 :             :       /* Set/reset conditionally defined registers from
     520                 :             :          CALL_USED_REGISTERS initializer.  */
     521                 :    80687036 :       if (call_used_regs[i] > 1)
     522                 :    13975493 :         call_used_regs[i] = !!(call_used_regs[i] & c_mask);
     523                 :             : 
     524                 :             :       /* Calculate registers of CLOBBERED_REGS register set
     525                 :             :          as call used registers from GENERAL_REGS register set.  */
     526                 :    80687036 :       if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
     527                 :    80687036 :           && call_used_regs[i])
     528                 :    24464572 :         SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
     529                 :             :     }
     530                 :             : 
     531                 :             :   /* If MMX is disabled, disable the registers.  */
     532                 :      877033 :   if (! TARGET_MMX)
     533                 :      387978 :     accessible_reg_set &= ~reg_class_contents[MMX_REGS];
     534                 :             : 
     535                 :             :   /* If SSE is disabled, disable the registers.  */
     536                 :      877033 :   if (! TARGET_SSE)
     537                 :      382642 :     accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
     538                 :             : 
     539                 :             :   /* If the FPU is disabled, disable the registers.  */
     540                 :      877033 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
     541                 :      383116 :     accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
     542                 :             : 
     543                 :             :   /* If AVX512F is disabled, disable the registers.  */
     544                 :      877033 :   if (! TARGET_AVX512F)
     545                 :             :     {
     546                 :     9906767 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     547                 :     9324016 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     548                 :             : 
     549                 :     1165502 :       accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
     550                 :             :     }
     551                 :             : 
     552                 :             :   /* If APX is disabled, disable the registers.  */
     553                 :      877033 :   if (! (TARGET_APX_EGPR && TARGET_64BIT))
     554                 :             :     {
     555                 :    14902693 :       for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
     556                 :    14026064 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     557                 :             :     }
     558                 :      877033 : }
     559                 :             : 
     560                 :             : /* Canonicalize a comparison from one we don't have to one we do have.  */
     561                 :             : 
     562                 :             : static void
     563                 :    21146741 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
     564                 :             :                               bool op0_preserve_value)
     565                 :             : {
     566                 :             :   /* The order of operands in x87 ficom compare is forced by combine in
     567                 :             :      simplify_comparison () function. Float operator is treated as RTX_OBJ
     568                 :             :      with a precedence over other operators and is always put in the first
     569                 :             :      place. Swap condition and operands to match ficom instruction.  */
     570                 :    21146741 :   if (!op0_preserve_value
     571                 :    20400186 :       && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
     572                 :             :     {
     573                 :           6 :       enum rtx_code scode = swap_condition ((enum rtx_code) *code);
     574                 :             : 
     575                 :             :       /* We are called only for compares that are split to SAHF instruction.
     576                 :             :          Ensure that we have setcc/jcc insn for the swapped condition.  */
     577                 :           6 :       if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
     578                 :             :         {
     579                 :           6 :           std::swap (*op0, *op1);
     580                 :           6 :           *code = (int) scode;
     581                 :           6 :           return;
     582                 :             :         }
     583                 :             :     }
     584                 :             : 
     585                 :             :   /* Swap operands of GTU comparison to canonicalize
     586                 :             :      addcarry/subborrow comparison.  */
     587                 :    20400180 :   if (!op0_preserve_value
     588                 :    20400180 :       && *code == GTU
     589                 :      716487 :       && GET_CODE (*op0) == PLUS
     590                 :      298751 :       && ix86_carry_flag_operator (XEXP (*op0, 0), VOIDmode)
     591                 :       42755 :       && GET_CODE (XEXP (*op0, 1)) == ZERO_EXTEND
     592                 :       38555 :       && GET_CODE (*op1) == ZERO_EXTEND)
     593                 :             :     {
     594                 :       35611 :       std::swap (*op0, *op1);
     595                 :       35611 :       *code = (int) swap_condition ((enum rtx_code) *code);
     596                 :       35611 :       return;
     597                 :             :     }
     598                 :             : }
     599                 :             : 
     600                 :             : /* Hook to determine if one function can safely inline another.  */
     601                 :             : 
     602                 :             : static bool
     603                 :     8491508 : ix86_can_inline_p (tree caller, tree callee)
     604                 :             : {
     605                 :     8491508 :   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
     606                 :     8491508 :   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
     607                 :             : 
     608                 :             :   /* Changes of those flags can be tolerated for always inlines. Lets hope
     609                 :             :      user knows what he is doing.  */
     610                 :     8491508 :   unsigned HOST_WIDE_INT always_inline_safe_mask
     611                 :             :          = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
     612                 :             :             | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
     613                 :             :             | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
     614                 :             :             | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
     615                 :             :             | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
     616                 :             :             | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
     617                 :             :             | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
     618                 :             : 
     619                 :             : 
     620                 :     8491508 :   if (!callee_tree)
     621                 :     7851601 :     callee_tree = target_option_default_node;
     622                 :     8491508 :   if (!caller_tree)
     623                 :     7860134 :     caller_tree = target_option_default_node;
     624                 :     8491508 :   if (callee_tree == caller_tree)
     625                 :             :     return true;
     626                 :             : 
     627                 :       18298 :   struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
     628                 :       18298 :   struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
     629                 :       18298 :   bool ret = false;
     630                 :       18298 :   bool always_inline
     631                 :       18298 :     = (DECL_DISREGARD_INLINE_LIMITS (callee)
     632                 :       36000 :        && lookup_attribute ("always_inline",
     633                 :       17702 :                             DECL_ATTRIBUTES (callee)));
     634                 :             : 
     635                 :             :   /* If callee only uses GPRs, ignore MASK_80387.  */
     636                 :       18298 :   if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
     637                 :        1021 :     always_inline_safe_mask |= MASK_80387;
     638                 :             : 
     639                 :       18298 :   cgraph_node *callee_node = cgraph_node::get (callee);
     640                 :             :   /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
     641                 :             :      function can inline a SSE2 function but a SSE2 function can't inline
     642                 :             :      a SSE4 function.  */
     643                 :       18298 :   if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
     644                 :             :        != callee_opts->x_ix86_isa_flags)
     645                 :       18084 :       || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
     646                 :             :           != callee_opts->x_ix86_isa_flags2))
     647                 :             :     ret = false;
     648                 :             : 
     649                 :             :   /* See if we have the same non-isa options.  */
     650                 :       18063 :   else if ((!always_inline
     651                 :         376 :             && caller_opts->x_target_flags != callee_opts->x_target_flags)
     652                 :       18019 :            || (caller_opts->x_target_flags & ~always_inline_safe_mask)
     653                 :       18019 :                != (callee_opts->x_target_flags & ~always_inline_safe_mask))
     654                 :             :     ret = false;
     655                 :             : 
     656                 :       18019 :   else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
     657                 :             :            /* If the calle doesn't use FP expressions differences in
     658                 :             :               ix86_fpmath can be ignored.  We are called from FEs
     659                 :             :               for multi-versioning call optimization, so beware of
     660                 :             :               ipa_fn_summaries not available.  */
     661                 :        1238 :            && (! ipa_fn_summaries
     662                 :        1238 :                || ipa_fn_summaries->get (callee_node) == NULL
     663                 :        1238 :                || ipa_fn_summaries->get (callee_node)->fp_expressions))
     664                 :             :     ret = false;
     665                 :             : 
     666                 :             :   /* At this point we cannot identify whether arch or tune setting
     667                 :             :      comes from target attribute or not. So the most conservative way
     668                 :             :      is to allow the callee that uses default arch and tune string to
     669                 :             :      be inlined.  */
     670                 :       17745 :   else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
     671                 :        9410 :            && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
     672                 :             :     ret = true;
     673                 :             : 
     674                 :             :   /* See if arch, tune, etc. are the same. As previous ISA flags already
     675                 :             :      checks if callee's ISA is subset of caller's, do not block
     676                 :             :      always_inline attribute for callee even it has different arch. */
     677                 :        8343 :   else if (!always_inline && caller_opts->arch != callee_opts->arch)
     678                 :             :     ret = false;
     679                 :             : 
     680                 :           3 :   else if (!always_inline && caller_opts->tune != callee_opts->tune)
     681                 :             :     ret = false;
     682                 :             : 
     683                 :        8343 :   else if (!always_inline
     684                 :           3 :            && caller_opts->branch_cost != callee_opts->branch_cost)
     685                 :             :     ret = false;
     686                 :             : 
     687                 :             :   else
     688                 :     8490955 :     ret = true;
     689                 :             : 
     690                 :             :   return ret;
     691                 :             : }
     692                 :             : 
     693                 :             : /* Return true if this goes in large data/bss.  */
     694                 :             : 
     695                 :             : static bool
     696                 :    70362057 : ix86_in_large_data_p (tree exp)
     697                 :             : {
     698                 :    70362057 :   if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
     699                 :    70361819 :       && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
     700                 :             :     return false;
     701                 :             : 
     702                 :        1040 :   if (exp == NULL_TREE)
     703                 :             :     return false;
     704                 :             : 
     705                 :             :   /* Functions are never large data.  */
     706                 :        1040 :   if (TREE_CODE (exp) == FUNCTION_DECL)
     707                 :             :     return false;
     708                 :             : 
     709                 :             :   /* Automatic variables are never large data.  */
     710                 :         256 :   if (VAR_P (exp) && !is_global_var (exp))
     711                 :             :     return false;
     712                 :             : 
     713                 :         256 :   if (VAR_P (exp) && DECL_SECTION_NAME (exp))
     714                 :             :     {
     715                 :          51 :       const char *section = DECL_SECTION_NAME (exp);
     716                 :          51 :       if (strcmp (section, ".ldata") == 0
     717                 :          51 :           || strcmp (section, ".lbss") == 0)
     718                 :             :         return true;
     719                 :             :       return false;
     720                 :             :     }
     721                 :             :   else
     722                 :             :     {
     723                 :         205 :       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
     724                 :             : 
     725                 :             :       /* If this is an incomplete type with size 0, then we can't put it
     726                 :             :          in data because it might be too big when completed.  Also,
     727                 :             :          int_size_in_bytes returns -1 if size can vary or is larger than
     728                 :             :          an integer in which case also it is safer to assume that it goes in
     729                 :             :          large data.  */
     730                 :         205 :       if (size <= 0 || size > ix86_section_threshold)
     731                 :             :         return true;
     732                 :             :     }
     733                 :             : 
     734                 :             :   return false;
     735                 :             : }
     736                 :             : 
     737                 :             : /* i386-specific section flag to mark large sections.  */
     738                 :             : #define SECTION_LARGE SECTION_MACH_DEP
     739                 :             : 
     740                 :             : /* Switch to the appropriate section for output of DECL.
     741                 :             :    DECL is either a `VAR_DECL' node or a constant of some sort.
     742                 :             :    RELOC indicates whether forming the initial value of DECL requires
     743                 :             :    link-time relocations.  */
     744                 :             : 
     745                 :             : ATTRIBUTE_UNUSED static section *
     746                 :     1631152 : x86_64_elf_select_section (tree decl, int reloc,
     747                 :             :                            unsigned HOST_WIDE_INT align)
     748                 :             : {
     749                 :     1631152 :   if (ix86_in_large_data_p (decl))
     750                 :             :     {
     751                 :           6 :       const char *sname = NULL;
     752                 :           6 :       unsigned int flags = SECTION_WRITE | SECTION_LARGE;
     753                 :           6 :       switch (categorize_decl_for_section (decl, reloc))
     754                 :             :         {
     755                 :           1 :         case SECCAT_DATA:
     756                 :           1 :           sname = ".ldata";
     757                 :           1 :           break;
     758                 :           0 :         case SECCAT_DATA_REL:
     759                 :           0 :           sname = ".ldata.rel";
     760                 :           0 :           break;
     761                 :           0 :         case SECCAT_DATA_REL_LOCAL:
     762                 :           0 :           sname = ".ldata.rel.local";
     763                 :           0 :           break;
     764                 :           0 :         case SECCAT_DATA_REL_RO:
     765                 :           0 :           sname = ".ldata.rel.ro";
     766                 :           0 :           break;
     767                 :           0 :         case SECCAT_DATA_REL_RO_LOCAL:
     768                 :           0 :           sname = ".ldata.rel.ro.local";
     769                 :           0 :           break;
     770                 :           0 :         case SECCAT_BSS:
     771                 :           0 :           sname = ".lbss";
     772                 :           0 :           flags |= SECTION_BSS;
     773                 :           0 :           break;
     774                 :             :         case SECCAT_RODATA:
     775                 :             :         case SECCAT_RODATA_MERGE_STR:
     776                 :             :         case SECCAT_RODATA_MERGE_STR_INIT:
     777                 :             :         case SECCAT_RODATA_MERGE_CONST:
     778                 :             :           sname = ".lrodata";
     779                 :             :           flags &= ~SECTION_WRITE;
     780                 :             :           break;
     781                 :           0 :         case SECCAT_SRODATA:
     782                 :           0 :         case SECCAT_SDATA:
     783                 :           0 :         case SECCAT_SBSS:
     784                 :           0 :           gcc_unreachable ();
     785                 :             :         case SECCAT_TEXT:
     786                 :             :         case SECCAT_TDATA:
     787                 :             :         case SECCAT_TBSS:
     788                 :             :           /* We don't split these for medium model.  Place them into
     789                 :             :              default sections and hope for best.  */
     790                 :             :           break;
     791                 :             :         }
     792                 :           1 :       if (sname)
     793                 :             :         {
     794                 :             :           /* We might get called with string constants, but get_named_section
     795                 :             :              doesn't like them as they are not DECLs.  Also, we need to set
     796                 :             :              flags in that case.  */
     797                 :           6 :           if (!DECL_P (decl))
     798                 :           3 :             return get_section (sname, flags, NULL);
     799                 :           3 :           return get_named_section (decl, sname, reloc);
     800                 :             :         }
     801                 :             :     }
     802                 :     1631146 :   return default_elf_select_section (decl, reloc, align);
     803                 :             : }
     804                 :             : 
     805                 :             : /* Select a set of attributes for section NAME based on the properties
     806                 :             :    of DECL and whether or not RELOC indicates that DECL's initializer
     807                 :             :    might contain runtime relocations.  */
     808                 :             : 
     809                 :             : static unsigned int ATTRIBUTE_UNUSED
     810                 :    57232639 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
     811                 :             : {
     812                 :    57232639 :   unsigned int flags = default_section_type_flags (decl, name, reloc);
     813                 :             : 
     814                 :    57232639 :   if (ix86_in_large_data_p (decl))
     815                 :           7 :     flags |= SECTION_LARGE;
     816                 :             : 
     817                 :    57232639 :   if (decl == NULL_TREE
     818                 :         370 :       && (strcmp (name, ".ldata.rel.ro") == 0
     819                 :         370 :           || strcmp (name, ".ldata.rel.ro.local") == 0))
     820                 :           0 :     flags |= SECTION_RELRO;
     821                 :             : 
     822                 :    57232639 :   if (strcmp (name, ".lbss") == 0
     823                 :    57232635 :       || startswith (name, ".lbss.")
     824                 :   114465271 :       || startswith (name, ".gnu.linkonce.lb."))
     825                 :           7 :     flags |= SECTION_BSS;
     826                 :             : 
     827                 :    57232639 :   return flags;
     828                 :             : }
     829                 :             : 
     830                 :             : /* Build up a unique section name, expressed as a
     831                 :             :    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
     832                 :             :    RELOC indicates whether the initial value of EXP requires
     833                 :             :    link-time relocations.  */
     834                 :             : 
     835                 :             : static void ATTRIBUTE_UNUSED
     836                 :     1775193 : x86_64_elf_unique_section (tree decl, int reloc)
     837                 :             : {
     838                 :     1775193 :   if (ix86_in_large_data_p (decl))
     839                 :             :     {
     840                 :           3 :       const char *prefix = NULL;
     841                 :             :       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
     842                 :           3 :       bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
     843                 :             : 
     844                 :           3 :       switch (categorize_decl_for_section (decl, reloc))
     845                 :             :         {
     846                 :           0 :         case SECCAT_DATA:
     847                 :           0 :         case SECCAT_DATA_REL:
     848                 :           0 :         case SECCAT_DATA_REL_LOCAL:
     849                 :           0 :         case SECCAT_DATA_REL_RO:
     850                 :           0 :         case SECCAT_DATA_REL_RO_LOCAL:
     851                 :           0 :           prefix = one_only ? ".ld" : ".ldata";
     852                 :           0 :           break;
     853                 :           3 :         case SECCAT_BSS:
     854                 :           3 :           prefix = one_only ? ".lb" : ".lbss";
     855                 :           3 :           break;
     856                 :             :         case SECCAT_RODATA:
     857                 :             :         case SECCAT_RODATA_MERGE_STR:
     858                 :             :         case SECCAT_RODATA_MERGE_STR_INIT:
     859                 :             :         case SECCAT_RODATA_MERGE_CONST:
     860                 :             :           prefix = one_only ? ".lr" : ".lrodata";
     861                 :             :           break;
     862                 :           0 :         case SECCAT_SRODATA:
     863                 :           0 :         case SECCAT_SDATA:
     864                 :           0 :         case SECCAT_SBSS:
     865                 :           0 :           gcc_unreachable ();
     866                 :             :         case SECCAT_TEXT:
     867                 :             :         case SECCAT_TDATA:
     868                 :             :         case SECCAT_TBSS:
     869                 :             :           /* We don't split these for medium model.  Place them into
     870                 :             :              default sections and hope for best.  */
     871                 :             :           break;
     872                 :             :         }
     873                 :           3 :       if (prefix)
     874                 :             :         {
     875                 :           3 :           const char *name, *linkonce;
     876                 :           3 :           char *string;
     877                 :             : 
     878                 :           3 :           name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     879                 :           3 :           name = targetm.strip_name_encoding (name);
     880                 :             : 
     881                 :             :           /* If we're using one_only, then there needs to be a .gnu.linkonce
     882                 :             :              prefix to the section name.  */
     883                 :           3 :           linkonce = one_only ? ".gnu.linkonce" : "";
     884                 :             : 
     885                 :           3 :           string = ACONCAT ((linkonce, prefix, ".", name, NULL));
     886                 :             : 
     887                 :           3 :           set_decl_section_name (decl, string);
     888                 :           3 :           return;
     889                 :             :         }
     890                 :             :     }
     891                 :     1775190 :   default_unique_section (decl, reloc);
     892                 :             : }
     893                 :             : 
     894                 :             : #ifdef COMMON_ASM_OP
     895                 :             : 
     896                 :             : #ifndef LARGECOMM_SECTION_ASM_OP
     897                 :             : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
     898                 :             : #endif
     899                 :             : 
     900                 :             : /* This says how to output assembler code to declare an
     901                 :             :    uninitialized external linkage data object.
     902                 :             : 
     903                 :             :    For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
     904                 :             :    large objects.  */
     905                 :             : void
     906                 :      167138 : x86_elf_aligned_decl_common (FILE *file, tree decl,
     907                 :             :                         const char *name, unsigned HOST_WIDE_INT size,
     908                 :             :                         unsigned align)
     909                 :             : {
     910                 :      167138 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     911                 :      167132 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     912                 :           6 :       && size > (unsigned int)ix86_section_threshold)
     913                 :             :     {
     914                 :           1 :       switch_to_section (get_named_section (decl, ".lbss", 0));
     915                 :           1 :       fputs (LARGECOMM_SECTION_ASM_OP, file);
     916                 :             :     }
     917                 :             :   else
     918                 :      167137 :     fputs (COMMON_ASM_OP, file);
     919                 :      167138 :   assemble_name (file, name);
     920                 :      167138 :   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
     921                 :             :            size, align / BITS_PER_UNIT);
     922                 :      167138 : }
     923                 :             : #endif
     924                 :             : 
     925                 :             : /* Utility function for targets to use in implementing
     926                 :             :    ASM_OUTPUT_ALIGNED_BSS.  */
     927                 :             : 
     928                 :             : void
     929                 :      763429 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
     930                 :             :                         unsigned HOST_WIDE_INT size, unsigned align)
     931                 :             : {
     932                 :      763429 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     933                 :      763419 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     934                 :          37 :       && size > (unsigned int)ix86_section_threshold)
     935                 :           3 :     switch_to_section (get_named_section (decl, ".lbss", 0));
     936                 :             :   else
     937                 :      763426 :     switch_to_section (bss_section);
     938                 :      913635 :   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
     939                 :             : #ifdef ASM_DECLARE_OBJECT_NAME
     940                 :      763429 :   last_assemble_variable_decl = decl;
     941                 :      763429 :   ASM_DECLARE_OBJECT_NAME (file, name, decl);
     942                 :             : #else
     943                 :             :   /* Standard thing is just output label for the object.  */
     944                 :             :   ASM_OUTPUT_LABEL (file, name);
     945                 :             : #endif /* ASM_DECLARE_OBJECT_NAME */
     946                 :      763429 :   ASM_OUTPUT_SKIP (file, size ? size : 1);
     947                 :      763429 : }
     948                 :             : 
     949                 :             : /* Decide whether we must probe the stack before any space allocation
     950                 :             :    on this target.  It's essentially TARGET_STACK_PROBE except when
     951                 :             :    -fstack-check causes the stack to be already probed differently.  */
     952                 :             : 
     953                 :             : bool
     954                 :      837016 : ix86_target_stack_probe (void)
     955                 :             : {
     956                 :             :   /* Do not probe the stack twice if static stack checking is enabled.  */
     957                 :      837016 :   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
     958                 :             :     return false;
     959                 :             : 
     960                 :      837016 :   return TARGET_STACK_PROBE;
     961                 :             : }
     962                 :             : 
     963                 :             : /* Decide whether we can make a sibling call to a function.  DECL is the
     964                 :             :    declaration of the function being targeted by the call and EXP is the
     965                 :             :    CALL_EXPR representing the call.  */
     966                 :             : 
     967                 :             : static bool
     968                 :      127922 : ix86_function_ok_for_sibcall (tree decl, tree exp)
     969                 :             : {
     970                 :      127922 :   tree type, decl_or_type;
     971                 :      127922 :   rtx a, b;
     972                 :      127922 :   bool bind_global = decl && !targetm.binds_local_p (decl);
     973                 :             : 
     974                 :      127922 :   if (ix86_function_naked (current_function_decl))
     975                 :             :     return false;
     976                 :             : 
     977                 :             :   /* Sibling call isn't OK if there are no caller-saved registers
     978                 :             :      since all registers must be preserved before return.  */
     979                 :      127920 :   if (cfun->machine->call_saved_registers
     980                 :      127920 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
     981                 :             :     return false;
     982                 :             : 
     983                 :             :   /* If we are generating position-independent code, we cannot sibcall
     984                 :             :      optimize direct calls to global functions, as the PLT requires
     985                 :             :      %ebx be live. (Darwin does not have a PLT.)  */
     986                 :      127897 :   if (!TARGET_MACHO
     987                 :      127897 :       && !TARGET_64BIT
     988                 :       10894 :       && flag_pic
     989                 :        8078 :       && flag_plt
     990                 :        8078 :       && bind_global)
     991                 :             :     return false;
     992                 :             : 
     993                 :             :   /* If we need to align the outgoing stack, then sibcalling would
     994                 :             :      unalign the stack, which may break the called function.  */
     995                 :      123424 :   if (ix86_minimum_incoming_stack_boundary (true)
     996                 :      123424 :       < PREFERRED_STACK_BOUNDARY)
     997                 :             :     return false;
     998                 :             : 
     999                 :      122844 :   if (decl)
    1000                 :             :     {
    1001                 :      113060 :       decl_or_type = decl;
    1002                 :      113060 :       type = TREE_TYPE (decl);
    1003                 :             :     }
    1004                 :             :   else
    1005                 :             :     {
    1006                 :             :       /* We're looking at the CALL_EXPR, we need the type of the function.  */
    1007                 :        9784 :       type = CALL_EXPR_FN (exp);                /* pointer expression */
    1008                 :        9784 :       type = TREE_TYPE (type);                  /* pointer type */
    1009                 :        9784 :       type = TREE_TYPE (type);                  /* function type */
    1010                 :        9784 :       decl_or_type = type;
    1011                 :             :     }
    1012                 :             : 
    1013                 :             :   /* Sibling call isn't OK if callee has no callee-saved registers
    1014                 :             :      and the calling function has callee-saved registers.  */
    1015                 :      122844 :   if (cfun->machine->call_saved_registers != TYPE_NO_CALLEE_SAVED_REGISTERS
    1016                 :      122839 :       && (cfun->machine->call_saved_registers
    1017                 :             :           != TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP)
    1018                 :      245683 :       && lookup_attribute ("no_callee_saved_registers",
    1019                 :      122839 :                            TYPE_ATTRIBUTES (type)))
    1020                 :             :     return false;
    1021                 :             : 
    1022                 :             :   /* If outgoing reg parm stack space changes, we cannot do sibcall.  */
    1023                 :      122836 :   if ((OUTGOING_REG_PARM_STACK_SPACE (type)
    1024                 :      122836 :        != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
    1025                 :      244925 :       || (REG_PARM_STACK_SPACE (decl_or_type)
    1026                 :      122089 :           != REG_PARM_STACK_SPACE (current_function_decl)))
    1027                 :             :     {
    1028                 :         747 :       maybe_complain_about_tail_call (exp,
    1029                 :             :                                       "inconsistent size of stack space"
    1030                 :             :                                       " allocated for arguments which are"
    1031                 :             :                                       " passed in registers");
    1032                 :         747 :       return false;
    1033                 :             :     }
    1034                 :             : 
    1035                 :             :   /* Check that the return value locations are the same.  Like
    1036                 :             :      if we are returning floats on the 80387 register stack, we cannot
    1037                 :             :      make a sibcall from a function that doesn't return a float to a
    1038                 :             :      function that does or, conversely, from a function that does return
    1039                 :             :      a float to a function that doesn't; the necessary stack adjustment
    1040                 :             :      would not be executed.  This is also the place we notice
    1041                 :             :      differences in the return value ABI.  Note that it is ok for one
    1042                 :             :      of the functions to have void return type as long as the return
    1043                 :             :      value of the other is passed in a register.  */
    1044                 :      122089 :   a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
    1045                 :      122089 :   b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
    1046                 :      122089 :                            cfun->decl, false);
    1047                 :      122089 :   if (STACK_REG_P (a) || STACK_REG_P (b))
    1048                 :             :     {
    1049                 :         693 :       if (!rtx_equal_p (a, b))
    1050                 :             :         return false;
    1051                 :             :     }
    1052                 :      121396 :   else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
    1053                 :             :     ;
    1054                 :       21445 :   else if (!rtx_equal_p (a, b))
    1055                 :             :     return false;
    1056                 :             : 
    1057                 :      121694 :   if (TARGET_64BIT)
    1058                 :             :     {
    1059                 :             :       /* The SYSV ABI has more call-clobbered registers;
    1060                 :             :          disallow sibcalls from MS to SYSV.  */
    1061                 :      115273 :       if (cfun->machine->call_abi == MS_ABI
    1062                 :      115273 :           && ix86_function_type_abi (type) == SYSV_ABI)
    1063                 :             :         return false;
    1064                 :             :     }
    1065                 :             :   else
    1066                 :             :     {
    1067                 :             :       /* If this call is indirect, we'll need to be able to use a
    1068                 :             :          call-clobbered register for the address of the target function.
    1069                 :             :          Make sure that all such registers are not used for passing
    1070                 :             :          parameters.  Note that DLLIMPORT functions and call to global
    1071                 :             :          function via GOT slot are indirect.  */
    1072                 :        6421 :       if (!decl
    1073                 :        4631 :           || (bind_global && flag_pic && !flag_plt)
    1074                 :             :           || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
    1075                 :        4631 :           || flag_force_indirect_call)
    1076                 :             :         {
    1077                 :             :           /* Check if regparm >= 3 since arg_reg_available is set to
    1078                 :             :              false if regparm == 0.  If regparm is 1 or 2, there is
    1079                 :             :              always a call-clobbered register available.
    1080                 :             : 
    1081                 :             :              ??? The symbol indirect call doesn't need a call-clobbered
    1082                 :             :              register.  But we don't know if this is a symbol indirect
    1083                 :             :              call or not here.  */
    1084                 :        1790 :           if (ix86_function_regparm (type, decl) >= 3
    1085                 :        1790 :               && !cfun->machine->arg_reg_available)
    1086                 :             :             return false;
    1087                 :             :         }
    1088                 :             :     }
    1089                 :             : 
    1090                 :      121694 :   if (decl && ix86_use_pseudo_pic_reg ())
    1091                 :             :     {
    1092                 :             :       /* When PIC register is used, it must be restored after ifunc
    1093                 :             :          function returns.  */
    1094                 :        2012 :        cgraph_node *node = cgraph_node::get (decl);
    1095                 :        2012 :        if (node && node->ifunc_resolver)
    1096                 :             :          return false;
    1097                 :             :     }
    1098                 :             : 
    1099                 :             :   /* Disable sibcall if callee has indirect_return attribute and
    1100                 :             :      caller doesn't since callee will return to the caller's caller
    1101                 :             :      via an indirect jump.  */
    1102                 :      121694 :   if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
    1103                 :             :        == (CF_RETURN | CF_BRANCH))
    1104                 :       47734 :       && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
    1105                 :      121698 :       && !lookup_attribute ("indirect_return",
    1106                 :           4 :                             TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
    1107                 :             :     return false;
    1108                 :             : 
    1109                 :             :   /* Otherwise okay.  That also includes certain types of indirect calls.  */
    1110                 :             :   return true;
    1111                 :             : }
    1112                 :             : 
    1113                 :             : /* This function determines from TYPE the calling-convention.  */
    1114                 :             : 
    1115                 :             : unsigned int
    1116                 :     6081872 : ix86_get_callcvt (const_tree type)
    1117                 :             : {
    1118                 :     6081872 :   unsigned int ret = 0;
    1119                 :     6081872 :   bool is_stdarg;
    1120                 :     6081872 :   tree attrs;
    1121                 :             : 
    1122                 :     6081872 :   if (TARGET_64BIT)
    1123                 :             :     return IX86_CALLCVT_CDECL;
    1124                 :             : 
    1125                 :     3228438 :   attrs = TYPE_ATTRIBUTES (type);
    1126                 :     3228438 :   if (attrs != NULL_TREE)
    1127                 :             :     {
    1128                 :       61634 :       if (lookup_attribute ("cdecl", attrs))
    1129                 :             :         ret |= IX86_CALLCVT_CDECL;
    1130                 :       61634 :       else if (lookup_attribute ("stdcall", attrs))
    1131                 :             :         ret |= IX86_CALLCVT_STDCALL;
    1132                 :       61634 :       else if (lookup_attribute ("fastcall", attrs))
    1133                 :             :         ret |= IX86_CALLCVT_FASTCALL;
    1134                 :       61625 :       else if (lookup_attribute ("thiscall", attrs))
    1135                 :             :         ret |= IX86_CALLCVT_THISCALL;
    1136                 :             : 
    1137                 :             :       /* Regparam isn't allowed for thiscall and fastcall.  */
    1138                 :             :       if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
    1139                 :             :         {
    1140                 :       61625 :           if (lookup_attribute ("regparm", attrs))
    1141                 :       15683 :             ret |= IX86_CALLCVT_REGPARM;
    1142                 :       61625 :           if (lookup_attribute ("sseregparm", attrs))
    1143                 :           0 :             ret |= IX86_CALLCVT_SSEREGPARM;
    1144                 :             :         }
    1145                 :             : 
    1146                 :       61634 :       if (IX86_BASE_CALLCVT(ret) != 0)
    1147                 :           9 :         return ret;
    1148                 :             :     }
    1149                 :             : 
    1150                 :     3228429 :   is_stdarg = stdarg_p (type);
    1151                 :     3228429 :   if (TARGET_RTD && !is_stdarg)
    1152                 :           0 :     return IX86_CALLCVT_STDCALL | ret;
    1153                 :             : 
    1154                 :     3228429 :   if (ret != 0
    1155                 :     3228429 :       || is_stdarg
    1156                 :     3204052 :       || TREE_CODE (type) != METHOD_TYPE
    1157                 :     3357794 :       || ix86_function_type_abi (type) != MS_ABI)
    1158                 :     3228429 :     return IX86_CALLCVT_CDECL | ret;
    1159                 :             : 
    1160                 :             :   return IX86_CALLCVT_THISCALL;
    1161                 :             : }
    1162                 :             : 
    1163                 :             : /* Return 0 if the attributes for two types are incompatible, 1 if they
    1164                 :             :    are compatible, and 2 if they are nearly compatible (which causes a
    1165                 :             :    warning to be generated).  */
    1166                 :             : 
    1167                 :             : static int
    1168                 :     1444222 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
    1169                 :             : {
    1170                 :     1444222 :   unsigned int ccvt1, ccvt2;
    1171                 :             : 
    1172                 :     1444222 :   if (TREE_CODE (type1) != FUNCTION_TYPE
    1173                 :     1444222 :       && TREE_CODE (type1) != METHOD_TYPE)
    1174                 :             :     return 1;
    1175                 :             : 
    1176                 :     1437681 :   ccvt1 = ix86_get_callcvt (type1);
    1177                 :     1437681 :   ccvt2 = ix86_get_callcvt (type2);
    1178                 :     1437681 :   if (ccvt1 != ccvt2)
    1179                 :             :     return 0;
    1180                 :     2853506 :   if (ix86_function_regparm (type1, NULL)
    1181                 :     1426753 :       != ix86_function_regparm (type2, NULL))
    1182                 :             :     return 0;
    1183                 :             : 
    1184                 :      694373 :   if (lookup_attribute ("no_callee_saved_registers",
    1185                 :      694373 :                         TYPE_ATTRIBUTES (type1))
    1186                 :      694373 :       != lookup_attribute ("no_callee_saved_registers",
    1187                 :      694373 :                            TYPE_ATTRIBUTES (type2)))
    1188                 :             :     return 0;
    1189                 :             : 
    1190                 :             :   return 1;
    1191                 :             : }
    1192                 :             : 
    1193                 :             : /* Return the regparm value for a function with the indicated TYPE and DECL.
    1194                 :             :    DECL may be NULL when calling function indirectly
    1195                 :             :    or considering a libcall.  */
    1196                 :             : 
    1197                 :             : static int
    1198                 :     4109256 : ix86_function_regparm (const_tree type, const_tree decl)
    1199                 :             : {
    1200                 :     4109256 :   tree attr;
    1201                 :     4109256 :   int regparm;
    1202                 :     4109256 :   unsigned int ccvt;
    1203                 :             : 
    1204                 :     4109256 :   if (TARGET_64BIT)
    1205                 :     2853434 :     return (ix86_function_type_abi (type) == SYSV_ABI
    1206                 :     2853434 :             ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
    1207                 :     1255822 :   ccvt = ix86_get_callcvt (type);
    1208                 :     1255822 :   regparm = ix86_regparm;
    1209                 :             : 
    1210                 :     1255822 :   if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
    1211                 :             :     {
    1212                 :        2017 :       attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
    1213                 :        2017 :       if (attr)
    1214                 :             :         {
    1215                 :        2017 :           regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
    1216                 :        2017 :           return regparm;
    1217                 :             :         }
    1218                 :             :     }
    1219                 :     1253805 :   else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1220                 :             :     return 2;
    1221                 :     1253805 :   else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1222                 :             :     return 1;
    1223                 :             : 
    1224                 :             :   /* Use register calling convention for local functions when possible.  */
    1225                 :     1253805 :   if (decl
    1226                 :     1192135 :       && TREE_CODE (decl) == FUNCTION_DECL)
    1227                 :             :     {
    1228                 :     1182054 :       cgraph_node *target = cgraph_node::get (decl);
    1229                 :     1182054 :       if (target)
    1230                 :     1175418 :         target = target->function_symbol ();
    1231                 :             : 
    1232                 :             :       /* Caller and callee must agree on the calling convention, so
    1233                 :             :          checking here just optimize means that with
    1234                 :             :          __attribute__((optimize (...))) caller could use regparm convention
    1235                 :             :          and callee not, or vice versa.  Instead look at whether the callee
    1236                 :             :          is optimized or not.  */
    1237                 :     1175418 :       if (target && opt_for_fn (target->decl, optimize)
    1238                 :     2349987 :           && !(profile_flag && !flag_fentry))
    1239                 :             :         {
    1240                 :     1174569 :           if (target->local && target->can_change_signature)
    1241                 :             :             {
    1242                 :      135884 :               int local_regparm, globals = 0, regno;
    1243                 :             : 
    1244                 :             :               /* Make sure no regparm register is taken by a
    1245                 :             :                  fixed register variable.  */
    1246                 :      135884 :               for (local_regparm = 0; local_regparm < REGPARM_MAX;
    1247                 :             :                    local_regparm++)
    1248                 :      101913 :                 if (fixed_regs[local_regparm])
    1249                 :             :                   break;
    1250                 :             : 
    1251                 :             :               /* We don't want to use regparm(3) for nested functions as
    1252                 :             :                  these use a static chain pointer in the third argument.  */
    1253                 :       33971 :               if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
    1254                 :             :                 local_regparm = 2;
    1255                 :             : 
    1256                 :             :               /* Save a register for the split stack.  */
    1257                 :       33971 :               if (flag_split_stack)
    1258                 :             :                 {
    1259                 :       20905 :                   if (local_regparm == 3)
    1260                 :             :                     local_regparm = 2;
    1261                 :         707 :                   else if (local_regparm == 2
    1262                 :         707 :                            && DECL_STATIC_CHAIN (target->decl))
    1263                 :             :                     local_regparm = 1;
    1264                 :             :                 }
    1265                 :             : 
    1266                 :             :               /* Each fixed register usage increases register pressure,
    1267                 :             :                  so less registers should be used for argument passing.
    1268                 :             :                  This functionality can be overriden by an explicit
    1269                 :             :                  regparm value.  */
    1270                 :      237797 :               for (regno = AX_REG; regno <= DI_REG; regno++)
    1271                 :      203826 :                 if (fixed_regs[regno])
    1272                 :           0 :                   globals++;
    1273                 :             : 
    1274                 :       33971 :               local_regparm
    1275                 :       33971 :                 = globals < local_regparm ? local_regparm - globals : 0;
    1276                 :             : 
    1277                 :       33971 :               if (local_regparm > regparm)
    1278                 :     4109256 :                 regparm = local_regparm;
    1279                 :             :             }
    1280                 :             :         }
    1281                 :             :     }
    1282                 :             : 
    1283                 :             :   return regparm;
    1284                 :             : }
    1285                 :             : 
    1286                 :             : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
    1287                 :             :    DFmode (2) arguments in SSE registers for a function with the
    1288                 :             :    indicated TYPE and DECL.  DECL may be NULL when calling function
    1289                 :             :    indirectly or considering a libcall.  Return -1 if any FP parameter
    1290                 :             :    should be rejected by error.  This is used in siutation we imply SSE
    1291                 :             :    calling convetion but the function is called from another function with
    1292                 :             :    SSE disabled. Otherwise return 0.  */
    1293                 :             : 
    1294                 :             : static int
    1295                 :     1060581 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
    1296                 :             : {
    1297                 :     1060581 :   gcc_assert (!TARGET_64BIT);
    1298                 :             : 
    1299                 :             :   /* Use SSE registers to pass SFmode and DFmode arguments if requested
    1300                 :             :      by the sseregparm attribute.  */
    1301                 :     1060581 :   if (TARGET_SSEREGPARM
    1302                 :     1060581 :       || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
    1303                 :             :     {
    1304                 :           0 :       if (!TARGET_SSE)
    1305                 :             :         {
    1306                 :           0 :           if (warn)
    1307                 :             :             {
    1308                 :           0 :               if (decl)
    1309                 :           0 :                 error ("calling %qD with attribute sseregparm without "
    1310                 :             :                        "SSE/SSE2 enabled", decl);
    1311                 :             :               else
    1312                 :           0 :                 error ("calling %qT with attribute sseregparm without "
    1313                 :             :                        "SSE/SSE2 enabled", type);
    1314                 :             :             }
    1315                 :           0 :           return 0;
    1316                 :             :         }
    1317                 :             : 
    1318                 :             :       return 2;
    1319                 :             :     }
    1320                 :             : 
    1321                 :     1060581 :   if (!decl)
    1322                 :             :     return 0;
    1323                 :             : 
    1324                 :      966322 :   cgraph_node *target = cgraph_node::get (decl);
    1325                 :      966322 :   if (target)
    1326                 :      959693 :     target = target->function_symbol ();
    1327                 :             : 
    1328                 :             :   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
    1329                 :             :      (and DFmode for SSE2) arguments in SSE registers.  */
    1330                 :      959693 :   if (target
    1331                 :             :       /* TARGET_SSE_MATH */
    1332                 :      959693 :       && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
    1333                 :        1296 :       && opt_for_fn (target->decl, optimize)
    1334                 :      960989 :       && !(profile_flag && !flag_fentry))
    1335                 :             :     {
    1336                 :        1296 :       if (target->local && target->can_change_signature)
    1337                 :             :         {
    1338                 :             :           /* Refuse to produce wrong code when local function with SSE enabled
    1339                 :             :              is called from SSE disabled function.
    1340                 :             :              FIXME: We need a way to detect these cases cross-ltrans partition
    1341                 :             :              and avoid using SSE calling conventions on local functions called
    1342                 :             :              from function with SSE disabled.  For now at least delay the
    1343                 :             :              warning until we know we are going to produce wrong code.
    1344                 :             :              See PR66047  */
    1345                 :           0 :           if (!TARGET_SSE && warn)
    1346                 :             :             return -1;
    1347                 :           0 :           return TARGET_SSE2_P (target_opts_for_fn (target->decl)
    1348                 :           0 :                                 ->x_ix86_isa_flags) ? 2 : 1;
    1349                 :             :         }
    1350                 :             :     }
    1351                 :             : 
    1352                 :             :   return 0;
    1353                 :             : }
    1354                 :             : 
    1355                 :             : /* Return true if EAX is live at the start of the function.  Used by
    1356                 :             :    ix86_expand_prologue to determine if we need special help before
    1357                 :             :    calling allocate_stack_worker.  */
    1358                 :             : 
    1359                 :             : static bool
    1360                 :        7089 : ix86_eax_live_at_start_p (void)
    1361                 :             : {
    1362                 :             :   /* Cheat.  Don't bother working forward from ix86_function_regparm
    1363                 :             :      to the function type to whether an actual argument is located in
    1364                 :             :      eax.  Instead just look at cfg info, which is still close enough
    1365                 :             :      to correct at this point.  This gives false positives for broken
    1366                 :             :      functions that might use uninitialized data that happens to be
    1367                 :             :      allocated in eax, but who cares?  */
    1368                 :        7089 :   return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
    1369                 :             : }
    1370                 :             : 
    1371                 :             : static bool
    1372                 :      159001 : ix86_keep_aggregate_return_pointer (tree fntype)
    1373                 :             : {
    1374                 :      159001 :   tree attr;
    1375                 :             : 
    1376                 :      159001 :   if (!TARGET_64BIT)
    1377                 :             :     {
    1378                 :      159001 :       attr = lookup_attribute ("callee_pop_aggregate_return",
    1379                 :      159001 :                                TYPE_ATTRIBUTES (fntype));
    1380                 :      159001 :       if (attr)
    1381                 :           0 :         return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
    1382                 :             : 
    1383                 :             :       /* For 32-bit MS-ABI the default is to keep aggregate
    1384                 :             :          return pointer.  */
    1385                 :      159001 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    1386                 :             :         return true;
    1387                 :             :     }
    1388                 :             :   return KEEP_AGGREGATE_RETURN_POINTER != 0;
    1389                 :             : }
    1390                 :             : 
    1391                 :             : /* Value is the number of bytes of arguments automatically
    1392                 :             :    popped when returning from a subroutine call.
    1393                 :             :    FUNDECL is the declaration node of the function (as a tree),
    1394                 :             :    FUNTYPE is the data type of the function (as a tree),
    1395                 :             :    or for a library call it is an identifier node for the subroutine name.
    1396                 :             :    SIZE is the number of bytes of arguments passed on the stack.
    1397                 :             : 
    1398                 :             :    On the 80386, the RTD insn may be used to pop them if the number
    1399                 :             :      of args is fixed, but if the number is variable then the caller
    1400                 :             :      must pop them all.  RTD can't be used for library calls now
    1401                 :             :      because the library is compiled with the Unix compiler.
    1402                 :             :    Use of RTD is a selectable option, since it is incompatible with
    1403                 :             :    standard Unix calling sequences.  If the option is not selected,
    1404                 :             :    the caller must always pop the args.
    1405                 :             : 
    1406                 :             :    The attribute stdcall is equivalent to RTD on a per module basis.  */
    1407                 :             : 
    1408                 :             : static poly_int64
    1409                 :     7299641 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
    1410                 :             : {
    1411                 :     7299641 :   unsigned int ccvt;
    1412                 :             : 
    1413                 :             :   /* None of the 64-bit ABIs pop arguments.  */
    1414                 :     7299641 :   if (TARGET_64BIT)
    1415                 :     6436874 :     return 0;
    1416                 :             : 
    1417                 :      862767 :   ccvt = ix86_get_callcvt (funtype);
    1418                 :             : 
    1419                 :      862767 :   if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
    1420                 :             :                | IX86_CALLCVT_THISCALL)) != 0
    1421                 :      862767 :       && ! stdarg_p (funtype))
    1422                 :           3 :     return size;
    1423                 :             : 
    1424                 :             :   /* Lose any fake structure return argument if it is passed on the stack.  */
    1425                 :      862764 :   if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
    1426                 :      862764 :       && !ix86_keep_aggregate_return_pointer (funtype))
    1427                 :             :     {
    1428                 :      159001 :       int nregs = ix86_function_regparm (funtype, fundecl);
    1429                 :      159001 :       if (nregs == 0)
    1430                 :      304008 :         return GET_MODE_SIZE (Pmode);
    1431                 :             :     }
    1432                 :             : 
    1433                 :      710760 :   return 0;
    1434                 :             : }
    1435                 :             : 
    1436                 :             : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
    1437                 :             : 
    1438                 :             : static bool
    1439                 :     9336155 : ix86_legitimate_combined_insn (rtx_insn *insn)
    1440                 :             : {
    1441                 :     9336155 :   int i;
    1442                 :             : 
    1443                 :             :   /* Check operand constraints in case hard registers were propagated
    1444                 :             :      into insn pattern.  This check prevents combine pass from
    1445                 :             :      generating insn patterns with invalid hard register operands.
    1446                 :             :      These invalid insns can eventually confuse reload to error out
    1447                 :             :      with a spill failure.  See also PRs 46829 and 46843.  */
    1448                 :             : 
    1449                 :     9336155 :   gcc_assert (INSN_CODE (insn) >= 0);
    1450                 :             : 
    1451                 :     9336155 :   extract_insn (insn);
    1452                 :     9336155 :   preprocess_constraints (insn);
    1453                 :             : 
    1454                 :     9336155 :   int n_operands = recog_data.n_operands;
    1455                 :     9336155 :   int n_alternatives = recog_data.n_alternatives;
    1456                 :    32039035 :   for (i = 0; i < n_operands; i++)
    1457                 :             :     {
    1458                 :    22706590 :       rtx op = recog_data.operand[i];
    1459                 :    22706590 :       machine_mode mode = GET_MODE (op);
    1460                 :    22706590 :       const operand_alternative *op_alt;
    1461                 :    22706590 :       int offset = 0;
    1462                 :    22706590 :       bool win;
    1463                 :    22706590 :       int j;
    1464                 :             : 
    1465                 :             :       /* A unary operator may be accepted by the predicate, but it
    1466                 :             :          is irrelevant for matching constraints.  */
    1467                 :    22706590 :       if (UNARY_P (op))
    1468                 :       40987 :         op = XEXP (op, 0);
    1469                 :             : 
    1470                 :    22706590 :       if (SUBREG_P (op))
    1471                 :             :         {
    1472                 :      923318 :           if (REG_P (SUBREG_REG (op))
    1473                 :      923318 :               && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    1474                 :          56 :             offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    1475                 :          56 :                                           GET_MODE (SUBREG_REG (op)),
    1476                 :          56 :                                           SUBREG_BYTE (op),
    1477                 :          56 :                                           GET_MODE (op));
    1478                 :      923318 :           op = SUBREG_REG (op);
    1479                 :             :         }
    1480                 :             : 
    1481                 :    22706590 :       if (!(REG_P (op) && HARD_REGISTER_P (op)))
    1482                 :    22408821 :         continue;
    1483                 :             : 
    1484                 :      297769 :       op_alt = recog_op_alt;
    1485                 :             : 
    1486                 :             :       /* Operand has no constraints, anything is OK.  */
    1487                 :      297769 :       win = !n_alternatives;
    1488                 :             : 
    1489                 :      297769 :       alternative_mask preferred = get_preferred_alternatives (insn);
    1490                 :      808270 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    1491                 :             :         {
    1492                 :      506468 :           if (!TEST_BIT (preferred, j))
    1493                 :      134811 :             continue;
    1494                 :      371657 :           if (op_alt[i].anything_ok
    1495                 :      195422 :               || (op_alt[i].matches != -1
    1496                 :       35426 :                   && operands_match_p
    1497                 :       35426 :                   (recog_data.operand[i],
    1498                 :       35426 :                    recog_data.operand[op_alt[i].matches]))
    1499                 :      562772 :               || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
    1500                 :             :             {
    1501                 :             :               win = true;
    1502                 :             :               break;
    1503                 :             :             }
    1504                 :             :         }
    1505                 :             : 
    1506                 :      297769 :       if (!win)
    1507                 :             :         return false;
    1508                 :             :     }
    1509                 :             : 
    1510                 :             :   return true;
    1511                 :             : }
    1512                 :             : 
    1513                 :             : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
    1514                 :             : 
    1515                 :             : static unsigned HOST_WIDE_INT
    1516                 :        4417 : ix86_asan_shadow_offset (void)
    1517                 :             : {
    1518                 :        4417 :   return SUBTARGET_SHADOW_OFFSET;
    1519                 :             : }
    1520                 :             : 
    1521                 :             : /* Argument support functions.  */
    1522                 :             : 
    1523                 :             : /* Return true when register may be used to pass function parameters.  */
    1524                 :             : bool
    1525                 :  1366742637 : ix86_function_arg_regno_p (int regno)
    1526                 :             : {
    1527                 :  1366742637 :   int i;
    1528                 :  1366742637 :   enum calling_abi call_abi;
    1529                 :  1366742637 :   const int *parm_regs;
    1530                 :             : 
    1531                 :  1363525949 :   if (TARGET_SSE && SSE_REGNO_P (regno)
    1532                 :  2257521339 :       && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
    1533                 :             :     return true;
    1534                 :             : 
    1535                 :  1256808309 :    if (!TARGET_64BIT)
    1536                 :   125786281 :      return (regno < REGPARM_MAX
    1537                 :   125786281 :              || (TARGET_MMX && MMX_REGNO_P (regno)
    1538                 :    11305280 :                  && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
    1539                 :             : 
    1540                 :             :   /* TODO: The function should depend on current function ABI but
    1541                 :             :      builtins.cc would need updating then. Therefore we use the
    1542                 :             :      default ABI.  */
    1543                 :  1131022028 :   call_abi = ix86_cfun_abi ();
    1544                 :             : 
    1545                 :             :   /* RAX is used as hidden argument to va_arg functions.  */
    1546                 :  1131022028 :   if (call_abi == SYSV_ABI && regno == AX_REG)
    1547                 :             :     return true;
    1548                 :             : 
    1549                 :  1117968949 :   if (call_abi == MS_ABI)
    1550                 :             :     parm_regs = x86_64_ms_abi_int_parameter_registers;
    1551                 :             :   else
    1552                 :  1083590133 :     parm_regs = x86_64_int_parameter_registers;
    1553                 :             : 
    1554                 : 14957548456 :   for (i = 0; i < (call_abi == MS_ABI
    1555                 :  7478774228 :                    ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
    1556                 :  6440730793 :     if (regno == parm_regs[i])
    1557                 :             :       return true;
    1558                 :             :   return false;
    1559                 :             : }
    1560                 :             : 
    1561                 :             : /* Return if we do not know how to pass ARG solely in registers.  */
    1562                 :             : 
    1563                 :             : static bool
    1564                 :   362973712 : ix86_must_pass_in_stack (const function_arg_info &arg)
    1565                 :             : {
    1566                 :   362973712 :   if (must_pass_in_stack_var_size_or_pad (arg))
    1567                 :             :     return true;
    1568                 :             : 
    1569                 :             :   /* For 32-bit, we want TImode aggregates to go on the stack.  But watch out!
    1570                 :             :      The layout_type routine is crafty and tries to trick us into passing
    1571                 :             :      currently unsupported vector types on the stack by using TImode.  */
    1572                 :     1747217 :   return (!TARGET_64BIT && arg.mode == TImode
    1573                 :   362973675 :           && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
    1574                 :             : }
    1575                 :             : 
    1576                 :             : /* It returns the size, in bytes, of the area reserved for arguments passed
    1577                 :             :    in registers for the function represented by fndecl dependent to the used
    1578                 :             :    abi format.  */
    1579                 :             : int
    1580                 :    10214098 : ix86_reg_parm_stack_space (const_tree fndecl)
    1581                 :             : {
    1582                 :    10214098 :   enum calling_abi call_abi = SYSV_ABI;
    1583                 :    10214098 :   if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
    1584                 :     9905284 :     call_abi = ix86_function_abi (fndecl);
    1585                 :             :   else
    1586                 :      308814 :     call_abi = ix86_function_type_abi (fndecl);
    1587                 :    10214098 :   if (TARGET_64BIT && call_abi == MS_ABI)
    1588                 :      119291 :     return 32;
    1589                 :             :   return 0;
    1590                 :             : }
    1591                 :             : 
    1592                 :             : /* We add this as a workaround in order to use libc_has_function
    1593                 :             :    hook in i386.md.  */
    1594                 :             : bool
    1595                 :           0 : ix86_libc_has_function (enum function_class fn_class)
    1596                 :             : {
    1597                 :           0 :   return targetm.libc_has_function (fn_class, NULL_TREE);
    1598                 :             : }
    1599                 :             : 
    1600                 :             : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
    1601                 :             :    specifying the call abi used.  */
    1602                 :             : enum calling_abi
    1603                 :   395049959 : ix86_function_type_abi (const_tree fntype)
    1604                 :             : {
    1605                 :   395049959 :   enum calling_abi abi = ix86_abi;
    1606                 :             : 
    1607                 :   395049959 :   if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
    1608                 :             :     return abi;
    1609                 :             : 
    1610                 :    16660900 :   if (abi == SYSV_ABI
    1611                 :    16660900 :       && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
    1612                 :             :     {
    1613                 :     2579627 :       static int warned;
    1614                 :     2579627 :       if (TARGET_X32 && !warned)
    1615                 :             :         {
    1616                 :           1 :           error ("X32 does not support %<ms_abi%> attribute");
    1617                 :           1 :           warned = 1;
    1618                 :             :         }
    1619                 :             : 
    1620                 :             :       abi = MS_ABI;
    1621                 :             :     }
    1622                 :    14081273 :   else if (abi == MS_ABI
    1623                 :    14081273 :            && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
    1624                 :             :     abi = SYSV_ABI;
    1625                 :             : 
    1626                 :             :   return abi;
    1627                 :             : }
    1628                 :             : 
    1629                 :             : enum calling_abi
    1630                 :   191784971 : ix86_function_abi (const_tree fndecl)
    1631                 :             : {
    1632                 :   191784971 :   return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
    1633                 :             : }
    1634                 :             : 
    1635                 :             : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
    1636                 :             :    specifying the call abi used.  */
    1637                 :             : enum calling_abi
    1638                 :  1957900869 : ix86_cfun_abi (void)
    1639                 :             : {
    1640                 :  1957900869 :   return cfun ? cfun->machine->call_abi : ix86_abi;
    1641                 :             : }
    1642                 :             : 
    1643                 :             : bool
    1644                 :     4894713 : ix86_function_ms_hook_prologue (const_tree fn)
    1645                 :             : {
    1646                 :     4894713 :   if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
    1647                 :             :     {
    1648                 :          15 :       if (decl_function_context (fn) != NULL_TREE)
    1649                 :           0 :         error_at (DECL_SOURCE_LOCATION (fn),
    1650                 :             :                   "%<ms_hook_prologue%> attribute is not compatible "
    1651                 :             :                   "with nested function");
    1652                 :             :       else
    1653                 :             :         return true;
    1654                 :             :     }
    1655                 :             :   return false;
    1656                 :             : }
    1657                 :             : 
    1658                 :             : bool
    1659                 :   105839218 : ix86_function_naked (const_tree fn)
    1660                 :             : {
    1661                 :   105839218 :   if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
    1662                 :             :     return true;
    1663                 :             : 
    1664                 :             :   return false;
    1665                 :             : }
    1666                 :             : 
    1667                 :             : /* Write the extra assembler code needed to declare a function properly.  */
    1668                 :             : 
    1669                 :             : void
    1670                 :     1498810 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
    1671                 :             :                                 tree decl)
    1672                 :             : {
    1673                 :     1498810 :   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
    1674                 :             : 
    1675                 :     1498810 :   if (cfun)
    1676                 :     1495257 :     cfun->machine->function_label_emitted = true;
    1677                 :             : 
    1678                 :     1498810 :   if (is_ms_hook)
    1679                 :             :     {
    1680                 :           2 :       int i, filler_count = (TARGET_64BIT ? 32 : 16);
    1681                 :           2 :       unsigned int filler_cc = 0xcccccccc;
    1682                 :             : 
    1683                 :          18 :       for (i = 0; i < filler_count; i += 4)
    1684                 :          16 :         fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
    1685                 :             :     }
    1686                 :             : 
    1687                 :             : #ifdef SUBTARGET_ASM_UNWIND_INIT
    1688                 :             :   SUBTARGET_ASM_UNWIND_INIT (out_file);
    1689                 :             : #endif
    1690                 :             : 
    1691                 :     1498810 :   assemble_function_label_raw (out_file, fname);
    1692                 :             : 
    1693                 :             :   /* Output magic byte marker, if hot-patch attribute is set.  */
    1694                 :     1498810 :   if (is_ms_hook)
    1695                 :             :     {
    1696                 :           2 :       if (TARGET_64BIT)
    1697                 :             :         {
    1698                 :             :           /* leaq [%rsp + 0], %rsp  */
    1699                 :           2 :           fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
    1700                 :             :                  out_file);
    1701                 :             :         }
    1702                 :             :       else
    1703                 :             :         {
    1704                 :             :           /* movl.s %edi, %edi
    1705                 :             :              push   %ebp
    1706                 :             :              movl.s %esp, %ebp */
    1707                 :           0 :           fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
    1708                 :             :         }
    1709                 :             :     }
    1710                 :     1498810 : }
    1711                 :             : 
    1712                 :             : /* Implementation of call abi switching target hook. Specific to FNDECL
    1713                 :             :    the specific call register sets are set.  See also
    1714                 :             :    ix86_conditional_register_usage for more details.  */
    1715                 :             : void
    1716                 :   172212825 : ix86_call_abi_override (const_tree fndecl)
    1717                 :             : {
    1718                 :   172212825 :   cfun->machine->call_abi = ix86_function_abi (fndecl);
    1719                 :   172212825 : }
    1720                 :             : 
    1721                 :             : /* Return 1 if pseudo register should be created and used to hold
    1722                 :             :    GOT address for PIC code.  */
    1723                 :             : bool
    1724                 :   165952121 : ix86_use_pseudo_pic_reg (void)
    1725                 :             : {
    1726                 :   165952121 :   if ((TARGET_64BIT
    1727                 :   155034891 :        && (ix86_cmodel == CM_SMALL_PIC
    1728                 :             :            || TARGET_PECOFF))
    1729                 :   160543817 :       || !flag_pic)
    1730                 :   161316530 :     return false;
    1731                 :             :   return true;
    1732                 :             : }
    1733                 :             : 
    1734                 :             : /* Initialize large model PIC register.  */
    1735                 :             : 
    1736                 :             : static void
    1737                 :          47 : ix86_init_large_pic_reg (unsigned int tmp_regno)
    1738                 :             : {
    1739                 :          47 :   rtx_code_label *label;
    1740                 :          47 :   rtx tmp_reg;
    1741                 :             : 
    1742                 :          47 :   gcc_assert (Pmode == DImode);
    1743                 :          47 :   label = gen_label_rtx ();
    1744                 :          47 :   emit_label (label);
    1745                 :          47 :   LABEL_PRESERVE_P (label) = 1;
    1746                 :          47 :   tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
    1747                 :          47 :   gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
    1748                 :          47 :   emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
    1749                 :             :                                 label));
    1750                 :          47 :   emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
    1751                 :          47 :   emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
    1752                 :          47 :   const char *name = LABEL_NAME (label);
    1753                 :          47 :   PUT_CODE (label, NOTE);
    1754                 :          47 :   NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
    1755                 :          47 :   NOTE_DELETED_LABEL_NAME (label) = name;
    1756                 :          47 : }
    1757                 :             : 
    1758                 :             : /* Create and initialize PIC register if required.  */
    1759                 :             : static void
    1760                 :     1433101 : ix86_init_pic_reg (void)
    1761                 :             : {
    1762                 :     1433101 :   edge entry_edge;
    1763                 :     1433101 :   rtx_insn *seq;
    1764                 :             : 
    1765                 :     1433101 :   if (!ix86_use_pseudo_pic_reg ())
    1766                 :             :     return;
    1767                 :             : 
    1768                 :       39620 :   start_sequence ();
    1769                 :             : 
    1770                 :       39620 :   if (TARGET_64BIT)
    1771                 :             :     {
    1772                 :          60 :       if (ix86_cmodel == CM_LARGE_PIC)
    1773                 :          44 :         ix86_init_large_pic_reg (R11_REG);
    1774                 :             :       else
    1775                 :          16 :         emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
    1776                 :             :     }
    1777                 :             :   else
    1778                 :             :     {
    1779                 :             :       /*  If there is future mcount call in the function it is more profitable
    1780                 :             :           to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM.  */
    1781                 :       39560 :       rtx reg = crtl->profile
    1782                 :       39560 :                 ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
    1783                 :       39560 :                 : pic_offset_table_rtx;
    1784                 :       39560 :       rtx_insn *insn = emit_insn (gen_set_got (reg));
    1785                 :       39560 :       RTX_FRAME_RELATED_P (insn) = 1;
    1786                 :       39560 :       if (crtl->profile)
    1787                 :           0 :         emit_move_insn (pic_offset_table_rtx, reg);
    1788                 :       39560 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    1789                 :             :     }
    1790                 :             : 
    1791                 :       39620 :   seq = get_insns ();
    1792                 :       39620 :   end_sequence ();
    1793                 :             : 
    1794                 :       39620 :   entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1795                 :       39620 :   insert_insn_on_edge (seq, entry_edge);
    1796                 :       39620 :   commit_one_edge_insertion (entry_edge);
    1797                 :             : }
    1798                 :             : 
    1799                 :             : /* Initialize a variable CUM of type CUMULATIVE_ARGS
    1800                 :             :    for a call to a function whose data type is FNTYPE.
    1801                 :             :    For a library call, FNTYPE is 0.  */
    1802                 :             : 
    1803                 :             : void
    1804                 :     9944924 : init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
    1805                 :             :                       tree fntype,      /* tree ptr for function decl */
    1806                 :             :                       rtx libname,      /* SYMBOL_REF of library name or 0 */
    1807                 :             :                       tree fndecl,
    1808                 :             :                       int caller)
    1809                 :             : {
    1810                 :     9944924 :   struct cgraph_node *local_info_node = NULL;
    1811                 :     9944924 :   struct cgraph_node *target = NULL;
    1812                 :             : 
    1813                 :             :   /* Set silent_p to false to raise an error for invalid calls when
    1814                 :             :      expanding function body.  */
    1815                 :     9944924 :   cfun->machine->silent_p = false;
    1816                 :             : 
    1817                 :     9944924 :   memset (cum, 0, sizeof (*cum));
    1818                 :             : 
    1819                 :     9944924 :   if (fndecl)
    1820                 :             :     {
    1821                 :     9621067 :       target = cgraph_node::get (fndecl);
    1822                 :     9621067 :       if (target)
    1823                 :             :         {
    1824                 :     9509952 :           target = target->function_symbol ();
    1825                 :     9509952 :           local_info_node = cgraph_node::local_info_node (target->decl);
    1826                 :     9509952 :           cum->call_abi = ix86_function_abi (target->decl);
    1827                 :             :         }
    1828                 :             :       else
    1829                 :      111115 :         cum->call_abi = ix86_function_abi (fndecl);
    1830                 :             :     }
    1831                 :             :   else
    1832                 :      323857 :     cum->call_abi = ix86_function_type_abi (fntype);
    1833                 :             : 
    1834                 :     9944924 :   cum->caller = caller;
    1835                 :             : 
    1836                 :             :   /* Set up the number of registers to use for passing arguments.  */
    1837                 :     9944924 :   cum->nregs = ix86_regparm;
    1838                 :     9944924 :   if (TARGET_64BIT)
    1839                 :             :     {
    1840                 :     8923812 :       cum->nregs = (cum->call_abi == SYSV_ABI
    1841                 :     8923812 :                    ? X86_64_REGPARM_MAX
    1842                 :             :                    : X86_64_MS_REGPARM_MAX);
    1843                 :             :     }
    1844                 :     9944924 :   if (TARGET_SSE)
    1845                 :             :     {
    1846                 :     9935912 :       cum->sse_nregs = SSE_REGPARM_MAX;
    1847                 :     9935912 :       if (TARGET_64BIT)
    1848                 :             :         {
    1849                 :     8914920 :           cum->sse_nregs = (cum->call_abi == SYSV_ABI
    1850                 :     8914920 :                            ? X86_64_SSE_REGPARM_MAX
    1851                 :             :                            : X86_64_MS_SSE_REGPARM_MAX);
    1852                 :             :         }
    1853                 :             :     }
    1854                 :     9944924 :   if (TARGET_MMX)
    1855                 :    10759135 :     cum->mmx_nregs = MMX_REGPARM_MAX;
    1856                 :     9944924 :   cum->warn_avx512f = true;
    1857                 :     9944924 :   cum->warn_avx = true;
    1858                 :     9944924 :   cum->warn_sse = true;
    1859                 :     9944924 :   cum->warn_mmx = true;
    1860                 :             : 
    1861                 :             :   /* Because type might mismatch in between caller and callee, we need to
    1862                 :             :      use actual type of function for local calls.
    1863                 :             :      FIXME: cgraph_analyze can be told to actually record if function uses
    1864                 :             :      va_start so for local functions maybe_vaarg can be made aggressive
    1865                 :             :      helping K&R code.
    1866                 :             :      FIXME: once typesytem is fixed, we won't need this code anymore.  */
    1867                 :     9944924 :   if (local_info_node && local_info_node->local
    1868                 :     9509952 :       && local_info_node->can_change_signature)
    1869                 :      362342 :     fntype = TREE_TYPE (target->decl);
    1870                 :     9944924 :   cum->stdarg = stdarg_p (fntype);
    1871                 :    19889848 :   cum->maybe_vaarg = (fntype
    1872                 :    10387407 :                       ? (!prototype_p (fntype) || stdarg_p (fntype))
    1873                 :      118511 :                       : !libname);
    1874                 :             : 
    1875                 :     9944924 :   cum->decl = fndecl;
    1876                 :             : 
    1877                 :     9944924 :   cum->warn_empty = !warn_abi || cum->stdarg;
    1878                 :     9944924 :   if (!cum->warn_empty && fntype)
    1879                 :             :     {
    1880                 :      107465 :       function_args_iterator iter;
    1881                 :      107465 :       tree argtype;
    1882                 :      107465 :       bool seen_empty_type = false;
    1883                 :      308373 :       FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
    1884                 :             :         {
    1885                 :      308373 :           if (argtype == error_mark_node || VOID_TYPE_P (argtype))
    1886                 :             :             break;
    1887                 :      201318 :           if (TYPE_EMPTY_P (argtype))
    1888                 :             :             seen_empty_type = true;
    1889                 :      200456 :           else if (seen_empty_type)
    1890                 :             :             {
    1891                 :         410 :               cum->warn_empty = true;
    1892                 :         410 :               break;
    1893                 :             :             }
    1894                 :             :         }
    1895                 :             :     }
    1896                 :             : 
    1897                 :     9944924 :   if (!TARGET_64BIT)
    1898                 :             :     {
    1899                 :             :       /* If there are variable arguments, then we won't pass anything
    1900                 :             :          in registers in 32-bit mode. */
    1901                 :     1021112 :       if (stdarg_p (fntype))
    1902                 :             :         {
    1903                 :        8743 :           cum->nregs = 0;
    1904                 :             :           /* Since in 32-bit, variable arguments are always passed on
    1905                 :             :              stack, there is scratch register available for indirect
    1906                 :             :              sibcall.  */
    1907                 :        8743 :           cfun->machine->arg_reg_available = true;
    1908                 :        8743 :           cum->sse_nregs = 0;
    1909                 :        8743 :           cum->mmx_nregs = 0;
    1910                 :        8743 :           cum->warn_avx512f = false;
    1911                 :        8743 :           cum->warn_avx = false;
    1912                 :        8743 :           cum->warn_sse = false;
    1913                 :        8743 :           cum->warn_mmx = false;
    1914                 :        8743 :           return;
    1915                 :             :         }
    1916                 :             : 
    1917                 :             :       /* Use ecx and edx registers if function has fastcall attribute,
    1918                 :             :          else look for regparm information.  */
    1919                 :     1012369 :       if (fntype)
    1920                 :             :         {
    1921                 :      999239 :           unsigned int ccvt = ix86_get_callcvt (fntype);
    1922                 :      999239 :           if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1923                 :             :             {
    1924                 :           0 :               cum->nregs = 1;
    1925                 :           0 :               cum->fastcall = 1; /* Same first register as in fastcall.  */
    1926                 :             :             }
    1927                 :      999239 :           else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1928                 :             :             {
    1929                 :           4 :               cum->nregs = 2;
    1930                 :           4 :               cum->fastcall = 1;
    1931                 :             :             }
    1932                 :             :           else
    1933                 :      999235 :             cum->nregs = ix86_function_regparm (fntype, fndecl);
    1934                 :             :         }
    1935                 :             : 
    1936                 :             :       /* Set up the number of SSE registers used for passing SFmode
    1937                 :             :          and DFmode arguments.  Warn for mismatching ABI.  */
    1938                 :     1012369 :       cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
    1939                 :             :     }
    1940                 :             : 
    1941                 :     9936181 :   cfun->machine->arg_reg_available = (cum->nregs > 0);
    1942                 :             : }
    1943                 :             : 
    1944                 :             : /* Return the "natural" mode for TYPE.  In most cases, this is just TYPE_MODE.
    1945                 :             :    But in the case of vector types, it is some vector mode.
    1946                 :             : 
    1947                 :             :    When we have only some of our vector isa extensions enabled, then there
    1948                 :             :    are some modes for which vector_mode_supported_p is false.  For these
    1949                 :             :    modes, the generic vector support in gcc will choose some non-vector mode
    1950                 :             :    in order to implement the type.  By computing the natural mode, we'll
    1951                 :             :    select the proper ABI location for the operand and not depend on whatever
    1952                 :             :    the middle-end decides to do with these vector types.
    1953                 :             : 
    1954                 :             :    The midde-end can't deal with the vector types > 16 bytes.  In this
    1955                 :             :    case, we return the original mode and warn ABI change if CUM isn't
    1956                 :             :    NULL.
    1957                 :             : 
    1958                 :             :    If INT_RETURN is true, warn ABI change if the vector mode isn't
    1959                 :             :    available for function return value.  */
    1960                 :             : 
    1961                 :             : static machine_mode
    1962                 :   209882070 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
    1963                 :             :                    bool in_return)
    1964                 :             : {
    1965                 :   209882070 :   machine_mode mode = TYPE_MODE (type);
    1966                 :             : 
    1967                 :   209882070 :   if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
    1968                 :             :     {
    1969                 :      439049 :       HOST_WIDE_INT size = int_size_in_bytes (type);
    1970                 :      439049 :       if ((size == 8 || size == 16 || size == 32 || size == 64)
    1971                 :             :           /* ??? Generic code allows us to create width 1 vectors.  Ignore.  */
    1972                 :      439049 :           && TYPE_VECTOR_SUBPARTS (type) > 1)
    1973                 :             :         {
    1974                 :      404268 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
    1975                 :             : 
    1976                 :             :           /* There are no XFmode vector modes ...  */
    1977                 :      404268 :           if (innermode == XFmode)
    1978                 :             :             return mode;
    1979                 :             : 
    1980                 :             :           /* ... and no decimal float vector modes.  */
    1981                 :      403723 :           if (DECIMAL_FLOAT_MODE_P (innermode))
    1982                 :             :             return mode;
    1983                 :             : 
    1984                 :      403471 :           if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
    1985                 :             :             mode = MIN_MODE_VECTOR_FLOAT;
    1986                 :             :           else
    1987                 :      338106 :             mode = MIN_MODE_VECTOR_INT;
    1988                 :             : 
    1989                 :             :           /* Get the mode which has this inner mode and number of units.  */
    1990                 :     8538106 :           FOR_EACH_MODE_FROM (mode, mode)
    1991                 :    17747108 :             if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
    1992                 :     9612473 :                 && GET_MODE_INNER (mode) == innermode)
    1993                 :             :               {
    1994                 :      403471 :                 if (size == 64 && (!TARGET_AVX512F || !TARGET_EVEX512)
    1995                 :      280936 :                     && !TARGET_IAMCU)
    1996                 :             :                   {
    1997                 :      280936 :                     static bool warnedavx512f;
    1998                 :      280936 :                     static bool warnedavx512f_ret;
    1999                 :             : 
    2000                 :      280936 :                     if (cum && cum->warn_avx512f && !warnedavx512f)
    2001                 :             :                       {
    2002                 :        1199 :                         if (warning (OPT_Wpsabi, "AVX512F vector argument "
    2003                 :             :                                      "without AVX512F enabled changes the ABI"))
    2004                 :           2 :                           warnedavx512f = true;
    2005                 :             :                       }
    2006                 :      279737 :                     else if (in_return && !warnedavx512f_ret)
    2007                 :             :                       {
    2008                 :      277027 :                         if (warning (OPT_Wpsabi, "AVX512F vector return "
    2009                 :             :                                      "without AVX512F enabled changes the ABI"))
    2010                 :           2 :                           warnedavx512f_ret = true;
    2011                 :             :                       }
    2012                 :             : 
    2013                 :      280936 :                     return TYPE_MODE (type);
    2014                 :             :                   }
    2015                 :      122535 :                 else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
    2016                 :             :                   {
    2017                 :      121975 :                     static bool warnedavx;
    2018                 :      121975 :                     static bool warnedavx_ret;
    2019                 :             : 
    2020                 :      121975 :                     if (cum && cum->warn_avx && !warnedavx)
    2021                 :             :                       {
    2022                 :         602 :                         if (warning (OPT_Wpsabi, "AVX vector argument "
    2023                 :             :                                      "without AVX enabled changes the ABI"))
    2024                 :           5 :                           warnedavx = true;
    2025                 :             :                       }
    2026                 :      121373 :                     else if (in_return && !warnedavx_ret)
    2027                 :             :                       {
    2028                 :      119404 :                         if (warning (OPT_Wpsabi, "AVX vector return "
    2029                 :             :                                      "without AVX enabled changes the ABI"))
    2030                 :           7 :                           warnedavx_ret = true;
    2031                 :             :                       }
    2032                 :             : 
    2033                 :      121975 :                     return TYPE_MODE (type);
    2034                 :             :                   }
    2035                 :         560 :                 else if (((size == 8 && TARGET_64BIT) || size == 16)
    2036                 :         557 :                          && !TARGET_SSE
    2037                 :         140 :                          && !TARGET_IAMCU)
    2038                 :             :                   {
    2039                 :         140 :                     static bool warnedsse;
    2040                 :         140 :                     static bool warnedsse_ret;
    2041                 :             : 
    2042                 :         140 :                     if (cum && cum->warn_sse && !warnedsse)
    2043                 :             :                       {
    2044                 :          19 :                         if (warning (OPT_Wpsabi, "SSE vector argument "
    2045                 :             :                                      "without SSE enabled changes the ABI"))
    2046                 :           6 :                           warnedsse = true;
    2047                 :             :                       }
    2048                 :         121 :                     else if (!TARGET_64BIT && in_return && !warnedsse_ret)
    2049                 :             :                       {
    2050                 :           0 :                         if (warning (OPT_Wpsabi, "SSE vector return "
    2051                 :             :                                      "without SSE enabled changes the ABI"))
    2052                 :           0 :                           warnedsse_ret = true;
    2053                 :             :                       }
    2054                 :             :                   }
    2055                 :         420 :                 else if ((size == 8 && !TARGET_64BIT)
    2056                 :           0 :                          && (!cfun
    2057                 :           0 :                              || cfun->machine->func_type == TYPE_NORMAL)
    2058                 :           0 :                          && !TARGET_MMX
    2059                 :           0 :                          && !TARGET_IAMCU)
    2060                 :             :                   {
    2061                 :           0 :                     static bool warnedmmx;
    2062                 :           0 :                     static bool warnedmmx_ret;
    2063                 :             : 
    2064                 :           0 :                     if (cum && cum->warn_mmx && !warnedmmx)
    2065                 :             :                       {
    2066                 :           0 :                         if (warning (OPT_Wpsabi, "MMX vector argument "
    2067                 :             :                                      "without MMX enabled changes the ABI"))
    2068                 :           0 :                           warnedmmx = true;
    2069                 :             :                       }
    2070                 :           0 :                     else if (in_return && !warnedmmx_ret)
    2071                 :             :                       {
    2072                 :           0 :                         if (warning (OPT_Wpsabi, "MMX vector return "
    2073                 :             :                                      "without MMX enabled changes the ABI"))
    2074                 :           0 :                           warnedmmx_ret = true;
    2075                 :             :                       }
    2076                 :             :                   }
    2077                 :         560 :                 return mode;
    2078                 :             :               }
    2079                 :             : 
    2080                 :           0 :           gcc_unreachable ();
    2081                 :             :         }
    2082                 :             :     }
    2083                 :             : 
    2084                 :             :   return mode;
    2085                 :             : }
    2086                 :             : 
    2087                 :             : /* We want to pass a value in REGNO whose "natural" mode is MODE.  However,
    2088                 :             :    this may not agree with the mode that the type system has chosen for the
    2089                 :             :    register, which is ORIG_MODE.  If ORIG_MODE is not BLKmode, then we can
    2090                 :             :    go ahead and use it.  Otherwise we have to build a PARALLEL instead.  */
    2091                 :             : 
    2092                 :             : static rtx
    2093                 :    37044015 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
    2094                 :             :                      unsigned int regno)
    2095                 :             : {
    2096                 :    37044015 :   rtx tmp;
    2097                 :             : 
    2098                 :    37044015 :   if (orig_mode != BLKmode)
    2099                 :    37043987 :     tmp = gen_rtx_REG (orig_mode, regno);
    2100                 :             :   else
    2101                 :             :     {
    2102                 :          28 :       tmp = gen_rtx_REG (mode, regno);
    2103                 :          28 :       tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
    2104                 :          28 :       tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
    2105                 :             :     }
    2106                 :             : 
    2107                 :    37044015 :   return tmp;
    2108                 :             : }
    2109                 :             : 
    2110                 :             : /* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    2111                 :             :    of this code is to classify each 8bytes of incoming argument by the register
    2112                 :             :    class and assign registers accordingly.  */
    2113                 :             : 
    2114                 :             : /* Return the union class of CLASS1 and CLASS2.
    2115                 :             :    See the x86-64 PS ABI for details.  */
    2116                 :             : 
    2117                 :             : static enum x86_64_reg_class
    2118                 :    39944335 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
    2119                 :             : {
    2120                 :             :   /* Rule #1: If both classes are equal, this is the resulting class.  */
    2121                 :    39521518 :   if (class1 == class2)
    2122                 :             :     return class1;
    2123                 :             : 
    2124                 :             :   /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
    2125                 :             :      the other class.  */
    2126                 :    34479357 :   if (class1 == X86_64_NO_CLASS)
    2127                 :             :     return class2;
    2128                 :    34663742 :   if (class2 == X86_64_NO_CLASS)
    2129                 :             :     return class1;
    2130                 :             : 
    2131                 :             :   /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
    2132                 :     1451134 :   if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
    2133                 :             :     return X86_64_MEMORY_CLASS;
    2134                 :             : 
    2135                 :             :   /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
    2136                 :     1424930 :   if ((class1 == X86_64_INTEGERSI_CLASS
    2137                 :      192112 :        && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
    2138                 :     1423654 :       || (class2 == X86_64_INTEGERSI_CLASS
    2139                 :      625757 :           && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
    2140                 :             :     return X86_64_INTEGERSI_CLASS;
    2141                 :     1419790 :   if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
    2142                 :      509548 :       || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
    2143                 :             :     return X86_64_INTEGER_CLASS;
    2144                 :             : 
    2145                 :             :   /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
    2146                 :             :      MEMORY is used.  */
    2147                 :       60155 :   if (class1 == X86_64_X87_CLASS
    2148                 :             :       || class1 == X86_64_X87UP_CLASS
    2149                 :       60155 :       || class1 == X86_64_COMPLEX_X87_CLASS
    2150                 :             :       || class2 == X86_64_X87_CLASS
    2151                 :       59250 :       || class2 == X86_64_X87UP_CLASS
    2152                 :       58940 :       || class2 == X86_64_COMPLEX_X87_CLASS)
    2153                 :        1215 :     return X86_64_MEMORY_CLASS;
    2154                 :             : 
    2155                 :             :   /* Rule #6: Otherwise class SSE is used.  */
    2156                 :             :   return X86_64_SSE_CLASS;
    2157                 :             : }
    2158                 :             : 
    2159                 :             : /* Classify the argument of type TYPE and mode MODE.
    2160                 :             :    CLASSES will be filled by the register class used to pass each word
    2161                 :             :    of the operand.  The number of words is returned.  In case the parameter
    2162                 :             :    should be passed in memory, 0 is returned. As a special case for zero
    2163                 :             :    sized containers, classes[0] will be NO_CLASS and 1 is returned.
    2164                 :             : 
    2165                 :             :    BIT_OFFSET is used internally for handling records and specifies offset
    2166                 :             :    of the offset in bits modulo 512 to avoid overflow cases.
    2167                 :             : 
    2168                 :             :    See the x86-64 PS ABI for details.
    2169                 :             : */
    2170                 :             : 
    2171                 :             : static int
    2172                 :   348981032 : classify_argument (machine_mode mode, const_tree type,
    2173                 :             :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
    2174                 :             :                    int &zero_width_bitfields)
    2175                 :             : {
    2176                 :   348981032 :   HOST_WIDE_INT bytes
    2177                 :   692989429 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2178                 :   348981032 :   int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
    2179                 :             : 
    2180                 :             :   /* Variable sized entities are always passed/returned in memory.  */
    2181                 :   348981032 :   if (bytes < 0)
    2182                 :             :     return 0;
    2183                 :             : 
    2184                 :   348979875 :   if (mode != VOIDmode)
    2185                 :             :     {
    2186                 :             :       /* The value of "named" doesn't matter.  */
    2187                 :   348192125 :       function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
    2188                 :   348192125 :       if (targetm.calls.must_pass_in_stack (arg))
    2189                 :          37 :         return 0;
    2190                 :             :     }
    2191                 :             : 
    2192                 :   348979838 :   if (type && (AGGREGATE_TYPE_P (type)
    2193                 :   325119024 :                || (TREE_CODE (type) == BITINT_TYPE && words > 1)))
    2194                 :             :     {
    2195                 :    25026273 :       int i;
    2196                 :    25026273 :       tree field;
    2197                 :    25026273 :       enum x86_64_reg_class subclasses[MAX_CLASSES];
    2198                 :             : 
    2199                 :             :       /* On x86-64 we pass structures larger than 64 bytes on the stack.  */
    2200                 :    25026273 :       if (bytes > 64)
    2201                 :             :         return 0;
    2202                 :             : 
    2203                 :    65039534 :       for (i = 0; i < words; i++)
    2204                 :    40807690 :         classes[i] = X86_64_NO_CLASS;
    2205                 :             : 
    2206                 :             :       /* Zero sized arrays or structures are NO_CLASS.  We return 0 to
    2207                 :             :          signalize memory class, so handle it as special case.  */
    2208                 :    24231844 :       if (!words)
    2209                 :             :         {
    2210                 :       64974 :           classes[0] = X86_64_NO_CLASS;
    2211                 :       64974 :           return 1;
    2212                 :             :         }
    2213                 :             : 
    2214                 :             :       /* Classify each field of record and merge classes.  */
    2215                 :    24166870 :       switch (TREE_CODE (type))
    2216                 :             :         {
    2217                 :    22210015 :         case RECORD_TYPE:
    2218                 :             :           /* And now merge the fields of structure.  */
    2219                 :   546323763 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2220                 :             :             {
    2221                 :   524299296 :               if (TREE_CODE (field) == FIELD_DECL)
    2222                 :             :                 {
    2223                 :    34256999 :                   int num;
    2224                 :             : 
    2225                 :    34256999 :                   if (TREE_TYPE (field) == error_mark_node)
    2226                 :           4 :                     continue;
    2227                 :             : 
    2228                 :             :                   /* Bitfields are always classified as integer.  Handle them
    2229                 :             :                      early, since later code would consider them to be
    2230                 :             :                      misaligned integers.  */
    2231                 :    34256995 :                   if (DECL_BIT_FIELD (field))
    2232                 :             :                     {
    2233                 :      432078 :                       if (integer_zerop (DECL_SIZE (field)))
    2234                 :             :                         {
    2235                 :       12902 :                           if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
    2236                 :        8048 :                             continue;
    2237                 :        4854 :                           if (zero_width_bitfields != 2)
    2238                 :             :                             {
    2239                 :        4320 :                               zero_width_bitfields = 1;
    2240                 :        4320 :                               continue;
    2241                 :             :                             }
    2242                 :             :                         }
    2243                 :      419710 :                       for (i = (int_bit_position (field)
    2244                 :      419710 :                                 + (bit_offset % 64)) / 8 / 8;
    2245                 :      842527 :                            i < ((int_bit_position (field) + (bit_offset % 64))
    2246                 :      842527 :                                 + tree_to_shwi (DECL_SIZE (field))
    2247                 :      842527 :                                 + 63) / 8 / 8; i++)
    2248                 :      422817 :                         classes[i]
    2249                 :      845634 :                           = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
    2250                 :             :                     }
    2251                 :             :                   else
    2252                 :             :                     {
    2253                 :    33824917 :                       int pos;
    2254                 :             : 
    2255                 :    33824917 :                       type = TREE_TYPE (field);
    2256                 :             : 
    2257                 :             :                       /* Flexible array member is ignored.  */
    2258                 :    33824917 :                       if (TYPE_MODE (type) == BLKmode
    2259                 :      429662 :                           && TREE_CODE (type) == ARRAY_TYPE
    2260                 :      177866 :                           && TYPE_SIZE (type) == NULL_TREE
    2261                 :        2004 :                           && TYPE_DOMAIN (type) != NULL_TREE
    2262                 :    33826162 :                           && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
    2263                 :             :                               == NULL_TREE))
    2264                 :             :                         {
    2265                 :        1245 :                           static bool warned;
    2266                 :             : 
    2267                 :        1245 :                           if (!warned && warn_psabi)
    2268                 :             :                             {
    2269                 :           2 :                               warned = true;
    2270                 :           2 :                               inform (input_location,
    2271                 :             :                                       "the ABI of passing struct with"
    2272                 :             :                                       " a flexible array member has"
    2273                 :             :                                       " changed in GCC 4.4");
    2274                 :             :                             }
    2275                 :        1245 :                           continue;
    2276                 :        1245 :                         }
    2277                 :    33823672 :                       num = classify_argument (TYPE_MODE (type), type,
    2278                 :             :                                                subclasses,
    2279                 :    33823672 :                                                (int_bit_position (field)
    2280                 :    33823672 :                                                 + bit_offset) % 512,
    2281                 :             :                                                zero_width_bitfields);
    2282                 :    33823672 :                       if (!num)
    2283                 :             :                         return 0;
    2284                 :    33638124 :                       pos = (int_bit_position (field)
    2285                 :    33638124 :                              + (bit_offset % 64)) / 8 / 8;
    2286                 :    70218337 :                       for (i = 0; i < num && (i + pos) < words; i++)
    2287                 :    36580213 :                         classes[i + pos]
    2288                 :    36580213 :                           = merge_classes (subclasses[i], classes[i + pos]);
    2289                 :             :                     }
    2290                 :             :                 }
    2291                 :             :             }
    2292                 :             :           break;
    2293                 :             : 
    2294                 :      384923 :         case ARRAY_TYPE:
    2295                 :             :           /* Arrays are handled as small records.  */
    2296                 :      384923 :           {
    2297                 :      384923 :             int num;
    2298                 :      384923 :             num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
    2299                 :      384923 :                                      TREE_TYPE (type), subclasses, bit_offset,
    2300                 :             :                                      zero_width_bitfields);
    2301                 :      384923 :             if (!num)
    2302                 :             :               return 0;
    2303                 :             : 
    2304                 :             :             /* The partial classes are now full classes.  */
    2305                 :      381764 :             if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
    2306                 :       13572 :               subclasses[0] = X86_64_SSE_CLASS;
    2307                 :      381764 :             if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
    2308                 :        4734 :               subclasses[0] = X86_64_SSE_CLASS;
    2309                 :      381764 :             if (subclasses[0] == X86_64_INTEGERSI_CLASS
    2310                 :      176327 :                 && !((bit_offset % 64) == 0 && bytes == 4))
    2311                 :      119523 :               subclasses[0] = X86_64_INTEGER_CLASS;
    2312                 :             : 
    2313                 :     1227190 :             for (i = 0; i < words; i++)
    2314                 :      845426 :               classes[i] = subclasses[i % num];
    2315                 :             : 
    2316                 :             :             break;
    2317                 :             :           }
    2318                 :      306846 :         case UNION_TYPE:
    2319                 :      306846 :         case QUAL_UNION_TYPE:
    2320                 :             :           /* Unions are similar to RECORD_TYPE but offset is always 0.
    2321                 :             :              */
    2322                 :     3808679 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2323                 :             :             {
    2324                 :     3535454 :               if (TREE_CODE (field) == FIELD_DECL)
    2325                 :             :                 {
    2326                 :     1925324 :                   int num;
    2327                 :             : 
    2328                 :     1925324 :                   if (TREE_TYPE (field) == error_mark_node)
    2329                 :          10 :                     continue;
    2330                 :             : 
    2331                 :     1925314 :                   num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
    2332                 :     1925314 :                                            TREE_TYPE (field), subclasses,
    2333                 :             :                                            bit_offset, zero_width_bitfields);
    2334                 :     1925314 :                   if (!num)
    2335                 :             :                     return 0;
    2336                 :     4832998 :                   for (i = 0; i < num && i < words; i++)
    2337                 :     2941305 :                     classes[i] = merge_classes (subclasses[i], classes[i]);
    2338                 :             :                 }
    2339                 :             :             }
    2340                 :             :           break;
    2341                 :             : 
    2342                 :     1265086 :         case BITINT_TYPE:
    2343                 :             :           /* _BitInt(N) for N > 64 is passed as structure containing
    2344                 :             :              (N + 63) / 64 64-bit elements.  */
    2345                 :     1265086 :           if (words > 2)
    2346                 :             :             return 0;
    2347                 :       74969 :           classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2348                 :       74969 :           return 2;
    2349                 :             : 
    2350                 :           0 :         default:
    2351                 :           0 :           gcc_unreachable ();
    2352                 :             :         }
    2353                 :             : 
    2354                 :    22679456 :       if (words > 2)
    2355                 :             :         {
    2356                 :             :           /* When size > 16 bytes, if the first one isn't
    2357                 :             :              X86_64_SSE_CLASS or any other ones aren't
    2358                 :             :              X86_64_SSEUP_CLASS, everything should be passed in
    2359                 :             :              memory.  */
    2360                 :     1078522 :           if (classes[0] != X86_64_SSE_CLASS)
    2361                 :             :             return 0;
    2362                 :             : 
    2363                 :      190315 :           for (i = 1; i < words; i++)
    2364                 :      172435 :             if (classes[i] != X86_64_SSEUP_CLASS)
    2365                 :             :               return 0;
    2366                 :             :         }
    2367                 :             : 
    2368                 :             :       /* Final merger cleanup.  */
    2369                 :    53365457 :       for (i = 0; i < words; i++)
    2370                 :             :         {
    2371                 :             :           /* If one class is MEMORY, everything should be passed in
    2372                 :             :              memory.  */
    2373                 :    31749515 :           if (classes[i] == X86_64_MEMORY_CLASS)
    2374                 :             :             return 0;
    2375                 :             : 
    2376                 :             :           /* The X86_64_SSEUP_CLASS should be always preceded by
    2377                 :             :              X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
    2378                 :    31749013 :           if (classes[i] == X86_64_SSEUP_CLASS
    2379                 :      146239 :               && classes[i - 1] != X86_64_SSE_CLASS
    2380                 :       74696 :               && classes[i - 1] != X86_64_SSEUP_CLASS)
    2381                 :             :             {
    2382                 :             :               /* The first one should never be X86_64_SSEUP_CLASS.  */
    2383                 :        1916 :               gcc_assert (i != 0);
    2384                 :        1916 :               classes[i] = X86_64_SSE_CLASS;
    2385                 :             :             }
    2386                 :             : 
    2387                 :             :           /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
    2388                 :             :              everything should be passed in memory.  */
    2389                 :    31749013 :           if (classes[i] == X86_64_X87UP_CLASS
    2390                 :      191090 :               && (classes[i - 1] != X86_64_X87_CLASS))
    2391                 :             :             {
    2392                 :        2370 :               static bool warned;
    2393                 :             : 
    2394                 :             :               /* The first one should never be X86_64_X87UP_CLASS.  */
    2395                 :        2370 :               gcc_assert (i != 0);
    2396                 :        2370 :               if (!warned && warn_psabi)
    2397                 :             :                 {
    2398                 :           1 :                   warned = true;
    2399                 :           1 :                   inform (input_location,
    2400                 :             :                           "the ABI of passing union with %<long double%>"
    2401                 :             :                           " has changed in GCC 4.4");
    2402                 :             :                 }
    2403                 :        2370 :               return 0;
    2404                 :             :             }
    2405                 :             :         }
    2406                 :             :       return words;
    2407                 :             :     }
    2408                 :             : 
    2409                 :             :   /* Compute alignment needed.  We align all types to natural boundaries with
    2410                 :             :      exception of XFmode that is aligned to 64bits.  */
    2411                 :   323953565 :   if (mode != VOIDmode && mode != BLKmode)
    2412                 :             :     {
    2413                 :   322729920 :       int mode_alignment = GET_MODE_BITSIZE (mode);
    2414                 :             : 
    2415                 :   322729920 :       if (mode == XFmode)
    2416                 :             :         mode_alignment = 128;
    2417                 :   315672973 :       else if (mode == XCmode)
    2418                 :      552346 :         mode_alignment = 256;
    2419                 :   322729920 :       if (COMPLEX_MODE_P (mode))
    2420                 :     2419851 :         mode_alignment /= 2;
    2421                 :             :       /* Misaligned fields are always returned in memory.  */
    2422                 :   322729920 :       if (bit_offset % mode_alignment)
    2423                 :             :         return 0;
    2424                 :             :     }
    2425                 :             : 
    2426                 :             :   /* for V1xx modes, just use the base mode */
    2427                 :   323945932 :   if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
    2428                 :   419167428 :       && GET_MODE_UNIT_SIZE (mode) == bytes)
    2429                 :        5349 :     mode = GET_MODE_INNER (mode);
    2430                 :             : 
    2431                 :             :   /* Classification of atomic types.  */
    2432                 :   323945932 :   switch (mode)
    2433                 :             :     {
    2434                 :      206905 :     case E_SDmode:
    2435                 :      206905 :     case E_DDmode:
    2436                 :      206905 :       classes[0] = X86_64_SSE_CLASS;
    2437                 :      206905 :       return 1;
    2438                 :       99145 :     case E_TDmode:
    2439                 :       99145 :       classes[0] = X86_64_SSE_CLASS;
    2440                 :       99145 :       classes[1] = X86_64_SSEUP_CLASS;
    2441                 :       99145 :       return 2;
    2442                 :   199833061 :     case E_DImode:
    2443                 :   199833061 :     case E_SImode:
    2444                 :   199833061 :     case E_HImode:
    2445                 :   199833061 :     case E_QImode:
    2446                 :   199833061 :     case E_CSImode:
    2447                 :   199833061 :     case E_CHImode:
    2448                 :   199833061 :     case E_CQImode:
    2449                 :   199833061 :       {
    2450                 :   199833061 :         int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
    2451                 :             : 
    2452                 :             :         /* Analyze last 128 bits only.  */
    2453                 :   199833061 :         size = (size - 1) & 0x7f;
    2454                 :             : 
    2455                 :   199833061 :         if (size < 32)
    2456                 :             :           {
    2457                 :    87193904 :             classes[0] = X86_64_INTEGERSI_CLASS;
    2458                 :    87193904 :             return 1;
    2459                 :             :           }
    2460                 :   112639157 :         else if (size < 64)
    2461                 :             :           {
    2462                 :   103390441 :             classes[0] = X86_64_INTEGER_CLASS;
    2463                 :   103390441 :             return 1;
    2464                 :             :           }
    2465                 :     9248716 :         else if (size < 64+32)
    2466                 :             :           {
    2467                 :     3976319 :             classes[0] = X86_64_INTEGER_CLASS;
    2468                 :     3976319 :             classes[1] = X86_64_INTEGERSI_CLASS;
    2469                 :     3976319 :             return 2;
    2470                 :             :           }
    2471                 :     5272397 :         else if (size < 64+64)
    2472                 :             :           {
    2473                 :     5272397 :             classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2474                 :     5272397 :             return 2;
    2475                 :             :           }
    2476                 :             :         else
    2477                 :             :           gcc_unreachable ();
    2478                 :             :       }
    2479                 :     1857305 :     case E_CDImode:
    2480                 :     1857305 :     case E_TImode:
    2481                 :     1857305 :       classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2482                 :     1857305 :       return 2;
    2483                 :           0 :     case E_COImode:
    2484                 :           0 :     case E_OImode:
    2485                 :             :       /* OImode shouldn't be used directly.  */
    2486                 :           0 :       gcc_unreachable ();
    2487                 :             :     case E_CTImode:
    2488                 :             :       return 0;
    2489                 :      917444 :     case E_HFmode:
    2490                 :      917444 :     case E_BFmode:
    2491                 :      917444 :       if (!(bit_offset % 64))
    2492                 :      915184 :         classes[0] = X86_64_SSEHF_CLASS;
    2493                 :             :       else
    2494                 :        2260 :         classes[0] = X86_64_SSE_CLASS;
    2495                 :             :       return 1;
    2496                 :     9823873 :     case E_SFmode:
    2497                 :     9823873 :       if (!(bit_offset % 64))
    2498                 :     9771093 :         classes[0] = X86_64_SSESF_CLASS;
    2499                 :             :       else
    2500                 :       52780 :         classes[0] = X86_64_SSE_CLASS;
    2501                 :             :       return 1;
    2502                 :     4198763 :     case E_DFmode:
    2503                 :     4198763 :       classes[0] = X86_64_SSEDF_CLASS;
    2504                 :     4198763 :       return 1;
    2505                 :     7056231 :     case E_XFmode:
    2506                 :     7056231 :       classes[0] = X86_64_X87_CLASS;
    2507                 :     7056231 :       classes[1] = X86_64_X87UP_CLASS;
    2508                 :     7056231 :       return 2;
    2509                 :     1281357 :     case E_TFmode:
    2510                 :     1281357 :       classes[0] = X86_64_SSE_CLASS;
    2511                 :     1281357 :       classes[1] = X86_64_SSEUP_CLASS;
    2512                 :     1281357 :       return 2;
    2513                 :      126694 :     case E_HCmode:
    2514                 :      126694 :     case E_BCmode:
    2515                 :      126694 :       classes[0] = X86_64_SSE_CLASS;
    2516                 :      126694 :       if (!(bit_offset % 64))
    2517                 :             :         return 1;
    2518                 :             :       else
    2519                 :             :         {
    2520                 :          98 :           classes[1] = X86_64_SSEHF_CLASS;
    2521                 :          98 :           return 2;
    2522                 :             :         }
    2523                 :      714713 :     case E_SCmode:
    2524                 :      714713 :       classes[0] = X86_64_SSE_CLASS;
    2525                 :      714713 :       if (!(bit_offset % 64))
    2526                 :             :         return 1;
    2527                 :             :       else
    2528                 :             :         {
    2529                 :        1041 :           static bool warned;
    2530                 :             : 
    2531                 :        1041 :           if (!warned && warn_psabi)
    2532                 :             :             {
    2533                 :           1 :               warned = true;
    2534                 :           1 :               inform (input_location,
    2535                 :             :                       "the ABI of passing structure with %<complex float%>"
    2536                 :             :                       " member has changed in GCC 4.4");
    2537                 :             :             }
    2538                 :        1041 :           classes[1] = X86_64_SSESF_CLASS;
    2539                 :        1041 :           return 2;
    2540                 :             :         }
    2541                 :      725416 :     case E_DCmode:
    2542                 :      725416 :       classes[0] = X86_64_SSEDF_CLASS;
    2543                 :      725416 :       classes[1] = X86_64_SSEDF_CLASS;
    2544                 :      725416 :       return 2;
    2545                 :      552346 :     case E_XCmode:
    2546                 :      552346 :       classes[0] = X86_64_COMPLEX_X87_CLASS;
    2547                 :      552346 :       return 1;
    2548                 :             :     case E_TCmode:
    2549                 :             :       /* This modes is larger than 16 bytes.  */
    2550                 :             :       return 0;
    2551                 :    29120035 :     case E_V8SFmode:
    2552                 :    29120035 :     case E_V8SImode:
    2553                 :    29120035 :     case E_V32QImode:
    2554                 :    29120035 :     case E_V16HFmode:
    2555                 :    29120035 :     case E_V16BFmode:
    2556                 :    29120035 :     case E_V16HImode:
    2557                 :    29120035 :     case E_V4DFmode:
    2558                 :    29120035 :     case E_V4DImode:
    2559                 :    29120035 :       classes[0] = X86_64_SSE_CLASS;
    2560                 :    29120035 :       classes[1] = X86_64_SSEUP_CLASS;
    2561                 :    29120035 :       classes[2] = X86_64_SSEUP_CLASS;
    2562                 :    29120035 :       classes[3] = X86_64_SSEUP_CLASS;
    2563                 :    29120035 :       return 4;
    2564                 :    26065671 :     case E_V8DFmode:
    2565                 :    26065671 :     case E_V16SFmode:
    2566                 :    26065671 :     case E_V32HFmode:
    2567                 :    26065671 :     case E_V32BFmode:
    2568                 :    26065671 :     case E_V8DImode:
    2569                 :    26065671 :     case E_V16SImode:
    2570                 :    26065671 :     case E_V32HImode:
    2571                 :    26065671 :     case E_V64QImode:
    2572                 :    26065671 :       classes[0] = X86_64_SSE_CLASS;
    2573                 :    26065671 :       classes[1] = X86_64_SSEUP_CLASS;
    2574                 :    26065671 :       classes[2] = X86_64_SSEUP_CLASS;
    2575                 :    26065671 :       classes[3] = X86_64_SSEUP_CLASS;
    2576                 :    26065671 :       classes[4] = X86_64_SSEUP_CLASS;
    2577                 :    26065671 :       classes[5] = X86_64_SSEUP_CLASS;
    2578                 :    26065671 :       classes[6] = X86_64_SSEUP_CLASS;
    2579                 :    26065671 :       classes[7] = X86_64_SSEUP_CLASS;
    2580                 :    26065671 :       return 8;
    2581                 :    36828691 :     case E_V4SFmode:
    2582                 :    36828691 :     case E_V4SImode:
    2583                 :    36828691 :     case E_V16QImode:
    2584                 :    36828691 :     case E_V8HImode:
    2585                 :    36828691 :     case E_V8HFmode:
    2586                 :    36828691 :     case E_V8BFmode:
    2587                 :    36828691 :     case E_V2DFmode:
    2588                 :    36828691 :     case E_V2DImode:
    2589                 :    36828691 :       classes[0] = X86_64_SSE_CLASS;
    2590                 :    36828691 :       classes[1] = X86_64_SSEUP_CLASS;
    2591                 :    36828691 :       return 2;
    2592                 :     3183893 :     case E_V1TImode:
    2593                 :     3183893 :     case E_V1DImode:
    2594                 :     3183893 :     case E_V2SFmode:
    2595                 :     3183893 :     case E_V2SImode:
    2596                 :     3183893 :     case E_V4HImode:
    2597                 :     3183893 :     case E_V4HFmode:
    2598                 :     3183893 :     case E_V4BFmode:
    2599                 :     3183893 :     case E_V2HFmode:
    2600                 :     3183893 :     case E_V2BFmode:
    2601                 :     3183893 :     case E_V8QImode:
    2602                 :     3183893 :       classes[0] = X86_64_SSE_CLASS;
    2603                 :     3183893 :       return 1;
    2604                 :             :     case E_BLKmode:
    2605                 :             :     case E_VOIDmode:
    2606                 :             :       return 0;
    2607                 :       37174 :     default:
    2608                 :       37174 :       gcc_assert (VECTOR_MODE_P (mode));
    2609                 :             : 
    2610                 :       37174 :       if (bytes > 16)
    2611                 :             :         return 0;
    2612                 :             : 
    2613                 :       45432 :       gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
    2614                 :             : 
    2615                 :       45432 :       if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
    2616                 :       22276 :         classes[0] = X86_64_INTEGERSI_CLASS;
    2617                 :             :       else
    2618                 :         440 :         classes[0] = X86_64_INTEGER_CLASS;
    2619                 :       22716 :       classes[1] = X86_64_INTEGER_CLASS;
    2620                 :       22716 :       return 1 + (bytes > 8);
    2621                 :             :     }
    2622                 :             : }
    2623                 :             : 
    2624                 :             : /* Wrapper around classify_argument with the extra zero_width_bitfields
    2625                 :             :    argument, to diagnose GCC 12.1 ABI differences for C.  */
    2626                 :             : 
    2627                 :             : static int
    2628                 :   312846589 : classify_argument (machine_mode mode, const_tree type,
    2629                 :             :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
    2630                 :             : {
    2631                 :   312846589 :   int zero_width_bitfields = 0;
    2632                 :   312846589 :   static bool warned = false;
    2633                 :   312846589 :   int n = classify_argument (mode, type, classes, bit_offset,
    2634                 :             :                              zero_width_bitfields);
    2635                 :   312846589 :   if (!zero_width_bitfields || warned || !warn_psabi)
    2636                 :             :     return n;
    2637                 :         534 :   enum x86_64_reg_class alt_classes[MAX_CLASSES];
    2638                 :         534 :   zero_width_bitfields = 2;
    2639                 :         534 :   if (classify_argument (mode, type, alt_classes, bit_offset,
    2640                 :             :                          zero_width_bitfields) != n)
    2641                 :           0 :     zero_width_bitfields = 3;
    2642                 :             :   else
    2643                 :        1286 :     for (int i = 0; i < n; i++)
    2644                 :         760 :       if (classes[i] != alt_classes[i])
    2645                 :             :         {
    2646                 :           8 :           zero_width_bitfields = 3;
    2647                 :           8 :           break;
    2648                 :             :         }
    2649                 :         534 :   if (zero_width_bitfields == 3)
    2650                 :             :     {
    2651                 :           8 :       warned = true;
    2652                 :           8 :       const char *url
    2653                 :             :         = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
    2654                 :             : 
    2655                 :           8 :       inform (input_location,
    2656                 :             :               "the ABI of passing C structures with zero-width bit-fields"
    2657                 :             :               " has changed in GCC %{12.1%}", url);
    2658                 :             :     }
    2659                 :             :   return n;
    2660                 :             : }
    2661                 :             : 
    2662                 :             : /* Examine the argument and return set number of register required in each
    2663                 :             :    class.  Return true iff parameter should be passed in memory.  */
    2664                 :             : 
    2665                 :             : static bool
    2666                 :   210312752 : examine_argument (machine_mode mode, const_tree type, int in_return,
    2667                 :             :                   int *int_nregs, int *sse_nregs)
    2668                 :             : {
    2669                 :   210312752 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2670                 :   210312752 :   int n = classify_argument (mode, type, regclass, 0);
    2671                 :             : 
    2672                 :   210312752 :   *int_nregs = 0;
    2673                 :   210312752 :   *sse_nregs = 0;
    2674                 :             : 
    2675                 :   210312752 :   if (!n)
    2676                 :             :     return true;
    2677                 :   629037859 :   for (n--; n >= 0; n--)
    2678                 :   422764944 :     switch (regclass[n])
    2679                 :             :       {
    2680                 :   132429538 :       case X86_64_INTEGER_CLASS:
    2681                 :   132429538 :       case X86_64_INTEGERSI_CLASS:
    2682                 :   132429538 :         (*int_nregs)++;
    2683                 :   132429538 :         break;
    2684                 :    75656395 :       case X86_64_SSE_CLASS:
    2685                 :    75656395 :       case X86_64_SSEHF_CLASS:
    2686                 :    75656395 :       case X86_64_SSESF_CLASS:
    2687                 :    75656395 :       case X86_64_SSEDF_CLASS:
    2688                 :    75656395 :         (*sse_nregs)++;
    2689                 :    75656395 :         break;
    2690                 :             :       case X86_64_NO_CLASS:
    2691                 :             :       case X86_64_SSEUP_CLASS:
    2692                 :             :         break;
    2693                 :     9506278 :       case X86_64_X87_CLASS:
    2694                 :     9506278 :       case X86_64_X87UP_CLASS:
    2695                 :     9506278 :       case X86_64_COMPLEX_X87_CLASS:
    2696                 :     9506278 :         if (!in_return)
    2697                 :             :           return true;
    2698                 :             :         break;
    2699                 :           0 :       case X86_64_MEMORY_CLASS:
    2700                 :           0 :         gcc_unreachable ();
    2701                 :             :       }
    2702                 :             : 
    2703                 :             :   return false;
    2704                 :             : }
    2705                 :             : 
    2706                 :             : /* Construct container for the argument used by GCC interface.  See
    2707                 :             :    FUNCTION_ARG for the detailed description.  */
    2708                 :             : 
    2709                 :             : static rtx
    2710                 :   102533837 : construct_container (machine_mode mode, machine_mode orig_mode,
    2711                 :             :                      const_tree type, int in_return, int nintregs, int nsseregs,
    2712                 :             :                      const int *intreg, int sse_regno)
    2713                 :             : {
    2714                 :             :   /* The following variables hold the static issued_error state.  */
    2715                 :   102533837 :   static bool issued_sse_arg_error;
    2716                 :   102533837 :   static bool issued_sse_ret_error;
    2717                 :   102533837 :   static bool issued_x87_ret_error;
    2718                 :             : 
    2719                 :   102533837 :   machine_mode tmpmode;
    2720                 :   102533837 :   int bytes
    2721                 :   204473955 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2722                 :   102533837 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2723                 :   102533837 :   int n;
    2724                 :   102533837 :   int i;
    2725                 :   102533837 :   int nexps = 0;
    2726                 :   102533837 :   int needed_sseregs, needed_intregs;
    2727                 :   102533837 :   rtx exp[MAX_CLASSES];
    2728                 :   102533837 :   rtx ret;
    2729                 :             : 
    2730                 :   102533837 :   n = classify_argument (mode, type, regclass, 0);
    2731                 :   102533837 :   if (!n)
    2732                 :             :     return NULL;
    2733                 :   102088751 :   if (examine_argument (mode, type, in_return, &needed_intregs,
    2734                 :             :                         &needed_sseregs))
    2735                 :             :     return NULL;
    2736                 :   102040904 :   if (needed_intregs > nintregs || needed_sseregs > nsseregs)
    2737                 :             :     return NULL;
    2738                 :             : 
    2739                 :             :   /* We allowed the user to turn off SSE for kernel mode.  Don't crash if
    2740                 :             :      some less clueful developer tries to use floating-point anyway.  */
    2741                 :   100951743 :   if (needed_sseregs
    2742                 :    37385646 :       && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
    2743                 :             :     {
    2744                 :             :       /* Return early if we shouldn't raise an error for invalid
    2745                 :             :          calls.  */
    2746                 :          71 :       if (cfun != NULL && cfun->machine->silent_p)
    2747                 :             :         return NULL;
    2748                 :          39 :       if (in_return)
    2749                 :             :         {
    2750                 :          34 :           if (!issued_sse_ret_error)
    2751                 :             :             {
    2752                 :          16 :               if (VALID_SSE2_TYPE_MODE (mode))
    2753                 :           5 :                 error ("SSE register return with SSE2 disabled");
    2754                 :             :               else
    2755                 :          11 :                 error ("SSE register return with SSE disabled");
    2756                 :          16 :               issued_sse_ret_error = true;
    2757                 :             :             }
    2758                 :             :         }
    2759                 :           5 :       else if (!issued_sse_arg_error)
    2760                 :             :         {
    2761                 :           5 :           if (VALID_SSE2_TYPE_MODE (mode))
    2762                 :           0 :             error ("SSE register argument with SSE2 disabled");
    2763                 :             :           else
    2764                 :           5 :             error ("SSE register argument with SSE disabled");
    2765                 :           5 :           issued_sse_arg_error = true;
    2766                 :             :         }
    2767                 :          39 :       return NULL;
    2768                 :             :     }
    2769                 :             : 
    2770                 :             :   /* Likewise, error if the ABI requires us to return values in the
    2771                 :             :      x87 registers and the user specified -mno-80387.  */
    2772                 :   100951672 :   if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
    2773                 :     1395449 :     for (i = 0; i < n; i++)
    2774                 :      738603 :       if (regclass[i] == X86_64_X87_CLASS
    2775                 :             :           || regclass[i] == X86_64_X87UP_CLASS
    2776                 :      738603 :           || regclass[i] == X86_64_COMPLEX_X87_CLASS)
    2777                 :             :         {
    2778                 :             :           /* Return early if we shouldn't raise an error for invalid
    2779                 :             :              calls.  */
    2780                 :          14 :           if (cfun != NULL && cfun->machine->silent_p)
    2781                 :             :             return NULL;
    2782                 :          11 :           if (!issued_x87_ret_error)
    2783                 :             :             {
    2784                 :           6 :               error ("x87 register return with x87 disabled");
    2785                 :           6 :               issued_x87_ret_error = true;
    2786                 :             :             }
    2787                 :          11 :           return NULL;
    2788                 :             :         }
    2789                 :             : 
    2790                 :             :   /* First construct simple cases.  Avoid SCmode, since we want to use
    2791                 :             :      single register to pass this type.  */
    2792                 :   100951658 :   if (n == 1 && mode != SCmode && mode != HCmode)
    2793                 :    63955295 :     switch (regclass[0])
    2794                 :             :       {
    2795                 :    57923190 :       case X86_64_INTEGER_CLASS:
    2796                 :    57923190 :       case X86_64_INTEGERSI_CLASS:
    2797                 :    57923190 :         return gen_rtx_REG (mode, intreg[0]);
    2798                 :     5836108 :       case X86_64_SSE_CLASS:
    2799                 :     5836108 :       case X86_64_SSEHF_CLASS:
    2800                 :     5836108 :       case X86_64_SSESF_CLASS:
    2801                 :     5836108 :       case X86_64_SSEDF_CLASS:
    2802                 :     5836108 :         if (mode != BLKmode)
    2803                 :    11671408 :           return gen_reg_or_parallel (mode, orig_mode,
    2804                 :    11671408 :                                       GET_SSE_REGNO (sse_regno));
    2805                 :             :         break;
    2806                 :      170794 :       case X86_64_X87_CLASS:
    2807                 :      170794 :       case X86_64_COMPLEX_X87_CLASS:
    2808                 :      170794 :         return gen_rtx_REG (mode, FIRST_STACK_REG);
    2809                 :             :       case X86_64_NO_CLASS:
    2810                 :             :         /* Zero sized array, struct or class.  */
    2811                 :             :         return NULL;
    2812                 :           0 :       default:
    2813                 :           0 :         gcc_unreachable ();
    2814                 :             :       }
    2815                 :    36996767 :   if (n == 2
    2816                 :    18394994 :       && regclass[0] == X86_64_SSE_CLASS
    2817                 :    12692198 :       && regclass[1] == X86_64_SSEUP_CLASS
    2818                 :    12687467 :       && mode != BLKmode)
    2819                 :    25374934 :     return gen_reg_or_parallel (mode, orig_mode,
    2820                 :    25374934 :                                 GET_SSE_REGNO (sse_regno));
    2821                 :    24309300 :   if (n == 4
    2822                 :     9689732 :       && regclass[0] == X86_64_SSE_CLASS
    2823                 :     9689732 :       && regclass[1] == X86_64_SSEUP_CLASS
    2824                 :     9689732 :       && regclass[2] == X86_64_SSEUP_CLASS
    2825                 :     9689732 :       && regclass[3] == X86_64_SSEUP_CLASS
    2826                 :     9689732 :       && mode != BLKmode)
    2827                 :    19376086 :     return gen_reg_or_parallel (mode, orig_mode,
    2828                 :    19376086 :                                 GET_SSE_REGNO (sse_regno));
    2829                 :    14621257 :   if (n == 8
    2830                 :     8658448 :       && regclass[0] == X86_64_SSE_CLASS
    2831                 :     8658448 :       && regclass[1] == X86_64_SSEUP_CLASS
    2832                 :     8658448 :       && regclass[2] == X86_64_SSEUP_CLASS
    2833                 :     8658448 :       && regclass[3] == X86_64_SSEUP_CLASS
    2834                 :     8658448 :       && regclass[4] == X86_64_SSEUP_CLASS
    2835                 :     8658448 :       && regclass[5] == X86_64_SSEUP_CLASS
    2836                 :     8658448 :       && regclass[6] == X86_64_SSEUP_CLASS
    2837                 :     8658448 :       && regclass[7] == X86_64_SSEUP_CLASS
    2838                 :     8658448 :       && mode != BLKmode)
    2839                 :    17312624 :     return gen_reg_or_parallel (mode, orig_mode,
    2840                 :    17312624 :                                 GET_SSE_REGNO (sse_regno));
    2841                 :     5964945 :   if (n == 2
    2842                 :     5707527 :       && regclass[0] == X86_64_X87_CLASS
    2843                 :     2271796 :       && regclass[1] == X86_64_X87UP_CLASS)
    2844                 :     2271796 :     return gen_rtx_REG (XFmode, FIRST_STACK_REG);
    2845                 :             : 
    2846                 :     3693149 :   if (n == 2
    2847                 :     3435731 :       && regclass[0] == X86_64_INTEGER_CLASS
    2848                 :     3060847 :       && regclass[1] == X86_64_INTEGER_CLASS
    2849                 :     3052734 :       && (mode == CDImode || mode == TImode || mode == BLKmode)
    2850                 :     3052734 :       && intreg[0] + 1 == intreg[1])
    2851                 :             :     {
    2852                 :     2752298 :       if (mode == BLKmode)
    2853                 :             :         {
    2854                 :             :           /* Use TImode for BLKmode values in 2 integer registers.  */
    2855                 :      528576 :           exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
    2856                 :      264288 :                                       gen_rtx_REG (TImode, intreg[0]),
    2857                 :             :                                       GEN_INT (0));
    2858                 :      264288 :           ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
    2859                 :      264288 :           XVECEXP (ret, 0, 0) = exp[0];
    2860                 :      264288 :           return ret;
    2861                 :             :         }
    2862                 :             :       else
    2863                 :     2488010 :         return gen_rtx_REG (mode, intreg[0]);
    2864                 :             :     }
    2865                 :             : 
    2866                 :             :   /* Otherwise figure out the entries of the PARALLEL.  */
    2867                 :     2565135 :   for (i = 0; i < n; i++)
    2868                 :             :     {
    2869                 :     1624284 :       int pos;
    2870                 :             : 
    2871                 :     1624284 :       switch (regclass[i])
    2872                 :             :         {
    2873                 :             :           case X86_64_NO_CLASS:
    2874                 :             :             break;
    2875                 :      848804 :           case X86_64_INTEGER_CLASS:
    2876                 :      848804 :           case X86_64_INTEGERSI_CLASS:
    2877                 :             :             /* Merge TImodes on aligned occasions here too.  */
    2878                 :      848804 :             if (i * 8 + 8 > bytes)
    2879                 :             :               {
    2880                 :        3219 :                 unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
    2881                 :        3219 :                 if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
    2882                 :             :                   /* We've requested 24 bytes we
    2883                 :             :                      don't have mode for.  Use DImode.  */
    2884                 :         358 :                   tmpmode = DImode;
    2885                 :             :               }
    2886                 :      845585 :             else if (regclass[i] == X86_64_INTEGERSI_CLASS)
    2887                 :             :               tmpmode = SImode;
    2888                 :             :             else
    2889                 :      727124 :               tmpmode = DImode;
    2890                 :     1697608 :             exp [nexps++]
    2891                 :      848804 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2892                 :      848804 :                                    gen_rtx_REG (tmpmode, *intreg),
    2893                 :      848804 :                                    GEN_INT (i*8));
    2894                 :      848804 :             intreg++;
    2895                 :      848804 :             break;
    2896                 :         592 :           case X86_64_SSEHF_CLASS:
    2897                 :         592 :             tmpmode = (mode == BFmode ? BFmode : HFmode);
    2898                 :        1184 :             exp [nexps++]
    2899                 :        1184 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2900                 :             :                                    gen_rtx_REG (tmpmode,
    2901                 :         592 :                                                 GET_SSE_REGNO (sse_regno)),
    2902                 :         592 :                                    GEN_INT (i*8));
    2903                 :         592 :             sse_regno++;
    2904                 :         592 :             break;
    2905                 :        2818 :           case X86_64_SSESF_CLASS:
    2906                 :        5636 :             exp [nexps++]
    2907                 :        5636 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2908                 :             :                                    gen_rtx_REG (SFmode,
    2909                 :        2818 :                                                 GET_SSE_REGNO (sse_regno)),
    2910                 :        2818 :                                    GEN_INT (i*8));
    2911                 :        2818 :             sse_regno++;
    2912                 :        2818 :             break;
    2913                 :      497498 :           case X86_64_SSEDF_CLASS:
    2914                 :      994996 :             exp [nexps++]
    2915                 :      994996 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2916                 :             :                                    gen_rtx_REG (DFmode,
    2917                 :      497498 :                                                 GET_SSE_REGNO (sse_regno)),
    2918                 :      497498 :                                    GEN_INT (i*8));
    2919                 :      497498 :             sse_regno++;
    2920                 :      497498 :             break;
    2921                 :      266508 :           case X86_64_SSE_CLASS:
    2922                 :      266508 :             pos = i;
    2923                 :      266508 :             switch (n)
    2924                 :             :               {
    2925                 :             :               case 1:
    2926                 :             :                 tmpmode = DImode;
    2927                 :             :                 break;
    2928                 :        9304 :               case 2:
    2929                 :        9304 :                 if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
    2930                 :             :                   {
    2931                 :           0 :                     tmpmode = TImode;
    2932                 :           0 :                     i++;
    2933                 :             :                   }
    2934                 :             :                 else
    2935                 :             :                   tmpmode = DImode;
    2936                 :             :                 break;
    2937                 :        1689 :               case 4:
    2938                 :        1689 :                 gcc_assert (i == 0
    2939                 :             :                             && regclass[1] == X86_64_SSEUP_CLASS
    2940                 :             :                             && regclass[2] == X86_64_SSEUP_CLASS
    2941                 :             :                             && regclass[3] == X86_64_SSEUP_CLASS);
    2942                 :             :                 tmpmode = OImode;
    2943                 :             :                 i += 3;
    2944                 :             :                 break;
    2945                 :        2136 :               case 8:
    2946                 :        2136 :                 gcc_assert (i == 0
    2947                 :             :                             && regclass[1] == X86_64_SSEUP_CLASS
    2948                 :             :                             && regclass[2] == X86_64_SSEUP_CLASS
    2949                 :             :                             && regclass[3] == X86_64_SSEUP_CLASS
    2950                 :             :                             && regclass[4] == X86_64_SSEUP_CLASS
    2951                 :             :                             && regclass[5] == X86_64_SSEUP_CLASS
    2952                 :             :                             && regclass[6] == X86_64_SSEUP_CLASS
    2953                 :             :                             && regclass[7] == X86_64_SSEUP_CLASS);
    2954                 :             :                 tmpmode = XImode;
    2955                 :             :                 i += 7;
    2956                 :             :                 break;
    2957                 :           0 :               default:
    2958                 :           0 :                 gcc_unreachable ();
    2959                 :             :               }
    2960                 :      533016 :             exp [nexps++]
    2961                 :      533016 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2962                 :             :                                    gen_rtx_REG (tmpmode,
    2963                 :      266508 :                                                 GET_SSE_REGNO (sse_regno)),
    2964                 :      266508 :                                    GEN_INT (pos*8));
    2965                 :      266508 :             sse_regno++;
    2966                 :      266508 :             break;
    2967                 :           0 :           default:
    2968                 :           0 :             gcc_unreachable ();
    2969                 :             :         }
    2970                 :             :     }
    2971                 :             : 
    2972                 :             :   /* Empty aligned struct, union or class.  */
    2973                 :      940851 :   if (nexps == 0)
    2974                 :             :     return NULL;
    2975                 :             : 
    2976                 :      940596 :   ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
    2977                 :     2556816 :   for (i = 0; i < nexps; i++)
    2978                 :     1616220 :     XVECEXP (ret, 0, i) = exp [i];
    2979                 :             :   return ret;
    2980                 :             : }
    2981                 :             : 
    2982                 :             : /* Update the data in CUM to advance over an argument of mode MODE
    2983                 :             :    and data type TYPE.  (TYPE is null for libcalls where that information
    2984                 :             :    may not be available.)
    2985                 :             : 
    2986                 :             :    Return a number of integer regsiters advanced over.  */
    2987                 :             : 
    2988                 :             : static int
    2989                 :     2096600 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    2990                 :             :                          const_tree type, HOST_WIDE_INT bytes,
    2991                 :             :                          HOST_WIDE_INT words)
    2992                 :             : {
    2993                 :     2096600 :   int res = 0;
    2994                 :     2096600 :   bool error_p = false;
    2995                 :             : 
    2996                 :     2096600 :   if (TARGET_IAMCU)
    2997                 :             :     {
    2998                 :             :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    2999                 :             :          bytes in registers.  */
    3000                 :           0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3001                 :           0 :         goto pass_in_reg;
    3002                 :             :       return res;
    3003                 :             :     }
    3004                 :             : 
    3005                 :     2096600 :   switch (mode)
    3006                 :             :     {
    3007                 :             :     default:
    3008                 :             :       break;
    3009                 :             : 
    3010                 :       93524 :     case E_BLKmode:
    3011                 :       93524 :       if (bytes < 0)
    3012                 :             :         break;
    3013                 :             :       /* FALLTHRU */
    3014                 :             : 
    3015                 :     2060084 :     case E_DImode:
    3016                 :     2060084 :     case E_SImode:
    3017                 :     2060084 :     case E_HImode:
    3018                 :     2060084 :     case E_QImode:
    3019                 :       93524 : pass_in_reg:
    3020                 :     2060084 :       cum->words += words;
    3021                 :     2060084 :       cum->nregs -= words;
    3022                 :     2060084 :       cum->regno += words;
    3023                 :     2060084 :       if (cum->nregs >= 0)
    3024                 :       45862 :         res = words;
    3025                 :     2060084 :       if (cum->nregs <= 0)
    3026                 :             :         {
    3027                 :     2027145 :           cum->nregs = 0;
    3028                 :     2027145 :           cfun->machine->arg_reg_available = false;
    3029                 :     2027145 :           cum->regno = 0;
    3030                 :             :         }
    3031                 :             :       break;
    3032                 :             : 
    3033                 :           0 :     case E_OImode:
    3034                 :             :       /* OImode shouldn't be used directly.  */
    3035                 :           0 :       gcc_unreachable ();
    3036                 :             : 
    3037                 :        4679 :     case E_DFmode:
    3038                 :        4679 :       if (cum->float_in_sse == -1)
    3039                 :           0 :         error_p = true;
    3040                 :        4679 :       if (cum->float_in_sse < 2)
    3041                 :             :         break;
    3042                 :             :       /* FALLTHRU */
    3043                 :        1349 :     case E_SFmode:
    3044                 :        1349 :       if (cum->float_in_sse == -1)
    3045                 :           0 :         error_p = true;
    3046                 :        1349 :       if (cum->float_in_sse < 1)
    3047                 :             :         break;
    3048                 :             :       /* FALLTHRU */
    3049                 :             : 
    3050                 :          52 :     case E_V16HFmode:
    3051                 :          52 :     case E_V16BFmode:
    3052                 :          52 :     case E_V8SFmode:
    3053                 :          52 :     case E_V8SImode:
    3054                 :          52 :     case E_V64QImode:
    3055                 :          52 :     case E_V32HImode:
    3056                 :          52 :     case E_V16SImode:
    3057                 :          52 :     case E_V8DImode:
    3058                 :          52 :     case E_V32HFmode:
    3059                 :          52 :     case E_V32BFmode:
    3060                 :          52 :     case E_V16SFmode:
    3061                 :          52 :     case E_V8DFmode:
    3062                 :          52 :     case E_V32QImode:
    3063                 :          52 :     case E_V16HImode:
    3064                 :          52 :     case E_V4DFmode:
    3065                 :          52 :     case E_V4DImode:
    3066                 :          52 :     case E_TImode:
    3067                 :          52 :     case E_V16QImode:
    3068                 :          52 :     case E_V8HImode:
    3069                 :          52 :     case E_V4SImode:
    3070                 :          52 :     case E_V2DImode:
    3071                 :          52 :     case E_V8HFmode:
    3072                 :          52 :     case E_V8BFmode:
    3073                 :          52 :     case E_V4SFmode:
    3074                 :          52 :     case E_V2DFmode:
    3075                 :          52 :       if (!type || !AGGREGATE_TYPE_P (type))
    3076                 :             :         {
    3077                 :          52 :           cum->sse_words += words;
    3078                 :          52 :           cum->sse_nregs -= 1;
    3079                 :          52 :           cum->sse_regno += 1;
    3080                 :          52 :           if (cum->sse_nregs <= 0)
    3081                 :             :             {
    3082                 :           4 :               cum->sse_nregs = 0;
    3083                 :           4 :               cum->sse_regno = 0;
    3084                 :             :             }
    3085                 :             :         }
    3086                 :             :       break;
    3087                 :             : 
    3088                 :          12 :     case E_V8QImode:
    3089                 :          12 :     case E_V4HImode:
    3090                 :          12 :     case E_V4HFmode:
    3091                 :          12 :     case E_V4BFmode:
    3092                 :          12 :     case E_V2SImode:
    3093                 :          12 :     case E_V2SFmode:
    3094                 :          12 :     case E_V1TImode:
    3095                 :          12 :     case E_V1DImode:
    3096                 :          12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3097                 :             :         {
    3098                 :          12 :           cum->mmx_words += words;
    3099                 :          12 :           cum->mmx_nregs -= 1;
    3100                 :          12 :           cum->mmx_regno += 1;
    3101                 :          12 :           if (cum->mmx_nregs <= 0)
    3102                 :             :             {
    3103                 :           0 :               cum->mmx_nregs = 0;
    3104                 :           0 :               cum->mmx_regno = 0;
    3105                 :             :             }
    3106                 :             :         }
    3107                 :             :       break;
    3108                 :             :     }
    3109                 :     2033225 :   if (error_p)
    3110                 :             :     {
    3111                 :           0 :       cum->float_in_sse = 0;
    3112                 :           0 :       error ("calling %qD with SSE calling convention without "
    3113                 :             :              "SSE/SSE2 enabled", cum->decl);
    3114                 :           0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3115                 :             :              "attribute used to function called");
    3116                 :             :     }
    3117                 :             : 
    3118                 :             :   return res;
    3119                 :             : }
    3120                 :             : 
    3121                 :             : static int
    3122                 :    18233657 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3123                 :             :                          const_tree type, HOST_WIDE_INT words, bool named)
    3124                 :             : {
    3125                 :    18233657 :   int int_nregs, sse_nregs;
    3126                 :             : 
    3127                 :             :   /* Unnamed 512 and 256bit vector mode parameters are passed on stack.  */
    3128                 :    18233657 :   if (!named && (VALID_AVX512F_REG_MODE (mode)
    3129                 :             :                  || VALID_AVX256_REG_MODE (mode)))
    3130                 :             :     return 0;
    3131                 :             : 
    3132                 :    18233293 :   if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
    3133                 :    18233293 :       && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
    3134                 :             :     {
    3135                 :    15984786 :       cum->nregs -= int_nregs;
    3136                 :    15984786 :       cum->sse_nregs -= sse_nregs;
    3137                 :    15984786 :       cum->regno += int_nregs;
    3138                 :    15984786 :       cum->sse_regno += sse_nregs;
    3139                 :    15984786 :       return int_nregs;
    3140                 :             :     }
    3141                 :             :   else
    3142                 :             :     {
    3143                 :     2248507 :       int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
    3144                 :     2248507 :       cum->words = ROUND_UP (cum->words, align);
    3145                 :     2248507 :       cum->words += words;
    3146                 :     2248507 :       return 0;
    3147                 :             :     }
    3148                 :             : }
    3149                 :             : 
    3150                 :             : static int
    3151                 :      447202 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
    3152                 :             :                             HOST_WIDE_INT words)
    3153                 :             : {
    3154                 :             :   /* Otherwise, this should be passed indirect.  */
    3155                 :      447202 :   gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
    3156                 :             : 
    3157                 :      447202 :   cum->words += words;
    3158                 :      447202 :   if (cum->nregs > 0)
    3159                 :             :     {
    3160                 :      289517 :       cum->nregs -= 1;
    3161                 :      289517 :       cum->regno += 1;
    3162                 :      289517 :       return 1;
    3163                 :             :     }
    3164                 :             :   return 0;
    3165                 :             : }
    3166                 :             : 
    3167                 :             : /* Update the data in CUM to advance over argument ARG.  */
    3168                 :             : 
    3169                 :             : static void
    3170                 :    20777813 : ix86_function_arg_advance (cumulative_args_t cum_v,
    3171                 :             :                            const function_arg_info &arg)
    3172                 :             : {
    3173                 :    20777813 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3174                 :    20777813 :   machine_mode mode = arg.mode;
    3175                 :    20777813 :   HOST_WIDE_INT bytes, words;
    3176                 :    20777813 :   int nregs;
    3177                 :             : 
    3178                 :             :   /* The argument of interrupt handler is a special case and is
    3179                 :             :      handled in ix86_function_arg.  */
    3180                 :    20777813 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3181                 :             :     return;
    3182                 :             : 
    3183                 :    20777459 :   bytes = arg.promoted_size_in_bytes ();
    3184                 :    20777459 :   words = CEIL (bytes, UNITS_PER_WORD);
    3185                 :             : 
    3186                 :    20777459 :   if (arg.type)
    3187                 :    20503798 :     mode = type_natural_mode (arg.type, NULL, false);
    3188                 :             : 
    3189                 :    20777459 :   if (TARGET_64BIT)
    3190                 :             :     {
    3191                 :    18680859 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3192                 :             : 
    3193                 :    18680859 :       if (call_abi == MS_ABI)
    3194                 :      447202 :         nregs = function_arg_advance_ms_64 (cum, bytes, words);
    3195                 :             :       else
    3196                 :    18233657 :         nregs = function_arg_advance_64 (cum, mode, arg.type, words,
    3197                 :    18233657 :                                          arg.named);
    3198                 :             :     }
    3199                 :             :   else
    3200                 :     2096600 :     nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
    3201                 :             : 
    3202                 :    20777459 :   if (!nregs)
    3203                 :             :     {
    3204                 :             :       /* Track if there are outgoing arguments on stack.  */
    3205                 :     5637325 :       if (cum->caller)
    3206                 :     2682063 :         cfun->machine->outgoing_args_on_stack = true;
    3207                 :             :     }
    3208                 :             : }
    3209                 :             : 
    3210                 :             : /* Define where to put the arguments to a function.
    3211                 :             :    Value is zero to push the argument on the stack,
    3212                 :             :    or a hard register in which to store the argument.
    3213                 :             : 
    3214                 :             :    MODE is the argument's machine mode.
    3215                 :             :    TYPE is the data type of the argument (as a tree).
    3216                 :             :     This is null for libcalls where that information may
    3217                 :             :     not be available.
    3218                 :             :    CUM is a variable of type CUMULATIVE_ARGS which gives info about
    3219                 :             :     the preceding args and about the function being called.
    3220                 :             :    NAMED is nonzero if this argument is a named parameter
    3221                 :             :     (otherwise it is an extra parameter matching an ellipsis).  */
    3222                 :             : 
    3223                 :             : static rtx
    3224                 :     2520173 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3225                 :             :                  machine_mode orig_mode, const_tree type,
    3226                 :             :                  HOST_WIDE_INT bytes, HOST_WIDE_INT words)
    3227                 :             : {
    3228                 :     2520173 :   bool error_p = false;
    3229                 :             : 
    3230                 :             :   /* Avoid the AL settings for the Unix64 ABI.  */
    3231                 :     2520173 :   if (mode == VOIDmode)
    3232                 :      732799 :     return constm1_rtx;
    3233                 :             : 
    3234                 :     1787374 :   if (TARGET_IAMCU)
    3235                 :             :     {
    3236                 :             :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3237                 :             :          bytes in registers.  */
    3238                 :           0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3239                 :           0 :         goto pass_in_reg;
    3240                 :             :       return NULL_RTX;
    3241                 :             :     }
    3242                 :             : 
    3243                 :     1787374 :   switch (mode)
    3244                 :             :     {
    3245                 :             :     default:
    3246                 :             :       break;
    3247                 :             : 
    3248                 :       77570 :     case E_BLKmode:
    3249                 :       77570 :       if (bytes < 0)
    3250                 :             :         break;
    3251                 :             :       /* FALLTHRU */
    3252                 :     1754109 :     case E_DImode:
    3253                 :     1754109 :     case E_SImode:
    3254                 :     1754109 :     case E_HImode:
    3255                 :     1754109 :     case E_QImode:
    3256                 :       77570 : pass_in_reg:
    3257                 :     1754109 :       if (words <= cum->nregs)
    3258                 :             :         {
    3259                 :       44030 :           int regno = cum->regno;
    3260                 :             : 
    3261                 :             :           /* Fastcall allocates the first two DWORD (SImode) or
    3262                 :             :             smaller arguments to ECX and EDX if it isn't an
    3263                 :             :             aggregate type .  */
    3264                 :       44030 :           if (cum->fastcall)
    3265                 :             :             {
    3266                 :           6 :               if (mode == BLKmode
    3267                 :           6 :                   || mode == DImode
    3268                 :           6 :                   || (type && AGGREGATE_TYPE_P (type)))
    3269                 :             :                 break;
    3270                 :             : 
    3271                 :             :               /* ECX not EAX is the first allocated register.  */
    3272                 :           6 :               if (regno == AX_REG)
    3273                 :       44030 :                 regno = CX_REG;
    3274                 :             :             }
    3275                 :       44030 :           return gen_rtx_REG (mode, regno);
    3276                 :             :         }
    3277                 :             :       break;
    3278                 :             : 
    3279                 :        3298 :     case E_DFmode:
    3280                 :        3298 :       if (cum->float_in_sse == -1)
    3281                 :           0 :         error_p = true;
    3282                 :        3298 :       if (cum->float_in_sse < 2)
    3283                 :             :         break;
    3284                 :             :       /* FALLTHRU */
    3285                 :         958 :     case E_SFmode:
    3286                 :         958 :       if (cum->float_in_sse == -1)
    3287                 :           0 :         error_p = true;
    3288                 :         958 :       if (cum->float_in_sse < 1)
    3289                 :             :         break;
    3290                 :             :       /* FALLTHRU */
    3291                 :          12 :     case E_TImode:
    3292                 :             :       /* In 32bit, we pass TImode in xmm registers.  */
    3293                 :          12 :     case E_V16QImode:
    3294                 :          12 :     case E_V8HImode:
    3295                 :          12 :     case E_V4SImode:
    3296                 :          12 :     case E_V2DImode:
    3297                 :          12 :     case E_V8HFmode:
    3298                 :          12 :     case E_V8BFmode:
    3299                 :          12 :     case E_V4SFmode:
    3300                 :          12 :     case E_V2DFmode:
    3301                 :          12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3302                 :             :         {
    3303                 :          12 :           if (cum->sse_nregs)
    3304                 :          12 :             return gen_reg_or_parallel (mode, orig_mode,
    3305                 :          12 :                                         cum->sse_regno + FIRST_SSE_REG);
    3306                 :             :         }
    3307                 :             :       break;
    3308                 :             : 
    3309                 :           0 :     case E_OImode:
    3310                 :           0 :     case E_XImode:
    3311                 :             :       /* OImode and XImode shouldn't be used directly.  */
    3312                 :           0 :       gcc_unreachable ();
    3313                 :             : 
    3314                 :           9 :     case E_V64QImode:
    3315                 :           9 :     case E_V32HImode:
    3316                 :           9 :     case E_V16SImode:
    3317                 :           9 :     case E_V8DImode:
    3318                 :           9 :     case E_V32HFmode:
    3319                 :           9 :     case E_V32BFmode:
    3320                 :           9 :     case E_V16SFmode:
    3321                 :           9 :     case E_V8DFmode:
    3322                 :           9 :     case E_V16HFmode:
    3323                 :           9 :     case E_V16BFmode:
    3324                 :           9 :     case E_V8SFmode:
    3325                 :           9 :     case E_V8SImode:
    3326                 :           9 :     case E_V32QImode:
    3327                 :           9 :     case E_V16HImode:
    3328                 :           9 :     case E_V4DFmode:
    3329                 :           9 :     case E_V4DImode:
    3330                 :           9 :       if (!type || !AGGREGATE_TYPE_P (type))
    3331                 :             :         {
    3332                 :           9 :           if (cum->sse_nregs)
    3333                 :           9 :             return gen_reg_or_parallel (mode, orig_mode,
    3334                 :           9 :                                         cum->sse_regno + FIRST_SSE_REG);
    3335                 :             :         }
    3336                 :             :       break;
    3337                 :             : 
    3338                 :           6 :     case E_V8QImode:
    3339                 :           6 :     case E_V4HImode:
    3340                 :           6 :     case E_V4HFmode:
    3341                 :           6 :     case E_V4BFmode:
    3342                 :           6 :     case E_V2SImode:
    3343                 :           6 :     case E_V2SFmode:
    3344                 :           6 :     case E_V1TImode:
    3345                 :           6 :     case E_V1DImode:
    3346                 :           6 :       if (!type || !AGGREGATE_TYPE_P (type))
    3347                 :             :         {
    3348                 :           6 :           if (cum->mmx_nregs)
    3349                 :           6 :             return gen_reg_or_parallel (mode, orig_mode,
    3350                 :           6 :                                         cum->mmx_regno + FIRST_MMX_REG);
    3351                 :             :         }
    3352                 :             :       break;
    3353                 :             :     }
    3354                 :        4256 :   if (error_p)
    3355                 :             :     {
    3356                 :           0 :       cum->float_in_sse = 0;
    3357                 :           0 :       error ("calling %qD with SSE calling convention without "
    3358                 :             :              "SSE/SSE2 enabled", cum->decl);
    3359                 :           0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3360                 :             :              "attribute used to function called");
    3361                 :             :     }
    3362                 :             : 
    3363                 :             :   return NULL_RTX;
    3364                 :             : }
    3365                 :             : 
    3366                 :             : static rtx
    3367                 :    18074349 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3368                 :             :                  machine_mode orig_mode, const_tree type, bool named)
    3369                 :             : {
    3370                 :             :   /* Handle a hidden AL argument containing number of registers
    3371                 :             :      for varargs x86-64 functions.  */
    3372                 :    18074349 :   if (mode == VOIDmode)
    3373                 :     4978277 :     return GEN_INT (cum->maybe_vaarg
    3374                 :             :                     ? (cum->sse_nregs < 0
    3375                 :             :                        ? X86_64_SSE_REGPARM_MAX
    3376                 :             :                        : cum->sse_regno)
    3377                 :             :                     : -1);
    3378                 :             : 
    3379                 :    13096072 :   switch (mode)
    3380                 :             :     {
    3381                 :             :     default:
    3382                 :             :       break;
    3383                 :             : 
    3384                 :       95327 :     case E_V16HFmode:
    3385                 :       95327 :     case E_V16BFmode:
    3386                 :       95327 :     case E_V8SFmode:
    3387                 :       95327 :     case E_V8SImode:
    3388                 :       95327 :     case E_V32QImode:
    3389                 :       95327 :     case E_V16HImode:
    3390                 :       95327 :     case E_V4DFmode:
    3391                 :       95327 :     case E_V4DImode:
    3392                 :       95327 :     case E_V32HFmode:
    3393                 :       95327 :     case E_V32BFmode:
    3394                 :       95327 :     case E_V16SFmode:
    3395                 :       95327 :     case E_V16SImode:
    3396                 :       95327 :     case E_V64QImode:
    3397                 :       95327 :     case E_V32HImode:
    3398                 :       95327 :     case E_V8DFmode:
    3399                 :       95327 :     case E_V8DImode:
    3400                 :             :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    3401                 :       95327 :       if (!named)
    3402                 :             :         return NULL;
    3403                 :             :       break;
    3404                 :             :     }
    3405                 :             : 
    3406                 :    13095708 :   return construct_container (mode, orig_mode, type, 0, cum->nregs,
    3407                 :    13095708 :                               cum->sse_nregs,
    3408                 :    13095708 :                               &x86_64_int_parameter_registers [cum->regno],
    3409                 :    13095708 :                               cum->sse_regno);
    3410                 :             : }
    3411                 :             : 
    3412                 :             : static rtx
    3413                 :      296624 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3414                 :             :                     machine_mode orig_mode, bool named, const_tree type,
    3415                 :             :                     HOST_WIDE_INT bytes)
    3416                 :             : {
    3417                 :      296624 :   unsigned int regno;
    3418                 :             : 
    3419                 :             :   /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
    3420                 :             :      We use value of -2 to specify that current function call is MSABI.  */
    3421                 :      296624 :   if (mode == VOIDmode)
    3422                 :       36356 :     return GEN_INT (-2);
    3423                 :             : 
    3424                 :             :   /* If we've run out of registers, it goes on the stack.  */
    3425                 :      260268 :   if (cum->nregs == 0)
    3426                 :             :     return NULL_RTX;
    3427                 :             : 
    3428                 :      176462 :   regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
    3429                 :             : 
    3430                 :             :   /* Only floating point modes are passed in anything but integer regs.  */
    3431                 :      176462 :   if (TARGET_SSE && (mode == SFmode || mode == DFmode))
    3432                 :             :     {
    3433                 :       38334 :       if (named)
    3434                 :             :         {
    3435                 :       38334 :           if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
    3436                 :       37337 :             regno = cum->regno + FIRST_SSE_REG;
    3437                 :             :         }
    3438                 :             :       else
    3439                 :             :         {
    3440                 :           0 :           rtx t1, t2;
    3441                 :             : 
    3442                 :             :           /* Unnamed floating parameters are passed in both the
    3443                 :             :              SSE and integer registers.  */
    3444                 :           0 :           t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
    3445                 :           0 :           t2 = gen_rtx_REG (mode, regno);
    3446                 :           0 :           t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
    3447                 :           0 :           t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
    3448                 :           0 :           return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
    3449                 :             :         }
    3450                 :             :     }
    3451                 :             :   /* Handle aggregated types passed in register.  */
    3452                 :      176462 :   if (orig_mode == BLKmode)
    3453                 :             :     {
    3454                 :           0 :       if (bytes > 0 && bytes <= 8)
    3455                 :           0 :         mode = (bytes > 4 ? DImode : SImode);
    3456                 :           0 :       if (mode == BLKmode)
    3457                 :           0 :         mode = DImode;
    3458                 :             :     }
    3459                 :             : 
    3460                 :      176462 :   return gen_reg_or_parallel (mode, orig_mode, regno);
    3461                 :             : }
    3462                 :             : 
    3463                 :             : /* Return where to put the arguments to a function.
    3464                 :             :    Return zero to push the argument on the stack, or a hard register in which to store the argument.
    3465                 :             : 
    3466                 :             :    ARG describes the argument while CUM gives information about the
    3467                 :             :    preceding args and about the function being called.  */
    3468                 :             : 
    3469                 :             : static rtx
    3470                 :    20891327 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    3471                 :             : {
    3472                 :    20891327 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3473                 :    20891327 :   machine_mode mode = arg.mode;
    3474                 :    20891327 :   HOST_WIDE_INT bytes, words;
    3475                 :    20891327 :   rtx reg;
    3476                 :             : 
    3477                 :    20891327 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3478                 :             :     {
    3479                 :         181 :       gcc_assert (arg.type != NULL_TREE);
    3480                 :         181 :       if (POINTER_TYPE_P (arg.type))
    3481                 :             :         {
    3482                 :             :           /* This is the pointer argument.  */
    3483                 :         118 :           gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
    3484                 :             :           /* It is at -WORD(AP) in the current frame in interrupt and
    3485                 :             :              exception handlers.  */
    3486                 :         118 :           reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
    3487                 :             :         }
    3488                 :             :       else
    3489                 :             :         {
    3490                 :          63 :           gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
    3491                 :             :                       && TREE_CODE (arg.type) == INTEGER_TYPE
    3492                 :             :                       && TYPE_MODE (arg.type) == word_mode);
    3493                 :             :           /* The error code is the word-mode integer argument at
    3494                 :             :              -2 * WORD(AP) in the current frame of the exception
    3495                 :             :              handler.  */
    3496                 :          63 :           reg = gen_rtx_MEM (word_mode,
    3497                 :          63 :                              plus_constant (Pmode,
    3498                 :             :                                             arg_pointer_rtx,
    3499                 :          63 :                                             -2 * UNITS_PER_WORD));
    3500                 :             :         }
    3501                 :         181 :       return reg;
    3502                 :             :     }
    3503                 :             : 
    3504                 :    20891146 :   bytes = arg.promoted_size_in_bytes ();
    3505                 :    20891146 :   words = CEIL (bytes, UNITS_PER_WORD);
    3506                 :             : 
    3507                 :             :   /* To simplify the code below, represent vector types with a vector mode
    3508                 :             :      even if MMX/SSE are not active.  */
    3509                 :    20891146 :   if (arg.type && VECTOR_TYPE_P (arg.type))
    3510                 :      175867 :     mode = type_natural_mode (arg.type, cum, false);
    3511                 :             : 
    3512                 :    20891146 :   if (TARGET_64BIT)
    3513                 :             :     {
    3514                 :    18370973 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3515                 :             : 
    3516                 :    18370973 :       if (call_abi == MS_ABI)
    3517                 :      296624 :         reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
    3518                 :      296624 :                                   arg.type, bytes);
    3519                 :             :       else
    3520                 :    18074349 :         reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
    3521                 :             :     }
    3522                 :             :   else
    3523                 :     2520173 :     reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
    3524                 :             : 
    3525                 :             :   /* Track if there are outgoing arguments on stack.  */
    3526                 :    20891146 :   if (reg == NULL_RTX && cum->caller)
    3527                 :     2160430 :     cfun->machine->outgoing_args_on_stack = true;
    3528                 :             : 
    3529                 :             :   return reg;
    3530                 :             : }
    3531                 :             : 
    3532                 :             : /* A C expression that indicates when an argument must be passed by
    3533                 :             :    reference.  If nonzero for an argument, a copy of that argument is
    3534                 :             :    made in memory and a pointer to the argument is passed instead of
    3535                 :             :    the argument itself.  The pointer is passed in whatever way is
    3536                 :             :    appropriate for passing a pointer to that type.  */
    3537                 :             : 
    3538                 :             : static bool
    3539                 :    20738510 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
    3540                 :             : {
    3541                 :    20738510 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3542                 :             : 
    3543                 :    20738510 :   if (TARGET_64BIT)
    3544                 :             :     {
    3545                 :    18652149 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3546                 :             : 
    3547                 :             :       /* See Windows x64 Software Convention.  */
    3548                 :    18652149 :       if (call_abi == MS_ABI)
    3549                 :             :         {
    3550                 :      441603 :           HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
    3551                 :             : 
    3552                 :      441603 :           if (tree type = arg.type)
    3553                 :             :             {
    3554                 :             :               /* Arrays are passed by reference.  */
    3555                 :      441603 :               if (TREE_CODE (type) == ARRAY_TYPE)
    3556                 :             :                 return true;
    3557                 :             : 
    3558                 :      441603 :               if (RECORD_OR_UNION_TYPE_P (type))
    3559                 :             :                 {
    3560                 :             :                   /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
    3561                 :             :                      are passed by reference.  */
    3562                 :       15036 :                   msize = int_size_in_bytes (type);
    3563                 :             :                 }
    3564                 :             :             }
    3565                 :             : 
    3566                 :             :           /* __m128 is passed by reference.  */
    3567                 :      873271 :           return msize != 1 && msize != 2 && msize != 4 && msize != 8;
    3568                 :             :         }
    3569                 :    18210546 :       else if (arg.type && int_size_in_bytes (arg.type) == -1)
    3570                 :             :         return true;
    3571                 :             :     }
    3572                 :             : 
    3573                 :             :   return false;
    3574                 :             : }
    3575                 :             : 
    3576                 :             : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3577                 :             :    passing ABI.  XXX: This function is obsolete and is only used for
    3578                 :             :    checking psABI compatibility with previous versions of GCC.  */
    3579                 :             : 
    3580                 :             : static bool
    3581                 :     1935621 : ix86_compat_aligned_value_p (const_tree type)
    3582                 :             : {
    3583                 :     1935621 :   machine_mode mode = TYPE_MODE (type);
    3584                 :     1935621 :   if (((TARGET_SSE && SSE_REG_MODE_P (mode))
    3585                 :     1935579 :        || mode == TDmode
    3586                 :     1935579 :        || mode == TFmode
    3587                 :             :        || mode == TCmode)
    3588                 :     1935833 :       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
    3589                 :             :     return true;
    3590                 :     1935409 :   if (TYPE_ALIGN (type) < 128)
    3591                 :             :     return false;
    3592                 :             : 
    3593                 :           0 :   if (AGGREGATE_TYPE_P (type))
    3594                 :             :     {
    3595                 :             :       /* Walk the aggregates recursively.  */
    3596                 :           0 :       switch (TREE_CODE (type))
    3597                 :             :         {
    3598                 :           0 :         case RECORD_TYPE:
    3599                 :           0 :         case UNION_TYPE:
    3600                 :           0 :         case QUAL_UNION_TYPE:
    3601                 :           0 :           {
    3602                 :           0 :             tree field;
    3603                 :             : 
    3604                 :             :             /* Walk all the structure fields.  */
    3605                 :           0 :             for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    3606                 :             :               {
    3607                 :           0 :                 if (TREE_CODE (field) == FIELD_DECL
    3608                 :           0 :                     && ix86_compat_aligned_value_p (TREE_TYPE (field)))
    3609                 :             :                   return true;
    3610                 :             :               }
    3611                 :             :             break;
    3612                 :             :           }
    3613                 :             : 
    3614                 :           0 :         case ARRAY_TYPE:
    3615                 :             :           /* Just for use if some languages passes arrays by value.  */
    3616                 :           0 :           if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
    3617                 :             :             return true;
    3618                 :             :           break;
    3619                 :             : 
    3620                 :             :         default:
    3621                 :             :           gcc_unreachable ();
    3622                 :             :         }
    3623                 :             :     }
    3624                 :             :   return false;
    3625                 :             : }
    3626                 :             : 
    3627                 :             : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
    3628                 :             :    XXX: This function is obsolete and is only used for checking psABI
    3629                 :             :    compatibility with previous versions of GCC.  */
    3630                 :             : 
    3631                 :             : static unsigned int
    3632                 :     5405329 : ix86_compat_function_arg_boundary (machine_mode mode,
    3633                 :             :                                    const_tree type, unsigned int align)
    3634                 :             : {
    3635                 :             :   /* In 32bit, only _Decimal128 and __float128 are aligned to their
    3636                 :             :      natural boundaries.  */
    3637                 :     5405329 :   if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
    3638                 :             :     {
    3639                 :             :       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
    3640                 :             :          make an exception for SSE modes since these require 128bit
    3641                 :             :          alignment.
    3642                 :             : 
    3643                 :             :          The handling here differs from field_alignment.  ICC aligns MMX
    3644                 :             :          arguments to 4 byte boundaries, while structure fields are aligned
    3645                 :             :          to 8 byte boundaries.  */
    3646                 :     1947486 :       if (!type)
    3647                 :             :         {
    3648                 :       11865 :           if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
    3649                 :     1947274 :             align = PARM_BOUNDARY;
    3650                 :             :         }
    3651                 :             :       else
    3652                 :             :         {
    3653                 :     1935621 :           if (!ix86_compat_aligned_value_p (type))
    3654                 :     1935409 :             align = PARM_BOUNDARY;
    3655                 :             :         }
    3656                 :             :     }
    3657                 :    10405683 :   if (align > BIGGEST_ALIGNMENT)
    3658                 :          76 :     align = BIGGEST_ALIGNMENT;
    3659                 :     5405329 :   return align;
    3660                 :             : }
    3661                 :             : 
    3662                 :             : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3663                 :             :    passing ABI.  */
    3664                 :             : 
    3665                 :             : static bool
    3666                 :     1938257 : ix86_contains_aligned_value_p (const_tree type)
    3667                 :             : {
    3668                 :     1938257 :   machine_mode mode = TYPE_MODE (type);
    3669                 :             : 
    3670                 :     1938257 :   if (mode == XFmode || mode == XCmode)
    3671                 :             :     return false;
    3672                 :             : 
    3673                 :     1936165 :   if (TYPE_ALIGN (type) < 128)
    3674                 :             :     return false;
    3675                 :             : 
    3676                 :        2848 :   if (AGGREGATE_TYPE_P (type))
    3677                 :             :     {
    3678                 :             :       /* Walk the aggregates recursively.  */
    3679                 :           0 :       switch (TREE_CODE (type))
    3680                 :             :         {
    3681                 :           0 :         case RECORD_TYPE:
    3682                 :           0 :         case UNION_TYPE:
    3683                 :           0 :         case QUAL_UNION_TYPE:
    3684                 :           0 :           {
    3685                 :           0 :             tree field;
    3686                 :             : 
    3687                 :             :             /* Walk all the structure fields.  */
    3688                 :           0 :             for (field = TYPE_FIELDS (type);
    3689                 :           0 :                  field;
    3690                 :           0 :                  field = DECL_CHAIN (field))
    3691                 :             :               {
    3692                 :           0 :                 if (TREE_CODE (field) == FIELD_DECL
    3693                 :           0 :                     && ix86_contains_aligned_value_p (TREE_TYPE (field)))
    3694                 :             :                   return true;
    3695                 :             :               }
    3696                 :             :             break;
    3697                 :             :           }
    3698                 :             : 
    3699                 :           0 :         case ARRAY_TYPE:
    3700                 :             :           /* Just for use if some languages passes arrays by value.  */
    3701                 :           0 :           if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
    3702                 :             :             return true;
    3703                 :             :           break;
    3704                 :             : 
    3705                 :             :         default:
    3706                 :             :           gcc_unreachable ();
    3707                 :             :         }
    3708                 :             :     }
    3709                 :             :   else
    3710                 :        2848 :     return TYPE_ALIGN (type) >= 128;
    3711                 :             : 
    3712                 :             :   return false;
    3713                 :             : }
    3714                 :             : 
    3715                 :             : /* Gives the alignment boundary, in bits, of an argument with the
    3716                 :             :    specified mode and type.  */
    3717                 :             : 
    3718                 :             : static unsigned int
    3719                 :    10774548 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
    3720                 :             : {
    3721                 :    10774548 :   unsigned int align;
    3722                 :    10774548 :   if (type)
    3723                 :             :     {
    3724                 :             :       /* Since the main variant type is used for call, we convert it to
    3725                 :             :          the main variant type.  */
    3726                 :    10735058 :       type = TYPE_MAIN_VARIANT (type);
    3727                 :    10735058 :       align = TYPE_ALIGN (type);
    3728                 :    10735058 :       if (TYPE_EMPTY_P (type))
    3729                 :       22340 :         return PARM_BOUNDARY;
    3730                 :             :     }
    3731                 :             :   else
    3732                 :       39490 :     align = GET_MODE_ALIGNMENT (mode);
    3733                 :    12750468 :   if (align < PARM_BOUNDARY)
    3734                 :             :     align = PARM_BOUNDARY;
    3735                 :             :   else
    3736                 :             :     {
    3737                 :     6661427 :       static bool warned;
    3738                 :     6661427 :       unsigned int saved_align = align;
    3739                 :             : 
    3740                 :     6661427 :       if (!TARGET_64BIT)
    3741                 :             :         {
    3742                 :             :           /* i386 ABI defines XFmode arguments to be 4 byte aligned.  */
    3743                 :     1973854 :           if (!type)
    3744                 :             :             {
    3745                 :       35597 :               if (mode == XFmode || mode == XCmode)
    3746                 :             :                 align = PARM_BOUNDARY;
    3747                 :             :             }
    3748                 :     1938257 :           else if (!ix86_contains_aligned_value_p (type))
    3749                 :             :             align = PARM_BOUNDARY;
    3750                 :             : 
    3751                 :       38445 :           if (align < 128)
    3752                 :     1947274 :             align = PARM_BOUNDARY;
    3753                 :             :         }
    3754                 :             : 
    3755                 :     6661427 :       if (warn_psabi
    3756                 :     5407977 :           && !warned
    3757                 :    12066756 :           && align != ix86_compat_function_arg_boundary (mode, type,
    3758                 :             :                                                          saved_align))
    3759                 :             :         {
    3760                 :          76 :           warned = true;
    3761                 :          76 :           inform (input_location,
    3762                 :             :                   "the ABI for passing parameters with %d-byte"
    3763                 :             :                   " alignment has changed in GCC 4.6",
    3764                 :             :                   align / BITS_PER_UNIT);
    3765                 :             :         }
    3766                 :             :     }
    3767                 :             : 
    3768                 :             :   return align;
    3769                 :             : }
    3770                 :             : 
    3771                 :             : /* Return true if N is a possible register number of function value.  */
    3772                 :             : 
    3773                 :             : static bool
    3774                 :     4618091 : ix86_function_value_regno_p (const unsigned int regno)
    3775                 :             : {
    3776                 :     4618091 :   switch (regno)
    3777                 :             :     {
    3778                 :             :     case AX_REG:
    3779                 :             :       return true;
    3780                 :      100371 :     case DX_REG:
    3781                 :      100371 :       return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
    3782                 :       97954 :     case DI_REG:
    3783                 :       97954 :     case SI_REG:
    3784                 :       97954 :       return TARGET_64BIT && ix86_cfun_abi () != MS_ABI;
    3785                 :             : 
    3786                 :             :       /* Complex values are returned in %st(0)/%st(1) pair.  */
    3787                 :       21159 :     case ST0_REG:
    3788                 :       21159 :     case ST1_REG:
    3789                 :             :       /* TODO: The function should depend on current function ABI but
    3790                 :             :        builtins.cc would need updating then. Therefore we use the
    3791                 :             :        default ABI.  */
    3792                 :       21159 :       if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
    3793                 :             :         return false;
    3794                 :       21159 :       return TARGET_FLOAT_RETURNS_IN_80387;
    3795                 :             : 
    3796                 :             :       /* Complex values are returned in %xmm0/%xmm1 pair.  */
    3797                 :     1316907 :     case XMM0_REG:
    3798                 :     1316907 :     case XMM1_REG:
    3799                 :     1316907 :       return TARGET_SSE;
    3800                 :             : 
    3801                 :       11393 :     case MM0_REG:
    3802                 :       11393 :       if (TARGET_MACHO || TARGET_64BIT)
    3803                 :             :         return false;
    3804                 :        5429 :       return TARGET_MMX;
    3805                 :             :     }
    3806                 :             : 
    3807                 :             :   return false;
    3808                 :             : }
    3809                 :             : 
    3810                 :             : /* Check whether the register REGNO should be zeroed on X86.
    3811                 :             :    When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
    3812                 :             :    together, no need to zero it again.
    3813                 :             :    When NEED_ZERO_MMX is true, MMX registers should be cleared.  */
    3814                 :             : 
    3815                 :             : static bool
    3816                 :        1296 : zero_call_used_regno_p (const unsigned int regno,
    3817                 :             :                         bool all_sse_zeroed,
    3818                 :             :                         bool need_zero_mmx)
    3819                 :             : {
    3820                 :         763 :   return GENERAL_REGNO_P (regno)
    3821                 :         763 :          || (!all_sse_zeroed && SSE_REGNO_P (regno))
    3822                 :         383 :          || MASK_REGNO_P (regno)
    3823                 :        1671 :          || (need_zero_mmx && MMX_REGNO_P (regno));
    3824                 :             : }
    3825                 :             : 
    3826                 :             : /* Return the machine_mode that is used to zero register REGNO.  */
    3827                 :             : 
    3828                 :             : static machine_mode
    3829                 :         921 : zero_call_used_regno_mode (const unsigned int regno)
    3830                 :             : {
    3831                 :             :   /* NB: We only need to zero the lower 32 bits for integer registers
    3832                 :             :      and the lower 128 bits for vector registers since destination are
    3833                 :             :      zero-extended to the full register width.  */
    3834                 :         921 :   if (GENERAL_REGNO_P (regno))
    3835                 :             :     return SImode;
    3836                 :             :   else if (SSE_REGNO_P (regno))
    3837                 :         380 :     return V4SFmode;
    3838                 :             :   else if (MASK_REGNO_P (regno))
    3839                 :             :     return HImode;
    3840                 :             :   else if (MMX_REGNO_P (regno))
    3841                 :           0 :     return V2SImode;
    3842                 :             :   else
    3843                 :           0 :     gcc_unreachable ();
    3844                 :             : }
    3845                 :             : 
    3846                 :             : /* Generate a rtx to zero all vector registers together if possible,
    3847                 :             :    otherwise, return NULL.  */
    3848                 :             : 
    3849                 :             : static rtx
    3850                 :         130 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
    3851                 :             : {
    3852                 :         130 :   if (!TARGET_AVX)
    3853                 :             :     return NULL;
    3854                 :             : 
    3855                 :         279 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3856                 :         276 :     if ((LEGACY_SSE_REGNO_P (regno)
    3857                 :         252 :          || (TARGET_64BIT
    3858                 :         252 :              && (REX_SSE_REGNO_P (regno)
    3859                 :         228 :                  || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
    3860                 :         316 :         && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3861                 :             :       return NULL;
    3862                 :             : 
    3863                 :           3 :   return gen_avx_vzeroall ();
    3864                 :             : }
    3865                 :             : 
    3866                 :             : /* Generate insns to zero all st registers together.
    3867                 :             :    Return true when zeroing instructions are generated.
    3868                 :             :    Assume the number of st registers that are zeroed is num_of_st,
    3869                 :             :    we will emit the following sequence to zero them together:
    3870                 :             :                   fldz;         \
    3871                 :             :                   fldz;         \
    3872                 :             :                   ...
    3873                 :             :                   fldz;         \
    3874                 :             :                   fstp %%st(0); \
    3875                 :             :                   fstp %%st(0); \
    3876                 :             :                   ...
    3877                 :             :                   fstp %%st(0);
    3878                 :             :    i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
    3879                 :             :    mark stack slots empty.
    3880                 :             : 
    3881                 :             :    How to compute the num_of_st:
    3882                 :             :    There is no direct mapping from stack registers to hard register
    3883                 :             :    numbers.  If one stack register needs to be cleared, we don't know
    3884                 :             :    where in the stack the value remains.  So, if any stack register
    3885                 :             :    needs to be cleared, the whole stack should be cleared.  However,
    3886                 :             :    x87 stack registers that hold the return value should be excluded.
    3887                 :             :    x87 returns in the top (two for complex values) register, so
    3888                 :             :    num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
    3889                 :             :    return the value of num_of_st.  */
    3890                 :             : 
    3891                 :             : 
    3892                 :             : static int
    3893                 :         130 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
    3894                 :             : {
    3895                 :             : 
    3896                 :             :   /* If the FPU is disabled, no need to zero all st registers.  */
    3897                 :         130 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
    3898                 :             :     return 0;
    3899                 :             : 
    3900                 :       10320 :   unsigned int num_of_st = 0;
    3901                 :       10320 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3902                 :       10211 :     if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
    3903                 :       10211 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3904                 :             :       {
    3905                 :             :         num_of_st++;
    3906                 :             :         break;
    3907                 :             :       }
    3908                 :             : 
    3909                 :         129 :   if (num_of_st == 0)
    3910                 :             :     return 0;
    3911                 :             : 
    3912                 :          20 :   bool return_with_x87 = false;
    3913                 :          40 :   return_with_x87 = (crtl->return_rtx
    3914                 :          20 :                      && (STACK_REG_P (crtl->return_rtx)));
    3915                 :             : 
    3916                 :          20 :   bool complex_return = false;
    3917                 :          40 :   complex_return = (crtl->return_rtx
    3918                 :          20 :                     && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
    3919                 :             : 
    3920                 :          20 :   if (return_with_x87)
    3921                 :           2 :     if (complex_return)
    3922                 :             :       num_of_st = 6;
    3923                 :             :     else
    3924                 :           1 :       num_of_st = 7;
    3925                 :             :   else
    3926                 :             :     num_of_st = 8;
    3927                 :             : 
    3928                 :          20 :   rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
    3929                 :         177 :   for (unsigned int i = 0; i < num_of_st; i++)
    3930                 :         157 :     emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
    3931                 :             : 
    3932                 :         177 :   for (unsigned int i = 0; i < num_of_st; i++)
    3933                 :             :     {
    3934                 :         157 :       rtx insn;
    3935                 :         157 :       insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
    3936                 :         157 :       add_reg_note (insn, REG_DEAD, st_reg);
    3937                 :             :     }
    3938                 :          20 :   return num_of_st;
    3939                 :             : }
    3940                 :             : 
    3941                 :             : 
    3942                 :             : /* When the routine exit in MMX mode, if any ST register needs
    3943                 :             :    to be zeroed, we should clear all MMX registers except the
    3944                 :             :    RET_MMX_REGNO that holds the return value.  */
    3945                 :             : static bool
    3946                 :           0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
    3947                 :             :                        unsigned int ret_mmx_regno)
    3948                 :             : {
    3949                 :           0 :   bool need_zero_all_mm = false;
    3950                 :           0 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3951                 :           0 :     if (STACK_REGNO_P (regno)
    3952                 :           0 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3953                 :             :       {
    3954                 :             :         need_zero_all_mm = true;
    3955                 :             :         break;
    3956                 :             :       }
    3957                 :             : 
    3958                 :           0 :   if (!need_zero_all_mm)
    3959                 :             :     return false;
    3960                 :             : 
    3961                 :             :   machine_mode mode = V2SImode;
    3962                 :           0 :   for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    3963                 :           0 :     if (regno != ret_mmx_regno)
    3964                 :             :       {
    3965                 :           0 :         rtx reg = gen_rtx_REG (mode, regno);
    3966                 :           0 :         emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
    3967                 :             :       }
    3968                 :             :   return true;
    3969                 :             : }
    3970                 :             : 
    3971                 :             : /* TARGET_ZERO_CALL_USED_REGS.  */
    3972                 :             : /* Generate a sequence of instructions that zero registers specified by
    3973                 :             :    NEED_ZEROED_HARDREGS.  Return the ZEROED_HARDREGS that are actually
    3974                 :             :    zeroed.  */
    3975                 :             : static HARD_REG_SET
    3976                 :         130 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
    3977                 :             : {
    3978                 :         130 :   HARD_REG_SET zeroed_hardregs;
    3979                 :         130 :   bool all_sse_zeroed = false;
    3980                 :         130 :   int all_st_zeroed_num = 0;
    3981                 :         130 :   bool all_mm_zeroed = false;
    3982                 :             : 
    3983                 :         130 :   CLEAR_HARD_REG_SET (zeroed_hardregs);
    3984                 :             : 
    3985                 :             :   /* first, let's see whether we can zero all vector registers together.  */
    3986                 :         130 :   rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
    3987                 :         130 :   if (zero_all_vec_insn)
    3988                 :             :     {
    3989                 :           3 :       emit_insn (zero_all_vec_insn);
    3990                 :           3 :       all_sse_zeroed = true;
    3991                 :             :     }
    3992                 :             : 
    3993                 :             :   /* mm/st registers are shared registers set, we should follow the following
    3994                 :             :      rules to clear them:
    3995                 :             :                         MMX exit mode         x87 exit mode
    3996                 :             :         -------------|----------------------|---------------
    3997                 :             :         uses x87 reg | clear all MMX        | clear all x87
    3998                 :             :         uses MMX reg | clear individual MMX | clear all x87
    3999                 :             :         x87 + MMX    | clear all MMX        | clear all x87
    4000                 :             : 
    4001                 :             :      first, we should decide which mode (MMX mode or x87 mode) the function
    4002                 :             :      exit with.  */
    4003                 :             : 
    4004                 :         130 :   bool exit_with_mmx_mode = (crtl->return_rtx
    4005                 :         130 :                              && (MMX_REG_P (crtl->return_rtx)));
    4006                 :             : 
    4007                 :         130 :   if (!exit_with_mmx_mode)
    4008                 :             :     /* x87 exit mode, we should zero all st registers together.  */
    4009                 :             :     {
    4010                 :         130 :       all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
    4011                 :             : 
    4012                 :         130 :       if (all_st_zeroed_num > 0)
    4013                 :         180 :         for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
    4014                 :             :           /* x87 stack registers that hold the return value should be excluded.
    4015                 :             :              x87 returns in the top (two for complex values) register.  */
    4016                 :         160 :           if (all_st_zeroed_num == 8
    4017                 :         160 :               || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
    4018                 :             :                    || (all_st_zeroed_num == 6
    4019                 :           7 :                        && (regno == (REGNO (crtl->return_rtx) + 1)))))
    4020                 :         157 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4021                 :             :     }
    4022                 :             :   else
    4023                 :             :     /* MMX exit mode, check whether we can zero all mm registers.  */
    4024                 :             :     {
    4025                 :           0 :       unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
    4026                 :           0 :       all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
    4027                 :             :                                              exit_mmx_regno);
    4028                 :           0 :       if (all_mm_zeroed)
    4029                 :           0 :         for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4030                 :           0 :           if (regno != exit_mmx_regno)
    4031                 :           0 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4032                 :             :     }
    4033                 :             : 
    4034                 :             :   /* Now, generate instructions to zero all the other registers.  */
    4035                 :             : 
    4036                 :       12090 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4037                 :             :     {
    4038                 :       11960 :       if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4039                 :       10664 :         continue;
    4040                 :        1671 :       if (!zero_call_used_regno_p (regno, all_sse_zeroed,
    4041                 :        1296 :                                    exit_with_mmx_mode && !all_mm_zeroed))
    4042                 :         375 :         continue;
    4043                 :             : 
    4044                 :         921 :       SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4045                 :             : 
    4046                 :         921 :       machine_mode mode = zero_call_used_regno_mode (regno);
    4047                 :             : 
    4048                 :         921 :       rtx reg = gen_rtx_REG (mode, regno);
    4049                 :         921 :       rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
    4050                 :             : 
    4051                 :         921 :       switch (mode)
    4052                 :             :         {
    4053                 :         533 :         case E_SImode:
    4054                 :         533 :           if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
    4055                 :             :             {
    4056                 :         533 :               rtx clob = gen_rtx_CLOBBER (VOIDmode,
    4057                 :             :                                           gen_rtx_REG (CCmode,
    4058                 :             :                                                        FLAGS_REG));
    4059                 :         533 :               tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
    4060                 :             :                                                            tmp,
    4061                 :             :                                                            clob));
    4062                 :             :             }
    4063                 :             :           /* FALLTHRU.  */
    4064                 :             : 
    4065                 :         921 :         case E_V4SFmode:
    4066                 :         921 :         case E_HImode:
    4067                 :         921 :         case E_V2SImode:
    4068                 :         921 :           emit_insn (tmp);
    4069                 :         921 :           break;
    4070                 :             : 
    4071                 :           0 :         default:
    4072                 :           0 :           gcc_unreachable ();
    4073                 :             :         }
    4074                 :             :     }
    4075                 :         130 :   return zeroed_hardregs;
    4076                 :             : }
    4077                 :             : 
    4078                 :             : /* Define how to find the value returned by a function.
    4079                 :             :    VALTYPE is the data type of the value (as a tree).
    4080                 :             :    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    4081                 :             :    otherwise, FUNC is 0.  */
    4082                 :             : 
    4083                 :             : static rtx
    4084                 :     3875445 : function_value_32 (machine_mode orig_mode, machine_mode mode,
    4085                 :             :                    const_tree fntype, const_tree fn)
    4086                 :             : {
    4087                 :     3875445 :   unsigned int regno;
    4088                 :             : 
    4089                 :             :   /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
    4090                 :             :      we normally prevent this case when mmx is not available.  However
    4091                 :             :      some ABIs may require the result to be returned like DImode.  */
    4092                 :     4156606 :   if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
    4093                 :             :     regno = FIRST_MMX_REG;
    4094                 :             : 
    4095                 :             :   /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
    4096                 :             :      we prevent this case when sse is not available.  However some ABIs
    4097                 :             :      may require the result to be returned like integer TImode.  */
    4098                 :     3866205 :   else if (mode == TImode
    4099                 :     4138126 :            || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
    4100                 :             :     regno = FIRST_SSE_REG;
    4101                 :             : 
    4102                 :             :   /* 32-byte vector modes in %ymm0.   */
    4103                 :     3917060 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
    4104                 :             :     regno = FIRST_SSE_REG;
    4105                 :             : 
    4106                 :             :   /* 64-byte vector modes in %zmm0.   */
    4107                 :     3745670 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
    4108                 :             :     regno = FIRST_SSE_REG;
    4109                 :             : 
    4110                 :             :   /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387).  */
    4111                 :     3594284 :   else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
    4112                 :             :     regno = FIRST_FLOAT_REG;
    4113                 :             :   else
    4114                 :             :     /* Most things go in %eax.  */
    4115                 :     3532479 :     regno = AX_REG;
    4116                 :             : 
    4117                 :             :   /* Return __bf16/ _Float16/_Complex _Foat16 by sse register.  */
    4118                 :     3875445 :   if (mode == HFmode || mode == BFmode)
    4119                 :             :     {
    4120                 :        1613 :       if (!TARGET_SSE2)
    4121                 :             :         {
    4122                 :           0 :           error ("SSE register return with SSE2 disabled");
    4123                 :           0 :           regno = AX_REG;
    4124                 :             :         }
    4125                 :             :       else
    4126                 :             :         regno = FIRST_SSE_REG;
    4127                 :             :     }
    4128                 :             : 
    4129                 :     3875445 :   if (mode == HCmode)
    4130                 :             :     {
    4131                 :          80 :       if (!TARGET_SSE2)
    4132                 :           0 :         error ("SSE register return with SSE2 disabled");
    4133                 :             : 
    4134                 :          80 :       rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
    4135                 :         160 :       XVECEXP (ret, 0, 0)
    4136                 :         160 :         = gen_rtx_EXPR_LIST (VOIDmode,
    4137                 :             :                              gen_rtx_REG (SImode,
    4138                 :          80 :                                           TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
    4139                 :             :                              GEN_INT (0));
    4140                 :          80 :       return ret;
    4141                 :             :     }
    4142                 :             : 
    4143                 :             :   /* Override FP return register with %xmm0 for local functions when
    4144                 :             :      SSE math is enabled or for functions with sseregparm attribute.  */
    4145                 :     3875365 :   if ((fn || fntype) && (mode == SFmode || mode == DFmode))
    4146                 :             :     {
    4147                 :       48212 :       int sse_level = ix86_function_sseregparm (fntype, fn, false);
    4148                 :       48212 :       if (sse_level == -1)
    4149                 :             :         {
    4150                 :           0 :           error ("calling %qD with SSE calling convention without "
    4151                 :             :                  "SSE/SSE2 enabled", fn);
    4152                 :           0 :           sorry ("this is a GCC bug that can be worked around by adding "
    4153                 :             :                  "attribute used to function called");
    4154                 :             :         }
    4155                 :       48212 :       else if ((sse_level >= 1 && mode == SFmode)
    4156                 :       48212 :                || (sse_level == 2 && mode == DFmode))
    4157                 :             :         regno = FIRST_SSE_REG;
    4158                 :             :     }
    4159                 :             : 
    4160                 :             :   /* OImode shouldn't be used directly.  */
    4161                 :     3875365 :   gcc_assert (mode != OImode);
    4162                 :             : 
    4163                 :     3875365 :   return gen_rtx_REG (orig_mode, regno);
    4164                 :             : }
    4165                 :             : 
    4166                 :             : static rtx
    4167                 :    89490468 : function_value_64 (machine_mode orig_mode, machine_mode mode,
    4168                 :             :                    const_tree valtype)
    4169                 :             : {
    4170                 :    89490468 :   rtx ret;
    4171                 :             : 
    4172                 :             :   /* Handle libcalls, which don't provide a type node.  */
    4173                 :    89490468 :   if (valtype == NULL)
    4174                 :             :     {
    4175                 :      103764 :       unsigned int regno;
    4176                 :             : 
    4177                 :      103764 :       switch (mode)
    4178                 :             :         {
    4179                 :             :         case E_BFmode:
    4180                 :             :         case E_HFmode:
    4181                 :             :         case E_HCmode:
    4182                 :             :         case E_SFmode:
    4183                 :             :         case E_SCmode:
    4184                 :             :         case E_DFmode:
    4185                 :             :         case E_DCmode:
    4186                 :             :         case E_TFmode:
    4187                 :             :         case E_SDmode:
    4188                 :             :         case E_DDmode:
    4189                 :             :         case E_TDmode:
    4190                 :             :           regno = FIRST_SSE_REG;
    4191                 :             :           break;
    4192                 :        1035 :         case E_XFmode:
    4193                 :        1035 :         case E_XCmode:
    4194                 :        1035 :           regno = FIRST_FLOAT_REG;
    4195                 :        1035 :           break;
    4196                 :             :         case E_TCmode:
    4197                 :             :           return NULL;
    4198                 :       56024 :         default:
    4199                 :       56024 :           regno = AX_REG;
    4200                 :             :         }
    4201                 :             : 
    4202                 :      103764 :       return gen_rtx_REG (mode, regno);
    4203                 :             :     }
    4204                 :    89386704 :   else if (POINTER_TYPE_P (valtype))
    4205                 :             :     {
    4206                 :             :       /* Pointers are always returned in word_mode.  */
    4207                 :    13445062 :       mode = word_mode;
    4208                 :             :     }
    4209                 :             : 
    4210                 :    89386704 :   ret = construct_container (mode, orig_mode, valtype, 1,
    4211                 :             :                              X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
    4212                 :             :                              x86_64_int_return_registers, 0);
    4213                 :             : 
    4214                 :             :   /* For zero sized structures, construct_container returns NULL, but we
    4215                 :             :      need to keep rest of compiler happy by returning meaningful value.  */
    4216                 :    89386704 :   if (!ret)
    4217                 :      189364 :     ret = gen_rtx_REG (orig_mode, AX_REG);
    4218                 :             : 
    4219                 :             :   return ret;
    4220                 :             : }
    4221                 :             : 
    4222                 :             : static rtx
    4223                 :           0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
    4224                 :             :                       const_tree fntype, const_tree fn, const_tree valtype)
    4225                 :             : {
    4226                 :           0 :   unsigned int regno;
    4227                 :             : 
    4228                 :             :   /* Floating point return values in %st(0)
    4229                 :             :      (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes).  */
    4230                 :           0 :   if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
    4231                 :           0 :            && (GET_MODE_SIZE (mode) > 8
    4232                 :           0 :                || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
    4233                 :             :   {
    4234                 :           0 :     regno = FIRST_FLOAT_REG;
    4235                 :           0 :     return gen_rtx_REG (orig_mode, regno);
    4236                 :             :   }
    4237                 :             :   else
    4238                 :           0 :     return function_value_32(orig_mode, mode, fntype,fn);
    4239                 :             : }
    4240                 :             : 
    4241                 :             : static rtx
    4242                 :      762831 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
    4243                 :             :                       const_tree valtype)
    4244                 :             : {
    4245                 :      762831 :   unsigned int regno = AX_REG;
    4246                 :             : 
    4247                 :      762831 :   if (TARGET_SSE)
    4248                 :             :     {
    4249                 :     1524208 :       switch (GET_MODE_SIZE (mode))
    4250                 :             :         {
    4251                 :       14219 :         case 16:
    4252                 :       14219 :           if (valtype != NULL_TREE
    4253                 :       14219 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4254                 :        7308 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4255                 :        7308 :               && !INTEGRAL_TYPE_P (valtype)
    4256                 :       21527 :               && !VECTOR_FLOAT_TYPE_P (valtype))
    4257                 :             :             break;
    4258                 :       14219 :           if ((SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
    4259                 :             :               && !COMPLEX_MODE_P (mode))
    4260                 :      197831 :             regno = FIRST_SSE_REG;
    4261                 :             :           break;
    4262                 :      728161 :         case 8:
    4263                 :      728161 :         case 4:
    4264                 :      728161 :           if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
    4265                 :             :             break;
    4266                 :      713387 :           if (mode == SFmode || mode == DFmode)
    4267                 :      197831 :             regno = FIRST_SSE_REG;
    4268                 :             :           break;
    4269                 :             :         default:
    4270                 :             :           break;
    4271                 :             :         }
    4272                 :             :     }
    4273                 :      762831 :   return gen_rtx_REG (orig_mode, regno);
    4274                 :             : }
    4275                 :             : 
    4276                 :             : static rtx
    4277                 :    94128744 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
    4278                 :             :                        machine_mode orig_mode, machine_mode mode)
    4279                 :             : {
    4280                 :    94128744 :   const_tree fn, fntype;
    4281                 :             : 
    4282                 :    94128744 :   fn = NULL_TREE;
    4283                 :    94128744 :   if (fntype_or_decl && DECL_P (fntype_or_decl))
    4284                 :     3400814 :     fn = fntype_or_decl;
    4285                 :     3400814 :   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
    4286                 :             : 
    4287                 :    94128744 :   if (ix86_function_type_abi (fntype) == MS_ABI)
    4288                 :             :     {
    4289                 :      762831 :       if (TARGET_64BIT)
    4290                 :      762831 :         return function_value_ms_64 (orig_mode, mode, valtype);
    4291                 :             :       else
    4292                 :           0 :         return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
    4293                 :             :     }
    4294                 :    93365913 :   else if (TARGET_64BIT)
    4295                 :    89490468 :     return function_value_64 (orig_mode, mode, valtype);
    4296                 :             :   else
    4297                 :     3875445 :     return function_value_32 (orig_mode, mode, fntype, fn);
    4298                 :             : }
    4299                 :             : 
    4300                 :             : static rtx
    4301                 :    94021896 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
    4302                 :             : {
    4303                 :    94021896 :   machine_mode mode, orig_mode;
    4304                 :             : 
    4305                 :    94021896 :   orig_mode = TYPE_MODE (valtype);
    4306                 :    94021896 :   mode = type_natural_mode (valtype, NULL, true);
    4307                 :    94021896 :   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
    4308                 :             : }
    4309                 :             : 
    4310                 :             : /* Pointer function arguments and return values are promoted to
    4311                 :             :    word_mode for normal functions.  */
    4312                 :             : 
    4313                 :             : static machine_mode
    4314                 :    30937162 : ix86_promote_function_mode (const_tree type, machine_mode mode,
    4315                 :             :                             int *punsignedp, const_tree fntype,
    4316                 :             :                             int for_return)
    4317                 :             : {
    4318                 :    30937162 :   if (cfun->machine->func_type == TYPE_NORMAL
    4319                 :    30936170 :       && type != NULL_TREE
    4320                 :    30903226 :       && POINTER_TYPE_P (type))
    4321                 :             :     {
    4322                 :    15314469 :       *punsignedp = POINTERS_EXTEND_UNSIGNED;
    4323                 :    15314469 :       return word_mode;
    4324                 :             :     }
    4325                 :    15622693 :   return default_promote_function_mode (type, mode, punsignedp, fntype,
    4326                 :    15622693 :                                         for_return);
    4327                 :             : }
    4328                 :             : 
    4329                 :             : /* Return true if a structure, union or array with MODE containing FIELD
    4330                 :             :    should be accessed using BLKmode.  */
    4331                 :             : 
    4332                 :             : static bool
    4333                 :   117149551 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
    4334                 :             : {
    4335                 :             :   /* Union with XFmode must be in BLKmode.  */
    4336                 :   117149551 :   return (mode == XFmode
    4337                 :   117282101 :           && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
    4338                 :      120368 :               || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
    4339                 :             : }
    4340                 :             : 
    4341                 :             : rtx
    4342                 :      106848 : ix86_libcall_value (machine_mode mode)
    4343                 :             : {
    4344                 :      106848 :   return ix86_function_value_1 (NULL, NULL, mode, mode);
    4345                 :             : }
    4346                 :             : 
    4347                 :             : /* Return true iff type is returned in memory.  */
    4348                 :             : 
    4349                 :             : static bool
    4350                 :    95129056 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
    4351                 :             : {
    4352                 :    95129056 :   const machine_mode mode = type_natural_mode (type, NULL, true);
    4353                 :    95129056 :   HOST_WIDE_INT size;
    4354                 :             : 
    4355                 :    95129056 :   if (TARGET_64BIT)
    4356                 :             :     {
    4357                 :    90666433 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    4358                 :             :         {
    4359                 :      704097 :           size = int_size_in_bytes (type);
    4360                 :             : 
    4361                 :             :           /* __m128 is returned in xmm0.  */
    4362                 :      704097 :           if ((!type || VECTOR_INTEGER_TYPE_P (type)
    4363                 :      684388 :                || INTEGRAL_TYPE_P (type)
    4364                 :      218638 :                || VECTOR_FLOAT_TYPE_P (type))
    4365                 :      502937 :               && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
    4366                 :             :               && !COMPLEX_MODE_P (mode)
    4367                 :     1207034 :               && (GET_MODE_SIZE (mode) == 16 || size == 16))
    4368                 :             :             return false;
    4369                 :             : 
    4370                 :             :           /* Otherwise, the size must be exactly in [1248]. */
    4371                 :     1341821 :           return size != 1 && size != 2 && size != 4 && size != 8;
    4372                 :             :         }
    4373                 :             :       else
    4374                 :             :         {
    4375                 :    89962336 :           int needed_intregs, needed_sseregs;
    4376                 :             : 
    4377                 :    89962336 :           return examine_argument (mode, type, 1,
    4378                 :             :                                    &needed_intregs, &needed_sseregs);
    4379                 :             :         }
    4380                 :             :     }
    4381                 :             :   else
    4382                 :             :     {
    4383                 :     4462623 :       size = int_size_in_bytes (type);
    4384                 :             : 
    4385                 :             :       /* Intel MCU psABI returns scalars and aggregates no larger than 8
    4386                 :             :          bytes in registers.  */
    4387                 :     4462623 :       if (TARGET_IAMCU)
    4388                 :           0 :         return VECTOR_MODE_P (mode) || size < 0 || size > 8;
    4389                 :             : 
    4390                 :     4462623 :       if (mode == BLKmode)
    4391                 :             :         return true;
    4392                 :             : 
    4393                 :     4462623 :       if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
    4394                 :             :         return false;
    4395                 :             : 
    4396                 :     4462623 :       if (VECTOR_MODE_P (mode) || mode == TImode)
    4397                 :             :         {
    4398                 :             :           /* User-created vectors small enough to fit in EAX.  */
    4399                 :      281133 :           if (size < 8)
    4400                 :             :             return false;
    4401                 :             : 
    4402                 :             :           /* Unless ABI prescibes otherwise,
    4403                 :             :              MMX/3dNow values are returned in MM0 if available.  */
    4404                 :             : 
    4405                 :      281133 :           if (size == 8)
    4406                 :        9232 :             return TARGET_VECT8_RETURNS || !TARGET_MMX;
    4407                 :             : 
    4408                 :             :           /* SSE values are returned in XMM0 if available.  */
    4409                 :      271901 :           if (size == 16)
    4410                 :      110523 :             return !TARGET_SSE;
    4411                 :             : 
    4412                 :             :           /* AVX values are returned in YMM0 if available.  */
    4413                 :      161378 :           if (size == 32)
    4414                 :       85686 :             return !TARGET_AVX;
    4415                 :             : 
    4416                 :             :           /* AVX512F values are returned in ZMM0 if available.  */
    4417                 :       75692 :           if (size == 64)
    4418                 :       75692 :             return !TARGET_AVX512F || !TARGET_EVEX512;
    4419                 :             :         }
    4420                 :             : 
    4421                 :     4181490 :       if (mode == XFmode)
    4422                 :             :         return false;
    4423                 :             : 
    4424                 :     4170363 :       if (size > 12)
    4425                 :             :         return true;
    4426                 :             : 
    4427                 :             :       /* OImode shouldn't be used directly.  */
    4428                 :     3215691 :       gcc_assert (mode != OImode);
    4429                 :             : 
    4430                 :             :       return false;
    4431                 :             :     }
    4432                 :             : }
    4433                 :             : 
    4434                 :             : /* Implement TARGET_PUSH_ARGUMENT.  */
    4435                 :             : 
    4436                 :             : static bool
    4437                 :     9008399 : ix86_push_argument (unsigned int npush)
    4438                 :             : {
    4439                 :             :   /* If SSE2 is available, use vector move to put large argument onto
    4440                 :             :      stack.  NB:  In 32-bit mode, use 8-byte vector move.  */
    4441                 :    11402867 :   return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
    4442                 :     8746020 :           && TARGET_PUSH_ARGS
    4443                 :    17754321 :           && !ACCUMULATE_OUTGOING_ARGS);
    4444                 :             : }
    4445                 :             : 
    4446                 :             : 
    4447                 :             : /* Create the va_list data type.  */
    4448                 :             : 
    4449                 :             : static tree
    4450                 :      275609 : ix86_build_builtin_va_list_64 (void)
    4451                 :             : {
    4452                 :      275609 :   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
    4453                 :             : 
    4454                 :      275609 :   record = lang_hooks.types.make_type (RECORD_TYPE);
    4455                 :      275609 :   type_decl = build_decl (BUILTINS_LOCATION,
    4456                 :             :                           TYPE_DECL, get_identifier ("__va_list_tag"), record);
    4457                 :             : 
    4458                 :      275609 :   f_gpr = build_decl (BUILTINS_LOCATION,
    4459                 :             :                       FIELD_DECL, get_identifier ("gp_offset"),
    4460                 :             :                       unsigned_type_node);
    4461                 :      275609 :   f_fpr = build_decl (BUILTINS_LOCATION,
    4462                 :             :                       FIELD_DECL, get_identifier ("fp_offset"),
    4463                 :             :                       unsigned_type_node);
    4464                 :      275609 :   f_ovf = build_decl (BUILTINS_LOCATION,
    4465                 :             :                       FIELD_DECL, get_identifier ("overflow_arg_area"),
    4466                 :             :                       ptr_type_node);
    4467                 :      275609 :   f_sav = build_decl (BUILTINS_LOCATION,
    4468                 :             :                       FIELD_DECL, get_identifier ("reg_save_area"),
    4469                 :             :                       ptr_type_node);
    4470                 :             : 
    4471                 :      275609 :   va_list_gpr_counter_field = f_gpr;
    4472                 :      275609 :   va_list_fpr_counter_field = f_fpr;
    4473                 :             : 
    4474                 :      275609 :   DECL_FIELD_CONTEXT (f_gpr) = record;
    4475                 :      275609 :   DECL_FIELD_CONTEXT (f_fpr) = record;
    4476                 :      275609 :   DECL_FIELD_CONTEXT (f_ovf) = record;
    4477                 :      275609 :   DECL_FIELD_CONTEXT (f_sav) = record;
    4478                 :             : 
    4479                 :      275609 :   TYPE_STUB_DECL (record) = type_decl;
    4480                 :      275609 :   TYPE_NAME (record) = type_decl;
    4481                 :      275609 :   TYPE_FIELDS (record) = f_gpr;
    4482                 :      275609 :   DECL_CHAIN (f_gpr) = f_fpr;
    4483                 :      275609 :   DECL_CHAIN (f_fpr) = f_ovf;
    4484                 :      275609 :   DECL_CHAIN (f_ovf) = f_sav;
    4485                 :             : 
    4486                 :      275609 :   layout_type (record);
    4487                 :             : 
    4488                 :      275609 :   TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
    4489                 :      275609 :                                         NULL_TREE, TYPE_ATTRIBUTES (record));
    4490                 :             : 
    4491                 :             :   /* The correct type is an array type of one element.  */
    4492                 :      275609 :   return build_array_type (record, build_index_type (size_zero_node));
    4493                 :             : }
    4494                 :             : 
    4495                 :             : /* Setup the builtin va_list data type and for 64-bit the additional
    4496                 :             :    calling convention specific va_list data types.  */
    4497                 :             : 
    4498                 :             : static tree
    4499                 :      282654 : ix86_build_builtin_va_list (void)
    4500                 :             : {
    4501                 :      282654 :   if (TARGET_64BIT)
    4502                 :             :     {
    4503                 :             :       /* Initialize ABI specific va_list builtin types.
    4504                 :             : 
    4505                 :             :          In lto1, we can encounter two va_list types:
    4506                 :             :          - one as a result of the type-merge across TUs, and
    4507                 :             :          - the one constructed here.
    4508                 :             :          These two types will not have the same TYPE_MAIN_VARIANT, and therefore
    4509                 :             :          a type identity check in canonical_va_list_type based on
    4510                 :             :          TYPE_MAIN_VARIANT (which we used to have) will not work.
    4511                 :             :          Instead, we tag each va_list_type_node with its unique attribute, and
    4512                 :             :          look for the attribute in the type identity check in
    4513                 :             :          canonical_va_list_type.
    4514                 :             : 
    4515                 :             :          Tagging sysv_va_list_type_node directly with the attribute is
    4516                 :             :          problematic since it's a array of one record, which will degrade into a
    4517                 :             :          pointer to record when used as parameter (see build_va_arg comments for
    4518                 :             :          an example), dropping the attribute in the process.  So we tag the
    4519                 :             :          record instead.  */
    4520                 :             : 
    4521                 :             :       /* For SYSV_ABI we use an array of one record.  */
    4522                 :      275609 :       sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
    4523                 :             : 
    4524                 :             :       /* For MS_ABI we use plain pointer to argument area.  */
    4525                 :      275609 :       tree char_ptr_type = build_pointer_type (char_type_node);
    4526                 :      275609 :       tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
    4527                 :      275609 :                              TYPE_ATTRIBUTES (char_ptr_type));
    4528                 :      275609 :       ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
    4529                 :             : 
    4530                 :      275609 :       return ((ix86_abi == MS_ABI)
    4531                 :      275609 :               ? ms_va_list_type_node
    4532                 :      275609 :               : sysv_va_list_type_node);
    4533                 :             :     }
    4534                 :             :   else
    4535                 :             :     {
    4536                 :             :       /* For i386 we use plain pointer to argument area.  */
    4537                 :        7045 :       return build_pointer_type (char_type_node);
    4538                 :             :     }
    4539                 :             : }
    4540                 :             : 
    4541                 :             : /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
    4542                 :             : 
    4543                 :             : static void
    4544                 :       15430 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
    4545                 :             : {
    4546                 :       15430 :   rtx save_area, mem;
    4547                 :       15430 :   alias_set_type set;
    4548                 :       15430 :   int i, max;
    4549                 :             : 
    4550                 :             :   /* GPR size of varargs save area.  */
    4551                 :       15430 :   if (cfun->va_list_gpr_size)
    4552                 :       15013 :     ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
    4553                 :             :   else
    4554                 :         417 :     ix86_varargs_gpr_size = 0;
    4555                 :             : 
    4556                 :             :   /* FPR size of varargs save area.  We don't need it if we don't pass
    4557                 :             :      anything in SSE registers.  */
    4558                 :       15430 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4559                 :       14471 :     ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
    4560                 :             :   else
    4561                 :         959 :     ix86_varargs_fpr_size = 0;
    4562                 :             : 
    4563                 :       15430 :   if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
    4564                 :             :     return;
    4565                 :             : 
    4566                 :       15178 :   save_area = frame_pointer_rtx;
    4567                 :       15178 :   set = get_varargs_alias_set ();
    4568                 :             : 
    4569                 :       15178 :   max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
    4570                 :       15178 :   if (max > X86_64_REGPARM_MAX)
    4571                 :             :     max = X86_64_REGPARM_MAX;
    4572                 :             : 
    4573                 :       84563 :   for (i = cum->regno; i < max; i++)
    4574                 :             :     {
    4575                 :       69385 :       mem = gen_rtx_MEM (word_mode,
    4576                 :       69385 :                          plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
    4577                 :       69385 :       MEM_NOTRAP_P (mem) = 1;
    4578                 :       69385 :       set_mem_alias_set (mem, set);
    4579                 :       69385 :       emit_move_insn (mem,
    4580                 :             :                       gen_rtx_REG (word_mode,
    4581                 :       69385 :                                    x86_64_int_parameter_registers[i]));
    4582                 :             :     }
    4583                 :             : 
    4584                 :       15178 :   if (ix86_varargs_fpr_size)
    4585                 :             :     {
    4586                 :       14471 :       machine_mode smode;
    4587                 :       14471 :       rtx_code_label *label;
    4588                 :       14471 :       rtx test;
    4589                 :             : 
    4590                 :             :       /* Now emit code to save SSE registers.  The AX parameter contains number
    4591                 :             :          of SSE parameter registers used to call this function, though all we
    4592                 :             :          actually check here is the zero/non-zero status.  */
    4593                 :             : 
    4594                 :       14471 :       label = gen_label_rtx ();
    4595                 :       14471 :       test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
    4596                 :       14471 :       emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
    4597                 :             :                                       label));
    4598                 :             : 
    4599                 :             :       /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
    4600                 :             :          we used movdqa (i.e. TImode) instead?  Perhaps even better would
    4601                 :             :          be if we could determine the real mode of the data, via a hook
    4602                 :             :          into pass_stdarg.  Ignore all that for now.  */
    4603                 :       14471 :       smode = V4SFmode;
    4604                 :       14471 :       if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
    4605                 :        3982 :         crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
    4606                 :             : 
    4607                 :       14471 :       max = cum->sse_regno + cfun->va_list_fpr_size / 16;
    4608                 :       14471 :       if (max > X86_64_SSE_REGPARM_MAX)
    4609                 :             :         max = X86_64_SSE_REGPARM_MAX;
    4610                 :             : 
    4611                 :      128705 :       for (i = cum->sse_regno; i < max; ++i)
    4612                 :             :         {
    4613                 :      114234 :           mem = plus_constant (Pmode, save_area,
    4614                 :      114234 :                                i * 16 + ix86_varargs_gpr_size);
    4615                 :      114234 :           mem = gen_rtx_MEM (smode, mem);
    4616                 :      114234 :           MEM_NOTRAP_P (mem) = 1;
    4617                 :      114234 :           set_mem_alias_set (mem, set);
    4618                 :      114234 :           set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
    4619                 :             : 
    4620                 :      114234 :           emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
    4621                 :             :         }
    4622                 :             : 
    4623                 :       14471 :       emit_label (label);
    4624                 :             :     }
    4625                 :             : }
    4626                 :             : 
    4627                 :             : static void
    4628                 :        5652 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
    4629                 :             : {
    4630                 :        5652 :   alias_set_type set = get_varargs_alias_set ();
    4631                 :        5652 :   int i;
    4632                 :             : 
    4633                 :             :   /* Reset to zero, as there might be a sysv vaarg used
    4634                 :             :      before.  */
    4635                 :        5652 :   ix86_varargs_gpr_size = 0;
    4636                 :        5652 :   ix86_varargs_fpr_size = 0;
    4637                 :             : 
    4638                 :       14154 :   for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
    4639                 :             :     {
    4640                 :        8502 :       rtx reg, mem;
    4641                 :             : 
    4642                 :        8502 :       mem = gen_rtx_MEM (Pmode,
    4643                 :        8502 :                          plus_constant (Pmode, virtual_incoming_args_rtx,
    4644                 :        8502 :                                         i * UNITS_PER_WORD));
    4645                 :        8502 :       MEM_NOTRAP_P (mem) = 1;
    4646                 :        8502 :       set_mem_alias_set (mem, set);
    4647                 :             : 
    4648                 :        8502 :       reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
    4649                 :        8502 :       emit_move_insn (mem, reg);
    4650                 :             :     }
    4651                 :        5652 : }
    4652                 :             : 
    4653                 :             : static void
    4654                 :       21228 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
    4655                 :             :                              const function_arg_info &arg,
    4656                 :             :                              int *, int no_rtl)
    4657                 :             : {
    4658                 :       21228 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    4659                 :       21228 :   CUMULATIVE_ARGS next_cum;
    4660                 :       21228 :   tree fntype;
    4661                 :             : 
    4662                 :             :   /* This argument doesn't appear to be used anymore.  Which is good,
    4663                 :             :      because the old code here didn't suppress rtl generation.  */
    4664                 :       21228 :   gcc_assert (!no_rtl);
    4665                 :             : 
    4666                 :       21228 :   if (!TARGET_64BIT)
    4667                 :         146 :     return;
    4668                 :             : 
    4669                 :       21082 :   fntype = TREE_TYPE (current_function_decl);
    4670                 :             : 
    4671                 :             :   /* For varargs, we do not want to skip the dummy va_dcl argument.
    4672                 :             :      For stdargs, we do want to skip the last named argument.  */
    4673                 :       21082 :   next_cum = *cum;
    4674                 :       21082 :   if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
    4675                 :          77 :        || arg.type != NULL_TREE)
    4676                 :       21094 :       && stdarg_p (fntype))
    4677                 :       21017 :     ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
    4678                 :             : 
    4679                 :       21082 :   if (cum->call_abi == MS_ABI)
    4680                 :        5652 :     setup_incoming_varargs_ms_64 (&next_cum);
    4681                 :             :   else
    4682                 :       15430 :     setup_incoming_varargs_64 (&next_cum);
    4683                 :             : }
    4684                 :             : 
    4685                 :             : /* Checks if TYPE is of kind va_list char *.  */
    4686                 :             : 
    4687                 :             : static bool
    4688                 :       72476 : is_va_list_char_pointer (tree type)
    4689                 :             : {
    4690                 :       72476 :   tree canonic;
    4691                 :             : 
    4692                 :             :   /* For 32-bit it is always true.  */
    4693                 :       72476 :   if (!TARGET_64BIT)
    4694                 :             :     return true;
    4695                 :       72314 :   canonic = ix86_canonical_va_list_type (type);
    4696                 :       72314 :   return (canonic == ms_va_list_type_node
    4697                 :       72314 :           || (ix86_abi == MS_ABI && canonic == va_list_type_node));
    4698                 :             : }
    4699                 :             : 
    4700                 :             : /* Implement va_start.  */
    4701                 :             : 
    4702                 :             : static void
    4703                 :       20763 : ix86_va_start (tree valist, rtx nextarg)
    4704                 :             : {
    4705                 :       20763 :   HOST_WIDE_INT words, n_gpr, n_fpr;
    4706                 :       20763 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4707                 :       20763 :   tree gpr, fpr, ovf, sav, t;
    4708                 :       20763 :   tree type;
    4709                 :       20763 :   rtx ovf_rtx;
    4710                 :             : 
    4711                 :       20763 :   if (flag_split_stack
    4712                 :          12 :       && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4713                 :             :     {
    4714                 :          12 :       unsigned int scratch_regno;
    4715                 :             : 
    4716                 :             :       /* When we are splitting the stack, we can't refer to the stack
    4717                 :             :          arguments using internal_arg_pointer, because they may be on
    4718                 :             :          the old stack.  The split stack prologue will arrange to
    4719                 :             :          leave a pointer to the old stack arguments in a scratch
    4720                 :             :          register, which we here copy to a pseudo-register.  The split
    4721                 :             :          stack prologue can't set the pseudo-register directly because
    4722                 :             :          it (the prologue) runs before any registers have been saved.  */
    4723                 :             : 
    4724                 :          12 :       scratch_regno = split_stack_prologue_scratch_regno ();
    4725                 :          12 :       if (scratch_regno != INVALID_REGNUM)
    4726                 :             :         {
    4727                 :          12 :           rtx reg;
    4728                 :          12 :           rtx_insn *seq;
    4729                 :             : 
    4730                 :          12 :           reg = gen_reg_rtx (Pmode);
    4731                 :          12 :           cfun->machine->split_stack_varargs_pointer = reg;
    4732                 :             : 
    4733                 :          12 :           start_sequence ();
    4734                 :          12 :           emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
    4735                 :          12 :           seq = get_insns ();
    4736                 :          12 :           end_sequence ();
    4737                 :             : 
    4738                 :          12 :           push_topmost_sequence ();
    4739                 :          12 :           emit_insn_after (seq, entry_of_function ());
    4740                 :          12 :           pop_topmost_sequence ();
    4741                 :             :         }
    4742                 :             :     }
    4743                 :             : 
    4744                 :             :   /* Only 64bit target needs something special.  */
    4745                 :       20763 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4746                 :             :     {
    4747                 :        5656 :       if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4748                 :        5652 :         std_expand_builtin_va_start (valist, nextarg);
    4749                 :             :       else
    4750                 :             :         {
    4751                 :           4 :           rtx va_r, next;
    4752                 :             : 
    4753                 :           4 :           va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
    4754                 :           8 :           next = expand_binop (ptr_mode, add_optab,
    4755                 :           4 :                                cfun->machine->split_stack_varargs_pointer,
    4756                 :             :                                crtl->args.arg_offset_rtx,
    4757                 :             :                                NULL_RTX, 0, OPTAB_LIB_WIDEN);
    4758                 :           4 :           convert_move (va_r, next, 0);
    4759                 :             :         }
    4760                 :        5656 :       return;
    4761                 :             :     }
    4762                 :             : 
    4763                 :       15107 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4764                 :       15107 :   f_fpr = DECL_CHAIN (f_gpr);
    4765                 :       15107 :   f_ovf = DECL_CHAIN (f_fpr);
    4766                 :       15107 :   f_sav = DECL_CHAIN (f_ovf);
    4767                 :             : 
    4768                 :       15107 :   valist = build_simple_mem_ref (valist);
    4769                 :       15107 :   TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
    4770                 :             :   /* The following should be folded into the MEM_REF offset.  */
    4771                 :       15107 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
    4772                 :             :                 f_gpr, NULL_TREE);
    4773                 :       15107 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
    4774                 :             :                 f_fpr, NULL_TREE);
    4775                 :       15107 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
    4776                 :             :                 f_ovf, NULL_TREE);
    4777                 :       15107 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
    4778                 :             :                 f_sav, NULL_TREE);
    4779                 :             : 
    4780                 :             :   /* Count number of gp and fp argument registers used.  */
    4781                 :       15107 :   words = crtl->args.info.words;
    4782                 :       15107 :   n_gpr = crtl->args.info.regno;
    4783                 :       15107 :   n_fpr = crtl->args.info.sse_regno;
    4784                 :             : 
    4785                 :       15107 :   if (cfun->va_list_gpr_size)
    4786                 :             :     {
    4787                 :       14898 :       type = TREE_TYPE (gpr);
    4788                 :       14898 :       t = build2 (MODIFY_EXPR, type,
    4789                 :       14898 :                   gpr, build_int_cst (type, n_gpr * 8));
    4790                 :       14898 :       TREE_SIDE_EFFECTS (t) = 1;
    4791                 :       14898 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4792                 :             :     }
    4793                 :             : 
    4794                 :       15107 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4795                 :             :     {
    4796                 :       14347 :       type = TREE_TYPE (fpr);
    4797                 :       14347 :       t = build2 (MODIFY_EXPR, type, fpr,
    4798                 :       14347 :                   build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
    4799                 :       14347 :       TREE_SIDE_EFFECTS (t) = 1;
    4800                 :       14347 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4801                 :             :     }
    4802                 :             : 
    4803                 :             :   /* Find the overflow area.  */
    4804                 :       15107 :   type = TREE_TYPE (ovf);
    4805                 :       15107 :   if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4806                 :       15099 :     ovf_rtx = crtl->args.internal_arg_pointer;
    4807                 :             :   else
    4808                 :             :     ovf_rtx = cfun->machine->split_stack_varargs_pointer;
    4809                 :       15107 :   t = make_tree (type, ovf_rtx);
    4810                 :       15107 :   if (words != 0)
    4811                 :         435 :     t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
    4812                 :             : 
    4813                 :       15107 :   t = build2 (MODIFY_EXPR, type, ovf, t);
    4814                 :       15107 :   TREE_SIDE_EFFECTS (t) = 1;
    4815                 :       15107 :   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4816                 :             : 
    4817                 :       15107 :   if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
    4818                 :             :     {
    4819                 :             :       /* Find the register save area.
    4820                 :             :          Prologue of the function save it right above stack frame.  */
    4821                 :       15063 :       type = TREE_TYPE (sav);
    4822                 :       15063 :       t = make_tree (type, frame_pointer_rtx);
    4823                 :       15063 :       if (!ix86_varargs_gpr_size)
    4824                 :         165 :         t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
    4825                 :             : 
    4826                 :       15063 :       t = build2 (MODIFY_EXPR, type, sav, t);
    4827                 :       15063 :       TREE_SIDE_EFFECTS (t) = 1;
    4828                 :       15063 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4829                 :             :     }
    4830                 :             : }
    4831                 :             : 
    4832                 :             : /* Implement va_arg.  */
    4833                 :             : 
    4834                 :             : static tree
    4835                 :       51713 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
    4836                 :             :                       gimple_seq *post_p)
    4837                 :             : {
    4838                 :       51713 :   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
    4839                 :       51713 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4840                 :       51713 :   tree gpr, fpr, ovf, sav, t;
    4841                 :       51713 :   int size, rsize;
    4842                 :       51713 :   tree lab_false, lab_over = NULL_TREE;
    4843                 :       51713 :   tree addr, t2;
    4844                 :       51713 :   rtx container;
    4845                 :       51713 :   int indirect_p = 0;
    4846                 :       51713 :   tree ptrtype;
    4847                 :       51713 :   machine_mode nat_mode;
    4848                 :       51713 :   unsigned int arg_boundary;
    4849                 :       51713 :   unsigned int type_align;
    4850                 :             : 
    4851                 :             :   /* Only 64bit target needs something special.  */
    4852                 :       51713 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4853                 :         260 :     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
    4854                 :             : 
    4855                 :       51453 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4856                 :       51453 :   f_fpr = DECL_CHAIN (f_gpr);
    4857                 :       51453 :   f_ovf = DECL_CHAIN (f_fpr);
    4858                 :       51453 :   f_sav = DECL_CHAIN (f_ovf);
    4859                 :             : 
    4860                 :       51453 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
    4861                 :             :                 valist, f_gpr, NULL_TREE);
    4862                 :             : 
    4863                 :       51453 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
    4864                 :       51453 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
    4865                 :       51453 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
    4866                 :             : 
    4867                 :       51453 :   indirect_p = pass_va_arg_by_reference (type);
    4868                 :       51453 :   if (indirect_p)
    4869                 :          99 :     type = build_pointer_type (type);
    4870                 :       51453 :   size = arg_int_size_in_bytes (type);
    4871                 :       51453 :   rsize = CEIL (size, UNITS_PER_WORD);
    4872                 :             : 
    4873                 :       51453 :   nat_mode = type_natural_mode (type, NULL, false);
    4874                 :       51453 :   switch (nat_mode)
    4875                 :             :     {
    4876                 :          28 :     case E_V16HFmode:
    4877                 :          28 :     case E_V16BFmode:
    4878                 :          28 :     case E_V8SFmode:
    4879                 :          28 :     case E_V8SImode:
    4880                 :          28 :     case E_V32QImode:
    4881                 :          28 :     case E_V16HImode:
    4882                 :          28 :     case E_V4DFmode:
    4883                 :          28 :     case E_V4DImode:
    4884                 :          28 :     case E_V32HFmode:
    4885                 :          28 :     case E_V32BFmode:
    4886                 :          28 :     case E_V16SFmode:
    4887                 :          28 :     case E_V16SImode:
    4888                 :          28 :     case E_V64QImode:
    4889                 :          28 :     case E_V32HImode:
    4890                 :          28 :     case E_V8DFmode:
    4891                 :          28 :     case E_V8DImode:
    4892                 :             :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    4893                 :          28 :       if (!TARGET_64BIT_MS_ABI)
    4894                 :             :         {
    4895                 :             :           container = NULL;
    4896                 :             :           break;
    4897                 :             :         }
    4898                 :             :       /* FALLTHRU */
    4899                 :             : 
    4900                 :       51425 :     default:
    4901                 :       51425 :       container = construct_container (nat_mode, TYPE_MODE (type),
    4902                 :             :                                        type, 0, X86_64_REGPARM_MAX,
    4903                 :             :                                        X86_64_SSE_REGPARM_MAX, intreg,
    4904                 :             :                                        0);
    4905                 :       51425 :       break;
    4906                 :             :     }
    4907                 :             : 
    4908                 :             :   /* Pull the value out of the saved registers.  */
    4909                 :             : 
    4910                 :       51453 :   addr = create_tmp_var (ptr_type_node, "addr");
    4911                 :       51453 :   type_align = TYPE_ALIGN (type);
    4912                 :             : 
    4913                 :       51453 :   if (container)
    4914                 :             :     {
    4915                 :       28372 :       int needed_intregs, needed_sseregs;
    4916                 :       28372 :       bool need_temp;
    4917                 :       28372 :       tree int_addr, sse_addr;
    4918                 :             : 
    4919                 :       28372 :       lab_false = create_artificial_label (UNKNOWN_LOCATION);
    4920                 :       28372 :       lab_over = create_artificial_label (UNKNOWN_LOCATION);
    4921                 :             : 
    4922                 :       28372 :       examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
    4923                 :             : 
    4924                 :       28372 :       bool container_in_reg = false;
    4925                 :       28372 :       if (REG_P (container))
    4926                 :             :         container_in_reg = true;
    4927                 :        1629 :       else if (GET_CODE (container) == PARALLEL
    4928                 :        1629 :                && GET_MODE (container) == BLKmode
    4929                 :         580 :                && XVECLEN (container, 0) == 1)
    4930                 :             :         {
    4931                 :             :           /* Check if it is a PARALLEL BLKmode container of an EXPR_LIST
    4932                 :             :              expression in a TImode register.  In this case, temp isn't
    4933                 :             :              needed.  Otherwise, the TImode variable will be put in the
    4934                 :             :              GPR save area which guarantees only 8-byte alignment.   */
    4935                 :         509 :           rtx x = XVECEXP (container, 0, 0);
    4936                 :         509 :           if (GET_CODE (x) == EXPR_LIST
    4937                 :         509 :               && REG_P (XEXP (x, 0))
    4938                 :         509 :               && XEXP (x, 1) == const0_rtx)
    4939                 :             :             container_in_reg = true;
    4940                 :             :         }
    4941                 :             : 
    4942                 :         668 :       need_temp = (!container_in_reg
    4943                 :        1138 :                    && ((needed_intregs && TYPE_ALIGN (type) > 64)
    4944                 :         668 :                        || TYPE_ALIGN (type) > 128));
    4945                 :             : 
    4946                 :             :       /* In case we are passing structure, verify that it is consecutive block
    4947                 :             :          on the register save area.  If not we need to do moves.  */
    4948                 :         668 :       if (!need_temp && !container_in_reg)
    4949                 :             :         {
    4950                 :             :           /* Verify that all registers are strictly consecutive  */
    4951                 :         942 :           if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
    4952                 :             :             {
    4953                 :             :               int i;
    4954                 :             : 
    4955                 :         779 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    4956                 :             :                 {
    4957                 :         505 :                   rtx slot = XVECEXP (container, 0, i);
    4958                 :         505 :                   if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
    4959                 :         505 :                       || INTVAL (XEXP (slot, 1)) != i * 16)
    4960                 :             :                     need_temp = true;
    4961                 :             :                 }
    4962                 :             :             }
    4963                 :             :           else
    4964                 :             :             {
    4965                 :             :               int i;
    4966                 :             : 
    4967                 :        1120 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    4968                 :             :                 {
    4969                 :         726 :                   rtx slot = XVECEXP (container, 0, i);
    4970                 :         726 :                   if (REGNO (XEXP (slot, 0)) != (unsigned int) i
    4971                 :         726 :                       || INTVAL (XEXP (slot, 1)) != i * 8)
    4972                 :             :                     need_temp = true;
    4973                 :             :                 }
    4974                 :             :             }
    4975                 :             :         }
    4976                 :       28372 :       if (!need_temp)
    4977                 :             :         {
    4978                 :             :           int_addr = addr;
    4979                 :             :           sse_addr = addr;
    4980                 :             :         }
    4981                 :             :       else
    4982                 :             :         {
    4983                 :         865 :           int_addr = create_tmp_var (ptr_type_node, "int_addr");
    4984                 :         865 :           sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
    4985                 :             :         }
    4986                 :             : 
    4987                 :             :       /* First ensure that we fit completely in registers.  */
    4988                 :       28372 :       if (needed_intregs)
    4989                 :             :         {
    4990                 :       17728 :           t = build_int_cst (TREE_TYPE (gpr),
    4991                 :       17728 :                              (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
    4992                 :       17728 :           t = build2 (GE_EXPR, boolean_type_node, gpr, t);
    4993                 :       17728 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    4994                 :       17728 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    4995                 :       17728 :           gimplify_and_add (t, pre_p);
    4996                 :             :         }
    4997                 :       28372 :       if (needed_sseregs)
    4998                 :             :         {
    4999                 :       11024 :           t = build_int_cst (TREE_TYPE (fpr),
    5000                 :             :                              (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
    5001                 :       11024 :                              + X86_64_REGPARM_MAX * 8);
    5002                 :       11024 :           t = build2 (GE_EXPR, boolean_type_node, fpr, t);
    5003                 :       11024 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    5004                 :       11024 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    5005                 :       11024 :           gimplify_and_add (t, pre_p);
    5006                 :             :         }
    5007                 :             : 
    5008                 :             :       /* Compute index to start of area used for integer regs.  */
    5009                 :       28372 :       if (needed_intregs)
    5010                 :             :         {
    5011                 :             :           /* int_addr = gpr + sav; */
    5012                 :       17728 :           t = fold_build_pointer_plus (sav, gpr);
    5013                 :       17728 :           gimplify_assign (int_addr, t, pre_p);
    5014                 :             :         }
    5015                 :       28372 :       if (needed_sseregs)
    5016                 :             :         {
    5017                 :             :           /* sse_addr = fpr + sav; */
    5018                 :       11024 :           t = fold_build_pointer_plus (sav, fpr);
    5019                 :       11024 :           gimplify_assign (sse_addr, t, pre_p);
    5020                 :             :         }
    5021                 :       28372 :       if (need_temp)
    5022                 :             :         {
    5023                 :         865 :           int i, prev_size = 0;
    5024                 :         865 :           tree temp = create_tmp_var (type, "va_arg_tmp");
    5025                 :         865 :           TREE_ADDRESSABLE (temp) = 1;
    5026                 :             : 
    5027                 :             :           /* addr = &temp; */
    5028                 :         865 :           t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
    5029                 :         865 :           gimplify_assign (addr, t, pre_p);
    5030                 :             : 
    5031                 :        2205 :           for (i = 0; i < XVECLEN (container, 0); i++)
    5032                 :             :             {
    5033                 :        1340 :               rtx slot = XVECEXP (container, 0, i);
    5034                 :        1340 :               rtx reg = XEXP (slot, 0);
    5035                 :        1340 :               machine_mode mode = GET_MODE (reg);
    5036                 :        1340 :               tree piece_type;
    5037                 :        1340 :               tree addr_type;
    5038                 :        1340 :               tree daddr_type;
    5039                 :        1340 :               tree src_addr, src;
    5040                 :        1340 :               int src_offset;
    5041                 :        1340 :               tree dest_addr, dest;
    5042                 :        1340 :               int cur_size = GET_MODE_SIZE (mode);
    5043                 :             : 
    5044                 :        1340 :               gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
    5045                 :        1340 :               prev_size = INTVAL (XEXP (slot, 1));
    5046                 :        1340 :               if (prev_size + cur_size > size)
    5047                 :             :                 {
    5048                 :          30 :                   cur_size = size - prev_size;
    5049                 :          30 :                   unsigned int nbits = cur_size * BITS_PER_UNIT;
    5050                 :          30 :                   if (!int_mode_for_size (nbits, 1).exists (&mode))
    5051                 :          10 :                     mode = QImode;
    5052                 :             :                 }
    5053                 :        1340 :               piece_type = lang_hooks.types.type_for_mode (mode, 1);
    5054                 :        1340 :               if (mode == GET_MODE (reg))
    5055                 :        1310 :                 addr_type = build_pointer_type (piece_type);
    5056                 :             :               else
    5057                 :          30 :                 addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5058                 :             :                                                          true);
    5059                 :        1340 :               daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5060                 :             :                                                         true);
    5061                 :             : 
    5062                 :        1340 :               if (SSE_REGNO_P (REGNO (reg)))
    5063                 :             :                 {
    5064                 :         522 :                   src_addr = sse_addr;
    5065                 :         522 :                   src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
    5066                 :             :                 }
    5067                 :             :               else
    5068                 :             :                 {
    5069                 :         818 :                   src_addr = int_addr;
    5070                 :         818 :                   src_offset = REGNO (reg) * 8;
    5071                 :             :                 }
    5072                 :        1340 :               src_addr = fold_convert (addr_type, src_addr);
    5073                 :        1340 :               src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
    5074                 :             : 
    5075                 :        1340 :               dest_addr = fold_convert (daddr_type, addr);
    5076                 :        1340 :               dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
    5077                 :        2680 :               if (cur_size == GET_MODE_SIZE (mode))
    5078                 :             :                 {
    5079                 :        1330 :                   src = build_va_arg_indirect_ref (src_addr);
    5080                 :        1330 :                   dest = build_va_arg_indirect_ref (dest_addr);
    5081                 :             : 
    5082                 :        1330 :                   gimplify_assign (dest, src, pre_p);
    5083                 :             :                 }
    5084                 :             :               else
    5085                 :             :                 {
    5086                 :          10 :                   tree copy
    5087                 :          20 :                     = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
    5088                 :             :                                        3, dest_addr, src_addr,
    5089                 :          10 :                                        size_int (cur_size));
    5090                 :          10 :                   gimplify_and_add (copy, pre_p);
    5091                 :             :                 }
    5092                 :        1340 :               prev_size += cur_size;
    5093                 :             :             }
    5094                 :             :         }
    5095                 :             : 
    5096                 :       28372 :       if (needed_intregs)
    5097                 :             :         {
    5098                 :       17728 :           t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
    5099                 :       17728 :                       build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
    5100                 :       17728 :           gimplify_assign (gpr, t, pre_p);
    5101                 :             :           /* The GPR save area guarantees only 8-byte alignment.  */
    5102                 :       17728 :           if (!need_temp)
    5103                 :       16936 :             type_align = MIN (type_align, 64);
    5104                 :             :         }
    5105                 :             : 
    5106                 :       28372 :       if (needed_sseregs)
    5107                 :             :         {
    5108                 :       11024 :           t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
    5109                 :       11024 :                       build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
    5110                 :       11024 :           gimplify_assign (unshare_expr (fpr), t, pre_p);
    5111                 :             :         }
    5112                 :             : 
    5113                 :       28372 :       gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
    5114                 :             : 
    5115                 :       28372 :       gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
    5116                 :             :     }
    5117                 :             : 
    5118                 :             :   /* ... otherwise out of the overflow area.  */
    5119                 :             : 
    5120                 :             :   /* When we align parameter on stack for caller, if the parameter
    5121                 :             :      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
    5122                 :             :      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
    5123                 :             :      here with caller.  */
    5124                 :       51453 :   arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
    5125                 :       51453 :   if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
    5126                 :             :     arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
    5127                 :             : 
    5128                 :             :   /* Care for on-stack alignment if needed.  */
    5129                 :       51453 :   if (arg_boundary <= 64 || size == 0)
    5130                 :       34412 :     t = ovf;
    5131                 :             :  else
    5132                 :             :     {
    5133                 :       17041 :       HOST_WIDE_INT align = arg_boundary / 8;
    5134                 :       17041 :       t = fold_build_pointer_plus_hwi (ovf, align - 1);
    5135                 :       17041 :       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
    5136                 :       17041 :                   build_int_cst (TREE_TYPE (t), -align));
    5137                 :             :     }
    5138                 :             : 
    5139                 :       51453 :   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
    5140                 :       51453 :   gimplify_assign (addr, t, pre_p);
    5141                 :             : 
    5142                 :       51453 :   t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
    5143                 :       51453 :   gimplify_assign (unshare_expr (ovf), t, pre_p);
    5144                 :             : 
    5145                 :       51453 :   if (container)
    5146                 :       28372 :     gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
    5147                 :             : 
    5148                 :       51453 :   type = build_aligned_type (type, type_align);
    5149                 :       51453 :   ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
    5150                 :       51453 :   addr = fold_convert (ptrtype, addr);
    5151                 :             : 
    5152                 :       51453 :   if (indirect_p)
    5153                 :          99 :     addr = build_va_arg_indirect_ref (addr);
    5154                 :       51453 :   return build_va_arg_indirect_ref (addr);
    5155                 :             : }
    5156                 :             : 
    5157                 :             : /* Return true if OPNUM's MEM should be matched
    5158                 :             :    in movabs* patterns.  */
    5159                 :             : 
    5160                 :             : bool
    5161                 :       18071 : ix86_check_movabs (rtx insn, int opnum)
    5162                 :             : {
    5163                 :       18071 :   rtx set, mem;
    5164                 :             : 
    5165                 :       18071 :   set = PATTERN (insn);
    5166                 :       18071 :   if (GET_CODE (set) == PARALLEL)
    5167                 :           0 :     set = XVECEXP (set, 0, 0);
    5168                 :       18071 :   gcc_assert (GET_CODE (set) == SET);
    5169                 :       18071 :   mem = XEXP (set, opnum);
    5170                 :       18071 :   while (SUBREG_P (mem))
    5171                 :           0 :     mem = SUBREG_REG (mem);
    5172                 :       18071 :   gcc_assert (MEM_P (mem));
    5173                 :       18071 :   return volatile_ok || !MEM_VOLATILE_P (mem);
    5174                 :             : }
    5175                 :             : 
    5176                 :             : /* Return false if INSN contains a MEM with a non-default address space.  */
    5177                 :             : bool
    5178                 :      733330 : ix86_check_no_addr_space (rtx insn)
    5179                 :             : {
    5180                 :      733330 :   subrtx_var_iterator::array_type array;
    5181                 :    16668965 :   FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
    5182                 :             :     {
    5183                 :    15935635 :       rtx x = *iter;
    5184                 :    17091419 :       if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
    5185                 :           0 :         return false;
    5186                 :             :     }
    5187                 :      733330 :   return true;
    5188                 :      733330 : }
    5189                 :             : 
    5190                 :             : /* Initialize the table of extra 80387 mathematical constants.  */
    5191                 :             : 
    5192                 :             : static void
    5193                 :        2385 : init_ext_80387_constants (void)
    5194                 :             : {
    5195                 :        2385 :   static const char * cst[5] =
    5196                 :             :   {
    5197                 :             :     "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
    5198                 :             :     "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
    5199                 :             :     "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
    5200                 :             :     "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
    5201                 :             :     "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
    5202                 :             :   };
    5203                 :        2385 :   int i;
    5204                 :             : 
    5205                 :       14310 :   for (i = 0; i < 5; i++)
    5206                 :             :     {
    5207                 :       11925 :       real_from_string (&ext_80387_constants_table[i], cst[i]);
    5208                 :             :       /* Ensure each constant is rounded to XFmode precision.  */
    5209                 :       11925 :       real_convert (&ext_80387_constants_table[i],
    5210                 :       23850 :                     XFmode, &ext_80387_constants_table[i]);
    5211                 :             :     }
    5212                 :             : 
    5213                 :        2385 :   ext_80387_constants_init = 1;
    5214                 :        2385 : }
    5215                 :             : 
    5216                 :             : /* Return non-zero if the constant is something that
    5217                 :             :    can be loaded with a special instruction.  */
    5218                 :             : 
    5219                 :             : int
    5220                 :     4981247 : standard_80387_constant_p (rtx x)
    5221                 :             : {
    5222                 :     4981247 :   machine_mode mode = GET_MODE (x);
    5223                 :             : 
    5224                 :     4981247 :   const REAL_VALUE_TYPE *r;
    5225                 :             : 
    5226                 :     4981247 :   if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
    5227                 :             :     return -1;
    5228                 :             : 
    5229                 :     4515497 :   if (x == CONST0_RTX (mode))
    5230                 :             :     return 1;
    5231                 :     2048581 :   if (x == CONST1_RTX (mode))
    5232                 :             :     return 2;
    5233                 :             : 
    5234                 :     1224891 :   r = CONST_DOUBLE_REAL_VALUE (x);
    5235                 :             : 
    5236                 :             :   /* For XFmode constants, try to find a special 80387 instruction when
    5237                 :             :      optimizing for size or on those CPUs that benefit from them.  */
    5238                 :     1224891 :   if (mode == XFmode
    5239                 :      797281 :       && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
    5240                 :     2022172 :       && !flag_rounding_math)
    5241                 :             :     {
    5242                 :      789682 :       int i;
    5243                 :             : 
    5244                 :      789682 :       if (! ext_80387_constants_init)
    5245                 :        2378 :         init_ext_80387_constants ();
    5246                 :             : 
    5247                 :     4727498 :       for (i = 0; i < 5; i++)
    5248                 :     3946729 :         if (real_identical (r, &ext_80387_constants_table[i]))
    5249                 :        8913 :           return i + 3;
    5250                 :             :     }
    5251                 :             : 
    5252                 :             :   /* Load of the constant -0.0 or -1.0 will be split as
    5253                 :             :      fldz;fchs or fld1;fchs sequence.  */
    5254                 :     1215978 :   if (real_isnegzero (r))
    5255                 :             :     return 8;
    5256                 :     1200706 :   if (real_identical (r, &dconstm1))
    5257                 :      300985 :     return 9;
    5258                 :             : 
    5259                 :             :   return 0;
    5260                 :             : }
    5261                 :             : 
    5262                 :             : /* Return the opcode of the special instruction to be used to load
    5263                 :             :    the constant X.  */
    5264                 :             : 
    5265                 :             : const char *
    5266                 :       53261 : standard_80387_constant_opcode (rtx x)
    5267                 :             : {
    5268                 :       53261 :   switch (standard_80387_constant_p (x))
    5269                 :             :     {
    5270                 :             :     case 1:
    5271                 :             :       return "fldz";
    5272                 :       33576 :     case 2:
    5273                 :       33576 :       return "fld1";
    5274                 :           1 :     case 3:
    5275                 :           1 :       return "fldlg2";
    5276                 :          10 :     case 4:
    5277                 :          10 :       return "fldln2";
    5278                 :          12 :     case 5:
    5279                 :          12 :       return "fldl2e";
    5280                 :           2 :     case 6:
    5281                 :           2 :       return "fldl2t";
    5282                 :         190 :     case 7:
    5283                 :         190 :       return "fldpi";
    5284                 :           0 :     case 8:
    5285                 :           0 :     case 9:
    5286                 :           0 :       return "#";
    5287                 :           0 :     default:
    5288                 :           0 :       gcc_unreachable ();
    5289                 :             :     }
    5290                 :             : }
    5291                 :             : 
    5292                 :             : /* Return the CONST_DOUBLE representing the 80387 constant that is
    5293                 :             :    loaded by the specified special instruction.  The argument IDX
    5294                 :             :    matches the return value from standard_80387_constant_p.  */
    5295                 :             : 
    5296                 :             : rtx
    5297                 :          24 : standard_80387_constant_rtx (int idx)
    5298                 :             : {
    5299                 :          24 :   int i;
    5300                 :             : 
    5301                 :          24 :   if (! ext_80387_constants_init)
    5302                 :           7 :     init_ext_80387_constants ();
    5303                 :             : 
    5304                 :          24 :   switch (idx)
    5305                 :             :     {
    5306                 :          24 :     case 3:
    5307                 :          24 :     case 4:
    5308                 :          24 :     case 5:
    5309                 :          24 :     case 6:
    5310                 :          24 :     case 7:
    5311                 :          24 :       i = idx - 3;
    5312                 :          24 :       break;
    5313                 :             : 
    5314                 :           0 :     default:
    5315                 :           0 :       gcc_unreachable ();
    5316                 :             :     }
    5317                 :             : 
    5318                 :          24 :   return const_double_from_real_value (ext_80387_constants_table[i],
    5319                 :          24 :                                        XFmode);
    5320                 :             : }
    5321                 :             : 
    5322                 :             : /* Return 1 if X is all bits 0, 2 if X is all bits 1
    5323                 :             :    and 3 if X is all bits 1 with zero extend
    5324                 :             :    in supported SSE/AVX vector mode.  */
    5325                 :             : 
    5326                 :             : int
    5327                 :    48816358 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
    5328                 :             : {
    5329                 :    48816358 :   machine_mode mode;
    5330                 :             : 
    5331                 :    48816358 :   if (!TARGET_SSE)
    5332                 :             :     return 0;
    5333                 :             : 
    5334                 :    48655158 :   mode = GET_MODE (x);
    5335                 :             : 
    5336                 :    48655158 :   if (x == const0_rtx || const0_operand (x, mode))
    5337                 :    10963214 :     return 1;
    5338                 :             : 
    5339                 :    37691944 :   if (x == constm1_rtx
    5340                 :    37554362 :       || vector_all_ones_operand (x, mode)
    5341                 :    74798089 :       || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5342                 :    31141261 :            || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
    5343                 :     5964884 :           && float_vector_all_ones_operand (x, mode)))
    5344                 :             :     {
    5345                 :             :       /* VOIDmode integer constant, get mode from the predicate.  */
    5346                 :      587833 :       if (mode == VOIDmode)
    5347                 :      137582 :         mode = pred_mode;
    5348                 :             : 
    5349                 :     1175666 :       switch (GET_MODE_SIZE (mode))
    5350                 :             :         {
    5351                 :       29605 :         case 64:
    5352                 :       29605 :           if (TARGET_AVX512F && TARGET_EVEX512)
    5353                 :             :             return 2;
    5354                 :             :           break;
    5355                 :       39304 :         case 32:
    5356                 :       39304 :           if (TARGET_AVX2)
    5357                 :             :             return 2;
    5358                 :             :           break;
    5359                 :      508203 :         case 16:
    5360                 :      508203 :           if (TARGET_SSE2)
    5361                 :             :             return 2;
    5362                 :             :           break;
    5363                 :           0 :         case 0:
    5364                 :             :           /* VOIDmode */
    5365                 :           0 :           gcc_unreachable ();
    5366                 :             :         default:
    5367                 :             :           break;
    5368                 :             :         }
    5369                 :             :     }
    5370                 :             : 
    5371                 :    37115545 :   if (vector_all_ones_zero_extend_half_operand (x, mode)
    5372                 :    37115545 :       || vector_all_ones_zero_extend_quarter_operand (x, mode))
    5373                 :         686 :     return 3;
    5374                 :             : 
    5375                 :             :   return 0;
    5376                 :             : }
    5377                 :             : 
    5378                 :             : /* Return the opcode of the special instruction to be used to load
    5379                 :             :    the constant operands[1] into operands[0].  */
    5380                 :             : 
    5381                 :             : const char *
    5382                 :      449296 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
    5383                 :             : {
    5384                 :      449296 :   machine_mode mode;
    5385                 :      449296 :   rtx x = operands[1];
    5386                 :             : 
    5387                 :      449296 :   gcc_assert (TARGET_SSE);
    5388                 :             : 
    5389                 :      449296 :   mode = GET_MODE (x);
    5390                 :             : 
    5391                 :      449296 :   if (x == const0_rtx || const0_operand (x, mode))
    5392                 :             :     {
    5393                 :      438135 :       switch (get_attr_mode (insn))
    5394                 :             :         {
    5395                 :      420658 :         case MODE_TI:
    5396                 :      420658 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5397                 :             :             return "%vpxor\t%0, %d0";
    5398                 :             :           /* FALLTHRU */
    5399                 :        5837 :         case MODE_XI:
    5400                 :        5837 :         case MODE_OI:
    5401                 :        5837 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5402                 :             :             {
    5403                 :          51 :               if (TARGET_AVX512VL)
    5404                 :             :                 return "vpxord\t%x0, %x0, %x0";
    5405                 :          43 :               else if (TARGET_EVEX512)
    5406                 :             :                 return "vpxord\t%g0, %g0, %g0";
    5407                 :             :               else
    5408                 :           0 :                 gcc_unreachable ();
    5409                 :             :             }
    5410                 :             :           return "vpxor\t%x0, %x0, %x0";
    5411                 :             : 
    5412                 :        2165 :         case MODE_V2DF:
    5413                 :        2165 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5414                 :             :             return "%vxorpd\t%0, %d0";
    5415                 :             :           /* FALLTHRU */
    5416                 :         935 :         case MODE_V8DF:
    5417                 :         935 :         case MODE_V4DF:
    5418                 :         935 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5419                 :             :             {
    5420                 :           4 :               if (TARGET_AVX512DQ)
    5421                 :             :                 {
    5422                 :           0 :                   if (TARGET_AVX512VL)
    5423                 :             :                     return "vxorpd\t%x0, %x0, %x0";
    5424                 :           0 :                   else if (TARGET_EVEX512)
    5425                 :             :                     return "vxorpd\t%g0, %g0, %g0";
    5426                 :             :                   else
    5427                 :           0 :                     gcc_unreachable ();
    5428                 :             :                 }
    5429                 :             :               else
    5430                 :             :                 {
    5431                 :           4 :                   if (TARGET_AVX512VL)
    5432                 :             :                     return "vpxorq\t%x0, %x0, %x0";
    5433                 :           4 :                   else if (TARGET_EVEX512)
    5434                 :             :                     return "vpxorq\t%g0, %g0, %g0";
    5435                 :             :                   else
    5436                 :           0 :                     gcc_unreachable ();
    5437                 :             :                 }
    5438                 :             :             }
    5439                 :             :           return "vxorpd\t%x0, %x0, %x0";
    5440                 :             : 
    5441                 :        6608 :         case MODE_V4SF:
    5442                 :        6608 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5443                 :             :             return "%vxorps\t%0, %d0";
    5444                 :             :           /* FALLTHRU */
    5445                 :        1959 :         case MODE_V16SF:
    5446                 :        1959 :         case MODE_V8SF:
    5447                 :        1959 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5448                 :             :             {
    5449                 :          26 :               if (TARGET_AVX512DQ)
    5450                 :             :                 {
    5451                 :          21 :                   if (TARGET_AVX512VL)
    5452                 :             :                     return "vxorps\t%x0, %x0, %x0";
    5453                 :           0 :                   else if (TARGET_EVEX512)
    5454                 :             :                     return "vxorps\t%g0, %g0, %g0";
    5455                 :             :                   else
    5456                 :           0 :                     gcc_unreachable ();
    5457                 :             :                 }
    5458                 :             :               else
    5459                 :             :                 {
    5460                 :           5 :                   if (TARGET_AVX512VL)
    5461                 :             :                     return "vpxord\t%x0, %x0, %x0";
    5462                 :           2 :                   else if (TARGET_EVEX512)
    5463                 :             :                     return "vpxord\t%g0, %g0, %g0";
    5464                 :             :                   else
    5465                 :           0 :                     gcc_unreachable ();
    5466                 :             :                 }
    5467                 :             :             }
    5468                 :             :           return "vxorps\t%x0, %x0, %x0";
    5469                 :             : 
    5470                 :           0 :         default:
    5471                 :           0 :           gcc_unreachable ();
    5472                 :             :         }
    5473                 :             :     }
    5474                 :       11161 :   else if (x == constm1_rtx
    5475                 :       11152 :            || vector_all_ones_operand (x, mode)
    5476                 :       11234 :            || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5477                 :          51 :                && float_vector_all_ones_operand (x, mode)))
    5478                 :             :     {
    5479                 :       11139 :       enum attr_mode insn_mode = get_attr_mode (insn);
    5480                 :             : 
    5481                 :       11139 :       switch (insn_mode)
    5482                 :             :         {
    5483                 :           7 :         case MODE_XI:
    5484                 :           7 :         case MODE_V8DF:
    5485                 :           7 :         case MODE_V16SF:
    5486                 :           7 :           gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5487                 :             :           return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5488                 :             : 
    5489                 :        1052 :         case MODE_OI:
    5490                 :        1052 :         case MODE_V4DF:
    5491                 :        1052 :         case MODE_V8SF:
    5492                 :        1052 :           gcc_assert (TARGET_AVX2);
    5493                 :             :           /* FALLTHRU */
    5494                 :       11132 :         case MODE_TI:
    5495                 :       11132 :         case MODE_V2DF:
    5496                 :       11132 :         case MODE_V4SF:
    5497                 :       11132 :           gcc_assert (TARGET_SSE2);
    5498                 :       11132 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5499                 :             :             {
    5500                 :           2 :               if (TARGET_AVX512VL)
    5501                 :             :                 return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
    5502                 :           0 :               else if (TARGET_EVEX512)
    5503                 :             :                 return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5504                 :             :               else
    5505                 :           0 :                 gcc_unreachable ();
    5506                 :             :             }
    5507                 :       11130 :           return (TARGET_AVX
    5508                 :       11130 :                   ? "vpcmpeqd\t%0, %0, %0"
    5509                 :       11130 :                   : "pcmpeqd\t%0, %0");
    5510                 :             : 
    5511                 :           0 :         default:
    5512                 :           0 :           gcc_unreachable ();
    5513                 :             :         }
    5514                 :             :    }
    5515                 :          22 :   else if (vector_all_ones_zero_extend_half_operand (x, mode))
    5516                 :             :     {
    5517                 :          40 :       if (GET_MODE_SIZE (mode) == 64)
    5518                 :             :         {
    5519                 :           5 :           gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5520                 :             :           return "vpcmpeqd\t%t0, %t0, %t0";
    5521                 :             :         }
    5522                 :          30 :       else if (GET_MODE_SIZE (mode) == 32)
    5523                 :             :         {
    5524                 :          15 :           gcc_assert (TARGET_AVX);
    5525                 :             :           return "vpcmpeqd\t%x0, %x0, %x0";
    5526                 :             :         }
    5527                 :           0 :       gcc_unreachable ();
    5528                 :             :     }
    5529                 :           2 :   else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
    5530                 :             :     {
    5531                 :           2 :       gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5532                 :             :       return "vpcmpeqd\t%x0, %x0, %x0";
    5533                 :             :     }
    5534                 :             : 
    5535                 :           0 :   gcc_unreachable ();
    5536                 :             : }
    5537                 :             : 
    5538                 :             : /* Returns true if INSN can be transformed from a memory load
    5539                 :             :    to a supported FP constant load.  */
    5540                 :             : 
    5541                 :             : bool
    5542                 :     2190809 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
    5543                 :             : {
    5544                 :     2190809 :   rtx src = find_constant_src (insn);
    5545                 :             : 
    5546                 :     2190809 :   gcc_assert (REG_P (dst));
    5547                 :             : 
    5548                 :     2190809 :   if (src == NULL
    5549                 :      614929 :       || (SSE_REGNO_P (REGNO (dst))
    5550                 :      484499 :           && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
    5551                 :      162497 :       || (!TARGET_AVX512VL
    5552                 :      162436 :           && EXT_REX_SSE_REGNO_P (REGNO (dst))
    5553                 :           0 :           && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
    5554                 :     2353306 :       || (STACK_REGNO_P (REGNO (dst))
    5555                 :      130430 :            && standard_80387_constant_p (src) < 1))
    5556                 :     2117775 :     return false;
    5557                 :             : 
    5558                 :             :   return true;
    5559                 :             : }
    5560                 :             : 
    5561                 :             : /* Predicate for pre-reload splitters with associated instructions,
    5562                 :             :    which can match any time before the split1 pass (usually combine),
    5563                 :             :    then are unconditionally split in that pass and should not be
    5564                 :             :    matched again afterwards.  */
    5565                 :             : 
    5566                 :             : bool
    5567                 :    15843449 : ix86_pre_reload_split (void)
    5568                 :             : {
    5569                 :    15843449 :   return (can_create_pseudo_p ()
    5570                 :    23926949 :           && !(cfun->curr_properties & PROP_rtl_split_insns));
    5571                 :             : }
    5572                 :             : 
    5573                 :             : /* Return the opcode of the TYPE_SSEMOV instruction.  To move from
    5574                 :             :    or to xmm16-xmm31/ymm16-ymm31 registers, we either require
    5575                 :             :    TARGET_AVX512VL or it is a register to register move which can
    5576                 :             :    be done with zmm register move. */
    5577                 :             : 
    5578                 :             : static const char *
    5579                 :     3677481 : ix86_get_ssemov (rtx *operands, unsigned size,
    5580                 :             :                  enum attr_mode insn_mode, machine_mode mode)
    5581                 :             : {
    5582                 :     3677481 :   char buf[128];
    5583                 :     3677481 :   bool misaligned_p = (misaligned_operand (operands[0], mode)
    5584                 :     3677481 :                        || misaligned_operand (operands[1], mode));
    5585                 :     3677481 :   bool evex_reg_p = (size == 64
    5586                 :     3598854 :                      || EXT_REX_SSE_REG_P (operands[0])
    5587                 :     7275713 :                      || EXT_REX_SSE_REG_P (operands[1]));
    5588                 :             : 
    5589                 :     3677481 :   bool egpr_p = (TARGET_APX_EGPR
    5590                 :     3677481 :                  && (x86_extended_rex2reg_mentioned_p (operands[0])
    5591                 :         104 :                      || x86_extended_rex2reg_mentioned_p (operands[1])));
    5592                 :         193 :   bool egpr_vl = egpr_p && TARGET_AVX512VL;
    5593                 :             : 
    5594                 :     3677481 :   machine_mode scalar_mode;
    5595                 :             : 
    5596                 :     3677481 :   const char *opcode = NULL;
    5597                 :     3677481 :   enum
    5598                 :             :     {
    5599                 :             :       opcode_int,
    5600                 :             :       opcode_float,
    5601                 :             :       opcode_double
    5602                 :     3677481 :     } type = opcode_int;
    5603                 :             : 
    5604                 :     3677481 :   switch (insn_mode)
    5605                 :             :     {
    5606                 :             :     case MODE_V16SF:
    5607                 :             :     case MODE_V8SF:
    5608                 :             :     case MODE_V4SF:
    5609                 :             :       scalar_mode = E_SFmode;
    5610                 :             :       type = opcode_float;
    5611                 :             :       break;
    5612                 :      207619 :     case MODE_V8DF:
    5613                 :      207619 :     case MODE_V4DF:
    5614                 :      207619 :     case MODE_V2DF:
    5615                 :      207619 :       scalar_mode = E_DFmode;
    5616                 :      207619 :       type = opcode_double;
    5617                 :      207619 :       break;
    5618                 :     1293056 :     case MODE_XI:
    5619                 :     1293056 :     case MODE_OI:
    5620                 :     1293056 :     case MODE_TI:
    5621                 :     1293056 :       scalar_mode = GET_MODE_INNER (mode);
    5622                 :             :       break;
    5623                 :           0 :     default:
    5624                 :           0 :       gcc_unreachable ();
    5625                 :             :     }
    5626                 :             : 
    5627                 :             :   /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
    5628                 :             :      we can only use zmm register move without memory operand.  */
    5629                 :     3677481 :   if (evex_reg_p
    5630                 :       79870 :       && !TARGET_AVX512VL
    5631                 :     3723014 :       && GET_MODE_SIZE (mode) < 64)
    5632                 :             :     {
    5633                 :             :       /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
    5634                 :             :          xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
    5635                 :             :          AVX512VL is disabled, LRA can still generate reg to
    5636                 :             :          reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
    5637                 :             :          modes.  */
    5638                 :           0 :       if (memory_operand (operands[0], mode)
    5639                 :           0 :           || memory_operand (operands[1], mode))
    5640                 :           0 :         gcc_unreachable ();
    5641                 :           0 :       size = 64;
    5642                 :             :       /* We need TARGET_EVEX512 to move into zmm register.  */
    5643                 :           0 :       gcc_assert (TARGET_EVEX512);
    5644                 :           0 :       switch (type)
    5645                 :             :         {
    5646                 :           0 :         case opcode_int:
    5647                 :           0 :           if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
    5648                 :           0 :             opcode = (misaligned_p
    5649                 :           0 :                       ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
    5650                 :             :                       : "vmovdqa64");
    5651                 :             :           else
    5652                 :           0 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5653                 :             :           break;
    5654                 :           0 :         case opcode_float:
    5655                 :           0 :           opcode = misaligned_p ? "vmovups" : "vmovaps";
    5656                 :             :           break;
    5657                 :           0 :         case opcode_double:
    5658                 :           0 :           opcode = misaligned_p ? "vmovupd" : "vmovapd";
    5659                 :             :           break;
    5660                 :             :         }
    5661                 :             :     }
    5662                 :     3677481 :   else if (SCALAR_FLOAT_MODE_P (scalar_mode))
    5663                 :             :     {
    5664                 :     2561654 :       switch (scalar_mode)
    5665                 :             :         {
    5666                 :       38059 :         case E_HFmode:
    5667                 :       38059 :         case E_BFmode:
    5668                 :       38059 :           if (evex_reg_p || egpr_vl)
    5669                 :       11000 :             opcode = (misaligned_p
    5670                 :         164 :                       ? (TARGET_AVX512BW
    5671                 :             :                          ? "vmovdqu16"
    5672                 :             :                          : "vmovdqu64")
    5673                 :             :                       : "vmovdqa64");
    5674                 :       27059 :           else if (egpr_p)
    5675                 :           0 :             opcode = (misaligned_p
    5676                 :           0 :                       ? (TARGET_AVX512BW
    5677                 :           0 :                          ? "vmovdqu16"
    5678                 :             :                          : "%vmovups")
    5679                 :             :                       : "%vmovaps");
    5680                 :             :           else
    5681                 :       27059 :             opcode = (misaligned_p
    5682                 :       27059 :                       ? (TARGET_AVX512BW
    5683                 :         471 :                          ? "vmovdqu16"
    5684                 :             :                          : "%vmovdqu")
    5685                 :             :                       : "%vmovdqa");
    5686                 :             :           break;
    5687                 :     2176806 :         case E_SFmode:
    5688                 :     2176806 :           opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5689                 :             :           break;
    5690                 :      207619 :         case E_DFmode:
    5691                 :      207619 :           opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
    5692                 :             :           break;
    5693                 :      139170 :         case E_TFmode:
    5694                 :      139170 :           if (evex_reg_p || egpr_vl)
    5695                 :          14 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5696                 :      139156 :           else if (egpr_p)
    5697                 :           0 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5698                 :             :           else
    5699                 :      139156 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5700                 :             :           break;
    5701                 :           0 :         default:
    5702                 :           0 :           gcc_unreachable ();
    5703                 :             :         }
    5704                 :             :     }
    5705                 :     1115827 :   else if (SCALAR_INT_MODE_P (scalar_mode))
    5706                 :             :     {
    5707                 :     1115827 :       switch (scalar_mode)
    5708                 :             :         {
    5709                 :       42389 :         case E_QImode:
    5710                 :       42389 :           if (evex_reg_p || egpr_vl)
    5711                 :        5729 :             opcode = (misaligned_p
    5712                 :        5729 :                       ? (TARGET_AVX512BW
    5713                 :        2388 :                          ? "vmovdqu8"
    5714                 :             :                          : "vmovdqu64")
    5715                 :             :                       : "vmovdqa64");
    5716                 :       36660 :           else if (egpr_p)
    5717                 :          30 :             opcode = (misaligned_p
    5718                 :           0 :                       ? (TARGET_AVX512BW
    5719                 :             :                          ? "vmovdqu8"
    5720                 :             :                          : "%vmovups")
    5721                 :             :                       : "%vmovaps");
    5722                 :             :           else
    5723                 :       36630 :             opcode = (misaligned_p
    5724                 :        8679 :                       ? (TARGET_AVX512BW
    5725                 :             :                          ? "vmovdqu8"
    5726                 :             :                          : "%vmovdqu")
    5727                 :             :                       : "%vmovdqa");
    5728                 :             :           break;
    5729                 :       38979 :         case E_HImode:
    5730                 :       38979 :           if (evex_reg_p || egpr_vl)
    5731                 :        3327 :             opcode = (misaligned_p
    5732                 :         157 :                       ? (TARGET_AVX512BW
    5733                 :             :                          ? "vmovdqu16"
    5734                 :             :                          : "vmovdqu64")
    5735                 :             :                       : "vmovdqa64");
    5736                 :       35652 :           else if (egpr_p)
    5737                 :          27 :             opcode = (misaligned_p
    5738                 :          27 :                       ? (TARGET_AVX512BW
    5739                 :           0 :                          ? "vmovdqu16"
    5740                 :             :                          : "%vmovups")
    5741                 :             :                       : "%vmovaps");
    5742                 :             :           else
    5743                 :       35625 :             opcode = (misaligned_p
    5744                 :       35625 :                       ? (TARGET_AVX512BW
    5745                 :        3114 :                          ? "vmovdqu16"
    5746                 :             :                          : "%vmovdqu")
    5747                 :             :                       : "%vmovdqa");
    5748                 :             :           break;
    5749                 :      155619 :         case E_SImode:
    5750                 :      155619 :           if (evex_reg_p || egpr_vl)
    5751                 :        7294 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5752                 :      148325 :           else if (egpr_p)
    5753                 :          14 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5754                 :             :           else
    5755                 :      148311 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5756                 :             :           break;
    5757                 :      867871 :         case E_DImode:
    5758                 :      867871 :         case E_TImode:
    5759                 :      867871 :         case E_OImode:
    5760                 :      867871 :           if (evex_reg_p || egpr_vl)
    5761                 :       17772 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5762                 :      850099 :           else if (egpr_p)
    5763                 :          26 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5764                 :             :           else
    5765                 :      850073 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5766                 :             :           break;
    5767                 :       10969 :         case E_XImode:
    5768                 :       10969 :           opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5769                 :             :           break;
    5770                 :           0 :         default:
    5771                 :           0 :           gcc_unreachable ();
    5772                 :             :         }
    5773                 :             :     }
    5774                 :             :   else
    5775                 :           0 :     gcc_unreachable ();
    5776                 :             : 
    5777                 :     3677481 :   switch (size)
    5778                 :             :     {
    5779                 :       78627 :     case 64:
    5780                 :       78627 :       snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
    5781                 :             :                 opcode);
    5782                 :       78627 :       break;
    5783                 :       91878 :     case 32:
    5784                 :       91878 :       snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
    5785                 :             :                 opcode);
    5786                 :       91878 :       break;
    5787                 :     3506976 :     case 16:
    5788                 :     3506976 :       snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
    5789                 :             :                 opcode);
    5790                 :     3506976 :       break;
    5791                 :           0 :     default:
    5792                 :           0 :       gcc_unreachable ();
    5793                 :             :     }
    5794                 :     3677481 :   output_asm_insn (buf, operands);
    5795                 :     3677481 :   return "";
    5796                 :             : }
    5797                 :             : 
    5798                 :             : /* Return the template of the TYPE_SSEMOV instruction to move
    5799                 :             :    operands[1] into operands[0].  */
    5800                 :             : 
    5801                 :             : const char *
    5802                 :     6107560 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
    5803                 :             : {
    5804                 :     6107560 :   machine_mode mode = GET_MODE (operands[0]);
    5805                 :     6107560 :   if (get_attr_type (insn) != TYPE_SSEMOV
    5806                 :     6107560 :       || mode != GET_MODE (operands[1]))
    5807                 :           0 :     gcc_unreachable ();
    5808                 :             : 
    5809                 :     6107560 :   enum attr_mode insn_mode = get_attr_mode (insn);
    5810                 :             : 
    5811                 :     6107560 :   switch (insn_mode)
    5812                 :             :     {
    5813                 :       78627 :     case MODE_XI:
    5814                 :       78627 :     case MODE_V8DF:
    5815                 :       78627 :     case MODE_V16SF:
    5816                 :       78627 :       return ix86_get_ssemov (operands, 64, insn_mode, mode);
    5817                 :             : 
    5818                 :       91878 :     case MODE_OI:
    5819                 :       91878 :     case MODE_V4DF:
    5820                 :       91878 :     case MODE_V8SF:
    5821                 :       91878 :       return ix86_get_ssemov (operands, 32, insn_mode, mode);
    5822                 :             : 
    5823                 :     3506976 :     case MODE_TI:
    5824                 :     3506976 :     case MODE_V2DF:
    5825                 :     3506976 :     case MODE_V4SF:
    5826                 :     3506976 :       return ix86_get_ssemov (operands, 16, insn_mode, mode);
    5827                 :             : 
    5828                 :      680634 :     case MODE_DI:
    5829                 :             :       /* Handle broken assemblers that require movd instead of movq. */
    5830                 :      680634 :       if (GENERAL_REG_P (operands[0]))
    5831                 :             :         {
    5832                 :             :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5833                 :             :             return "%vmovq\t{%1, %q0|%q0, %1}";
    5834                 :             :           else
    5835                 :             :             return "%vmovd\t{%1, %q0|%q0, %1}";
    5836                 :             :         }
    5837                 :      609501 :       else if (GENERAL_REG_P (operands[1]))
    5838                 :             :         {
    5839                 :             :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5840                 :             :             return "%vmovq\t{%q1, %0|%0, %q1}";
    5841                 :             :           else
    5842                 :             :             return "%vmovd\t{%q1, %0|%0, %q1}";
    5843                 :             :         }
    5844                 :             :       else
    5845                 :      427697 :         return "%vmovq\t{%1, %0|%0, %1}";
    5846                 :             : 
    5847                 :      225052 :     case MODE_SI:
    5848                 :      225052 :       if (GENERAL_REG_P (operands[0]))
    5849                 :             :         return "%vmovd\t{%1, %k0|%k0, %1}";
    5850                 :      167961 :       else if (GENERAL_REG_P (operands[1]))
    5851                 :             :         return "%vmovd\t{%k1, %0|%0, %k1}";
    5852                 :             :       else
    5853                 :       71200 :         return "%vmovd\t{%1, %0|%0, %1}";
    5854                 :             : 
    5855                 :       57716 :     case MODE_HI:
    5856                 :       57716 :       if (GENERAL_REG_P (operands[0]))
    5857                 :             :         return "vmovw\t{%1, %k0|%k0, %1}";
    5858                 :       57682 :       else if (GENERAL_REG_P (operands[1]))
    5859                 :             :         return "vmovw\t{%k1, %0|%0, %k1}";
    5860                 :             :       else
    5861                 :       57595 :         return "vmovw\t{%1, %0|%0, %1}";
    5862                 :             : 
    5863                 :      777802 :     case MODE_DF:
    5864                 :      777802 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5865                 :             :         return "vmovsd\t{%d1, %0|%0, %d1}";
    5866                 :             :       else
    5867                 :      776794 :         return "%vmovsd\t{%1, %0|%0, %1}";
    5868                 :             : 
    5869                 :      685094 :     case MODE_SF:
    5870                 :      685094 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5871                 :             :         return "vmovss\t{%d1, %0|%0, %d1}";
    5872                 :             :       else
    5873                 :      684323 :         return "%vmovss\t{%1, %0|%0, %1}";
    5874                 :             : 
    5875                 :          99 :     case MODE_HF:
    5876                 :          99 :     case MODE_BF:
    5877                 :          99 :       if (REG_P (operands[0]) && REG_P (operands[1]))
    5878                 :             :         return "vmovsh\t{%d1, %0|%0, %d1}";
    5879                 :             :       else
    5880                 :           0 :         return "vmovsh\t{%1, %0|%0, %1}";
    5881                 :             : 
    5882                 :          36 :     case MODE_V1DF:
    5883                 :          36 :       gcc_assert (!TARGET_AVX);
    5884                 :             :       return "movlpd\t{%1, %0|%0, %1}";
    5885                 :             : 
    5886                 :        3646 :     case MODE_V2SF:
    5887                 :        3646 :       if (TARGET_AVX && REG_P (operands[0]))
    5888                 :             :         return "vmovlps\t{%1, %d0|%d0, %1}";
    5889                 :             :       else
    5890                 :        3567 :         return "%vmovlps\t{%1, %0|%0, %1}";
    5891                 :             : 
    5892                 :           0 :     default:
    5893                 :           0 :       gcc_unreachable ();
    5894                 :             :     }
    5895                 :             : }
    5896                 :             : 
    5897                 :             : /* Returns true if OP contains a symbol reference */
    5898                 :             : 
    5899                 :             : bool
    5900                 :   525788278 : symbolic_reference_mentioned_p (rtx op)
    5901                 :             : {
    5902                 :   525788278 :   const char *fmt;
    5903                 :   525788278 :   int i;
    5904                 :             : 
    5905                 :   525788278 :   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
    5906                 :             :     return true;
    5907                 :             : 
    5908                 :   397702154 :   fmt = GET_RTX_FORMAT (GET_CODE (op));
    5909                 :   675797410 :   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
    5910                 :             :     {
    5911                 :   538905130 :       if (fmt[i] == 'E')
    5912                 :             :         {
    5913                 :     1953555 :           int j;
    5914                 :             : 
    5915                 :     3899525 :           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
    5916                 :     3223730 :             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
    5917                 :             :               return true;
    5918                 :             :         }
    5919                 :             : 
    5920                 :   536951575 :       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
    5921                 :             :         return true;
    5922                 :             :     }
    5923                 :             : 
    5924                 :             :   return false;
    5925                 :             : }
    5926                 :             : 
    5927                 :             : /* Return true if it is appropriate to emit `ret' instructions in the
    5928                 :             :    body of a function.  Do this only if the epilogue is simple, needing a
    5929                 :             :    couple of insns.  Prior to reloading, we can't tell how many registers
    5930                 :             :    must be saved, so return false then.  Return false if there is no frame
    5931                 :             :    marker to de-allocate.  */
    5932                 :             : 
    5933                 :             : bool
    5934                 :           0 : ix86_can_use_return_insn_p (void)
    5935                 :             : {
    5936                 :           0 :   if (ix86_function_ms_hook_prologue (current_function_decl))
    5937                 :             :     return false;
    5938                 :             : 
    5939                 :           0 :   if (ix86_function_naked (current_function_decl))
    5940                 :             :     return false;
    5941                 :             : 
    5942                 :             :   /* Don't use `ret' instruction in interrupt handler.  */
    5943                 :           0 :   if (! reload_completed
    5944                 :           0 :       || frame_pointer_needed
    5945                 :           0 :       || cfun->machine->func_type != TYPE_NORMAL)
    5946                 :             :     return 0;
    5947                 :             : 
    5948                 :             :   /* Don't allow more than 32k pop, since that's all we can do
    5949                 :             :      with one instruction.  */
    5950                 :           0 :   if (crtl->args.pops_args && crtl->args.size >= 32768)
    5951                 :             :     return 0;
    5952                 :             : 
    5953                 :           0 :   struct ix86_frame &frame = cfun->machine->frame;
    5954                 :           0 :   return (frame.stack_pointer_offset == UNITS_PER_WORD
    5955                 :           0 :           && (frame.nregs + frame.nsseregs) == 0);
    5956                 :             : }
    5957                 :             : 
    5958                 :             : /* Return stack frame size.  get_frame_size () returns used stack slots
    5959                 :             :    during compilation, which may be optimized out later.  If stack frame
    5960                 :             :    is needed, stack_frame_required should be true.  */
    5961                 :             : 
    5962                 :             : static HOST_WIDE_INT
    5963                 :     7976780 : ix86_get_frame_size (void)
    5964                 :             : {
    5965                 :     7976780 :   if (cfun->machine->stack_frame_required)
    5966                 :     7906125 :     return get_frame_size ();
    5967                 :             :   else
    5968                 :             :     return 0;
    5969                 :             : }
    5970                 :             : 
    5971                 :             : /* Value should be nonzero if functions must have frame pointers.
    5972                 :             :    Zero means the frame pointer need not be set up (and parms may
    5973                 :             :    be accessed via the stack pointer) in functions that seem suitable.  */
    5974                 :             : 
    5975                 :             : static bool
    5976                 :     1179789 : ix86_frame_pointer_required (void)
    5977                 :             : {
    5978                 :             :   /* If we accessed previous frames, then the generated code expects
    5979                 :             :      to be able to access the saved ebp value in our frame.  */
    5980                 :     1179789 :   if (cfun->machine->accesses_prev_frame)
    5981                 :             :     return true;
    5982                 :             : 
    5983                 :             :   /* Several x86 os'es need a frame pointer for other reasons,
    5984                 :             :      usually pertaining to setjmp.  */
    5985                 :     1179756 :   if (SUBTARGET_FRAME_POINTER_REQUIRED)
    5986                 :             :     return true;
    5987                 :             : 
    5988                 :             :   /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
    5989                 :     1179756 :   if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
    5990                 :             :     return true;
    5991                 :             : 
    5992                 :             :   /* Win64 SEH, very large frames need a frame-pointer as maximum stack
    5993                 :             :      allocation is 4GB.  */
    5994                 :     1179756 :   if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
    5995                 :             :     return true;
    5996                 :             : 
    5997                 :             :   /* SSE saves require frame-pointer when stack is misaligned.  */
    5998                 :     1179756 :   if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
    5999                 :             :     return true;
    6000                 :             : 
    6001                 :             :   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
    6002                 :             :      turns off the frame pointer by default.  Turn it back on now if
    6003                 :             :      we've not got a leaf function.  */
    6004                 :     1179755 :   if (TARGET_OMIT_LEAF_FRAME_POINTER
    6005                 :     1179755 :       && (!crtl->is_leaf
    6006                 :           0 :           || ix86_current_function_calls_tls_descriptor))
    6007                 :           0 :     return true;
    6008                 :             : 
    6009                 :             :   /* Several versions of mcount for the x86 assumes that there is a
    6010                 :             :      frame, so we cannot allow profiling without a frame pointer.  */
    6011                 :     1179755 :   if (crtl->profile && !flag_fentry)
    6012                 :             :     return true;
    6013                 :             : 
    6014                 :             :   return false;
    6015                 :             : }
    6016                 :             : 
    6017                 :             : /* Record that the current function accesses previous call frames.  */
    6018                 :             : 
    6019                 :             : void
    6020                 :         966 : ix86_setup_frame_addresses (void)
    6021                 :             : {
    6022                 :         966 :   cfun->machine->accesses_prev_frame = 1;
    6023                 :         966 : }
    6024                 :             : 
    6025                 :             : #if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
    6026                 :             : # define USE_HIDDEN_LINKONCE 1
    6027                 :             : #else
    6028                 :             : # define USE_HIDDEN_LINKONCE 0
    6029                 :             : #endif
    6030                 :             : 
    6031                 :             : /* Label count for call and return thunks.  It is used to make unique
    6032                 :             :    labels in call and return thunks.  */
    6033                 :             : static int indirectlabelno;
    6034                 :             : 
    6035                 :             : /* True if call thunk function is needed.  */
    6036                 :             : static bool indirect_thunk_needed = false;
    6037                 :             : 
    6038                 :             : /* Bit masks of integer registers, which contain branch target, used
    6039                 :             :    by call thunk functions.  */
    6040                 :             : static HARD_REG_SET indirect_thunks_used;
    6041                 :             : 
    6042                 :             : /* True if return thunk function is needed.  */
    6043                 :             : static bool indirect_return_needed = false;
    6044                 :             : 
    6045                 :             : /* True if return thunk function via CX is needed.  */
    6046                 :             : static bool indirect_return_via_cx;
    6047                 :             : 
    6048                 :             : #ifndef INDIRECT_LABEL
    6049                 :             : # define INDIRECT_LABEL "LIND"
    6050                 :             : #endif
    6051                 :             : 
    6052                 :             : /* Indicate what prefix is needed for an indirect branch.  */
    6053                 :             : enum indirect_thunk_prefix
    6054                 :             : {
    6055                 :             :   indirect_thunk_prefix_none,
    6056                 :             :   indirect_thunk_prefix_nt
    6057                 :             : };
    6058                 :             : 
    6059                 :             : /* Return the prefix needed for an indirect branch INSN.  */
    6060                 :             : 
    6061                 :             : enum indirect_thunk_prefix
    6062                 :          67 : indirect_thunk_need_prefix (rtx_insn *insn)
    6063                 :             : {
    6064                 :          67 :   enum indirect_thunk_prefix need_prefix;
    6065                 :          67 :   if ((cfun->machine->indirect_branch_type
    6066                 :          67 :             == indirect_branch_thunk_extern)
    6067                 :          67 :            && ix86_notrack_prefixed_insn_p (insn))
    6068                 :             :     {
    6069                 :             :       /* NOTRACK prefix is only used with external thunk so that it
    6070                 :             :          can be properly updated to support CET at run-time.  */
    6071                 :             :       need_prefix = indirect_thunk_prefix_nt;
    6072                 :             :     }
    6073                 :             :   else
    6074                 :             :     need_prefix = indirect_thunk_prefix_none;
    6075                 :          67 :   return need_prefix;
    6076                 :             : }
    6077                 :             : 
    6078                 :             : /* Fills in the label name that should be used for the indirect thunk.  */
    6079                 :             : 
    6080                 :             : static void
    6081                 :          73 : indirect_thunk_name (char name[32], unsigned int regno,
    6082                 :             :                      enum indirect_thunk_prefix need_prefix,
    6083                 :             :                      bool ret_p)
    6084                 :             : {
    6085                 :          73 :   if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
    6086                 :           0 :     gcc_unreachable ();
    6087                 :             : 
    6088                 :          73 :   if (USE_HIDDEN_LINKONCE)
    6089                 :             :     {
    6090                 :          73 :       const char *prefix;
    6091                 :             : 
    6092                 :          73 :       if (need_prefix == indirect_thunk_prefix_nt
    6093                 :          73 :           && regno != INVALID_REGNUM)
    6094                 :             :         {
    6095                 :             :           /* NOTRACK prefix is only used with external thunk via
    6096                 :             :              register so that NOTRACK prefix can be added to indirect
    6097                 :             :              branch via register to support CET at run-time.  */
    6098                 :             :           prefix = "_nt";
    6099                 :             :         }
    6100                 :             :       else
    6101                 :          71 :         prefix = "";
    6102                 :             : 
    6103                 :          73 :       const char *ret = ret_p ? "return" : "indirect";
    6104                 :             : 
    6105                 :          73 :       if (regno != INVALID_REGNUM)
    6106                 :             :         {
    6107                 :          55 :           const char *reg_prefix;
    6108                 :          55 :           if (LEGACY_INT_REGNO_P (regno))
    6109                 :          53 :             reg_prefix = TARGET_64BIT ? "r" : "e";
    6110                 :             :           else
    6111                 :             :             reg_prefix = "";
    6112                 :          55 :           sprintf (name, "__x86_%s_thunk%s_%s%s",
    6113                 :             :                    ret, prefix, reg_prefix, reg_names[regno]);
    6114                 :             :         }
    6115                 :             :       else
    6116                 :          18 :         sprintf (name, "__x86_%s_thunk%s", ret, prefix);
    6117                 :             :     }
    6118                 :             :   else
    6119                 :             :     {
    6120                 :             :       if (regno != INVALID_REGNUM)
    6121                 :             :         ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
    6122                 :             :       else
    6123                 :             :         {
    6124                 :             :           if (ret_p)
    6125                 :             :             ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
    6126                 :             :           else
    6127                 :          73 :             ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
    6128                 :             :         }
    6129                 :             :     }
    6130                 :          73 : }
    6131                 :             : 
    6132                 :             : /* Output a call and return thunk for indirect branch.  If REGNO != -1,
    6133                 :             :    the function address is in REGNO and the call and return thunk looks like:
    6134                 :             : 
    6135                 :             :         call    L2
    6136                 :             :    L1:
    6137                 :             :         pause
    6138                 :             :         lfence
    6139                 :             :         jmp     L1
    6140                 :             :    L2:
    6141                 :             :         mov     %REG, (%sp)
    6142                 :             :         ret
    6143                 :             : 
    6144                 :             :    Otherwise, the function address is on the top of stack and the
    6145                 :             :    call and return thunk looks like:
    6146                 :             : 
    6147                 :             :         call L2
    6148                 :             :   L1:
    6149                 :             :         pause
    6150                 :             :         lfence
    6151                 :             :         jmp L1
    6152                 :             :   L2:
    6153                 :             :         lea WORD_SIZE(%sp), %sp
    6154                 :             :         ret
    6155                 :             :  */
    6156                 :             : 
    6157                 :             : static void
    6158                 :          38 : output_indirect_thunk (unsigned int regno)
    6159                 :             : {
    6160                 :          38 :   char indirectlabel1[32];
    6161                 :          38 :   char indirectlabel2[32];
    6162                 :             : 
    6163                 :          38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
    6164                 :             :                                indirectlabelno++);
    6165                 :          38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
    6166                 :             :                                indirectlabelno++);
    6167                 :             : 
    6168                 :             :   /* Call */
    6169                 :          38 :   fputs ("\tcall\t", asm_out_file);
    6170                 :          38 :   assemble_name_raw (asm_out_file, indirectlabel2);
    6171                 :          38 :   fputc ('\n', asm_out_file);
    6172                 :             : 
    6173                 :          38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
    6174                 :             : 
    6175                 :             :   /* AMD and Intel CPUs prefer each a different instruction as loop filler.
    6176                 :             :      Usage of both pause + lfence is compromise solution.  */
    6177                 :          38 :   fprintf (asm_out_file, "\tpause\n\tlfence\n");
    6178                 :             : 
    6179                 :             :   /* Jump.  */
    6180                 :          38 :   fputs ("\tjmp\t", asm_out_file);
    6181                 :          38 :   assemble_name_raw (asm_out_file, indirectlabel1);
    6182                 :          38 :   fputc ('\n', asm_out_file);
    6183                 :             : 
    6184                 :          38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
    6185                 :             : 
    6186                 :             :   /* The above call insn pushed a word to stack.  Adjust CFI info.  */
    6187                 :          38 :   if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
    6188                 :             :     {
    6189                 :          38 :       if (! dwarf2out_do_cfi_asm ())
    6190                 :             :         {
    6191                 :           0 :           dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6192                 :           0 :           xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
    6193                 :           0 :           xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
    6194                 :           0 :           vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6195                 :             :         }
    6196                 :          38 :       dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6197                 :          38 :       xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
    6198                 :          38 :       xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
    6199                 :          38 :       vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6200                 :          38 :       dwarf2out_emit_cfi (xcfi);
    6201                 :             :     }
    6202                 :             : 
    6203                 :          38 :   if (regno != INVALID_REGNUM)
    6204                 :             :     {
    6205                 :             :       /* MOV.  */
    6206                 :          27 :       rtx xops[2];
    6207                 :          27 :       xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
    6208                 :          27 :       xops[1] = gen_rtx_REG (word_mode, regno);
    6209                 :          27 :       output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
    6210                 :             :     }
    6211                 :             :   else
    6212                 :             :     {
    6213                 :             :       /* LEA.  */
    6214                 :          11 :       rtx xops[2];
    6215                 :          11 :       xops[0] = stack_pointer_rtx;
    6216                 :          11 :       xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    6217                 :          11 :       output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
    6218                 :             :     }
    6219                 :             : 
    6220                 :          38 :   fputs ("\tret\n", asm_out_file);
    6221                 :          38 :   if ((ix86_harden_sls & harden_sls_return))
    6222                 :           1 :     fputs ("\tint3\n", asm_out_file);
    6223                 :          38 : }
    6224                 :             : 
    6225                 :             : /* Output a funtion with a call and return thunk for indirect branch.
    6226                 :             :    If REGNO != INVALID_REGNUM, the function address is in REGNO.
    6227                 :             :    Otherwise, the function address is on the top of stack.  Thunk is
    6228                 :             :    used for function return if RET_P is true.  */
    6229                 :             : 
    6230                 :             : static void
    6231                 :          22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
    6232                 :             :                                 unsigned int regno, bool ret_p)
    6233                 :             : {
    6234                 :          22 :   char name[32];
    6235                 :          22 :   tree decl;
    6236                 :             : 
    6237                 :             :   /* Create __x86_indirect_thunk.  */
    6238                 :          22 :   indirect_thunk_name (name, regno, need_prefix, ret_p);
    6239                 :          22 :   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6240                 :             :                      get_identifier (name),
    6241                 :             :                      build_function_type_list (void_type_node, NULL_TREE));
    6242                 :          22 :   DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6243                 :             :                                    NULL_TREE, void_type_node);
    6244                 :          22 :   TREE_PUBLIC (decl) = 1;
    6245                 :          22 :   TREE_STATIC (decl) = 1;
    6246                 :          22 :   DECL_IGNORED_P (decl) = 1;
    6247                 :             : 
    6248                 :             : #if TARGET_MACHO
    6249                 :             :   if (TARGET_MACHO)
    6250                 :             :     {
    6251                 :             :       switch_to_section (darwin_sections[picbase_thunk_section]);
    6252                 :             :       fputs ("\t.weak_definition\t", asm_out_file);
    6253                 :             :       assemble_name (asm_out_file, name);
    6254                 :             :       fputs ("\n\t.private_extern\t", asm_out_file);
    6255                 :             :       assemble_name (asm_out_file, name);
    6256                 :             :       putc ('\n', asm_out_file);
    6257                 :             :       ASM_OUTPUT_LABEL (asm_out_file, name);
    6258                 :             :       DECL_WEAK (decl) = 1;
    6259                 :             :     }
    6260                 :             :   else
    6261                 :             : #endif
    6262                 :          22 :     if (USE_HIDDEN_LINKONCE)
    6263                 :             :       {
    6264                 :          22 :         cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6265                 :             : 
    6266                 :          22 :         targetm.asm_out.unique_section (decl, 0);
    6267                 :          22 :         switch_to_section (get_named_section (decl, NULL, 0));
    6268                 :             : 
    6269                 :          22 :         targetm.asm_out.globalize_label (asm_out_file, name);
    6270                 :          22 :         fputs ("\t.hidden\t", asm_out_file);
    6271                 :          22 :         assemble_name (asm_out_file, name);
    6272                 :          22 :         putc ('\n', asm_out_file);
    6273                 :          22 :         ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6274                 :             :       }
    6275                 :             :     else
    6276                 :             :       {
    6277                 :             :         switch_to_section (text_section);
    6278                 :          22 :         ASM_OUTPUT_LABEL (asm_out_file, name);
    6279                 :             :       }
    6280                 :             : 
    6281                 :          22 :   DECL_INITIAL (decl) = make_node (BLOCK);
    6282                 :          22 :   current_function_decl = decl;
    6283                 :          22 :   allocate_struct_function (decl, false);
    6284                 :          22 :   init_function_start (decl);
    6285                 :             :   /* We're about to hide the function body from callees of final_* by
    6286                 :             :      emitting it directly; tell them we're a thunk, if they care.  */
    6287                 :          22 :   cfun->is_thunk = true;
    6288                 :          22 :   first_function_block_is_cold = false;
    6289                 :             :   /* Make sure unwind info is emitted for the thunk if needed.  */
    6290                 :          22 :   final_start_function (emit_barrier (), asm_out_file, 1);
    6291                 :             : 
    6292                 :          22 :   output_indirect_thunk (regno);
    6293                 :             : 
    6294                 :          22 :   final_end_function ();
    6295                 :          22 :   init_insn_lengths ();
    6296                 :          22 :   free_after_compilation (cfun);
    6297                 :          22 :   set_cfun (NULL);
    6298                 :          22 :   current_function_decl = NULL;
    6299                 :          22 : }
    6300                 :             : 
    6301                 :             : static int pic_labels_used;
    6302                 :             : 
    6303                 :             : /* Fills in the label name that should be used for a pc thunk for
    6304                 :             :    the given register.  */
    6305                 :             : 
    6306                 :             : static void
    6307                 :       36596 : get_pc_thunk_name (char name[32], unsigned int regno)
    6308                 :             : {
    6309                 :       36596 :   gcc_assert (!TARGET_64BIT);
    6310                 :             : 
    6311                 :       36596 :   if (USE_HIDDEN_LINKONCE)
    6312                 :       36596 :     sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
    6313                 :             :   else
    6314                 :       36596 :     ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
    6315                 :       36596 : }
    6316                 :             : 
    6317                 :             : 
    6318                 :             : /* This function generates code for -fpic that loads %ebx with
    6319                 :             :    the return address of the caller and then returns.  */
    6320                 :             : 
    6321                 :             : static void
    6322                 :      226834 : ix86_code_end (void)
    6323                 :             : {
    6324                 :      226834 :   rtx xops[2];
    6325                 :      226834 :   unsigned int regno;
    6326                 :             : 
    6327                 :      226834 :   if (indirect_return_needed)
    6328                 :           6 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6329                 :             :                                     INVALID_REGNUM, true);
    6330                 :      226834 :   if (indirect_return_via_cx)
    6331                 :           0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6332                 :             :                                     CX_REG, true);
    6333                 :      226834 :   if (indirect_thunk_needed)
    6334                 :           0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6335                 :             :                                     INVALID_REGNUM, false);
    6336                 :             : 
    6337                 :     2041506 :   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
    6338                 :             :     {
    6339                 :     1814672 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6340                 :           0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6341                 :             :                                         regno, false);
    6342                 :             :     }
    6343                 :             : 
    6344                 :     3856178 :   for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
    6345                 :             :     {
    6346                 :     3629344 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6347                 :           0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6348                 :             :                                         regno, false);
    6349                 :             :     }
    6350                 :             : 
    6351                 :     2041506 :   for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
    6352                 :             :     {
    6353                 :     1814672 :       char name[32];
    6354                 :     1814672 :       tree decl;
    6355                 :             : 
    6356                 :     1814672 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6357                 :          16 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6358                 :             :                                         regno, false);
    6359                 :             : 
    6360                 :     1814672 :       if (!(pic_labels_used & (1 << regno)))
    6361                 :     1811141 :         continue;
    6362                 :             : 
    6363                 :        3531 :       get_pc_thunk_name (name, regno);
    6364                 :             : 
    6365                 :        3531 :       decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6366                 :             :                          get_identifier (name),
    6367                 :             :                          build_function_type_list (void_type_node, NULL_TREE));
    6368                 :        3531 :       DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6369                 :             :                                        NULL_TREE, void_type_node);
    6370                 :        3531 :       TREE_PUBLIC (decl) = 1;
    6371                 :        3531 :       TREE_STATIC (decl) = 1;
    6372                 :        3531 :       DECL_IGNORED_P (decl) = 1;
    6373                 :             : 
    6374                 :             : #if TARGET_MACHO
    6375                 :             :       if (TARGET_MACHO)
    6376                 :             :         {
    6377                 :             :           switch_to_section (darwin_sections[picbase_thunk_section]);
    6378                 :             :           fputs ("\t.weak_definition\t", asm_out_file);
    6379                 :             :           assemble_name (asm_out_file, name);
    6380                 :             :           fputs ("\n\t.private_extern\t", asm_out_file);
    6381                 :             :           assemble_name (asm_out_file, name);
    6382                 :             :           putc ('\n', asm_out_file);
    6383                 :             :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6384                 :             :           DECL_WEAK (decl) = 1;
    6385                 :             :         }
    6386                 :             :       else
    6387                 :             : #endif
    6388                 :        3531 :       if (USE_HIDDEN_LINKONCE)
    6389                 :             :         {
    6390                 :        3531 :           cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6391                 :             : 
    6392                 :        3531 :           targetm.asm_out.unique_section (decl, 0);
    6393                 :        3531 :           switch_to_section (get_named_section (decl, NULL, 0));
    6394                 :             : 
    6395                 :        3531 :           targetm.asm_out.globalize_label (asm_out_file, name);
    6396                 :        3531 :           fputs ("\t.hidden\t", asm_out_file);
    6397                 :        3531 :           assemble_name (asm_out_file, name);
    6398                 :        3531 :           putc ('\n', asm_out_file);
    6399                 :        3531 :           ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6400                 :             :         }
    6401                 :             :       else
    6402                 :             :         {
    6403                 :             :           switch_to_section (text_section);
    6404                 :        3531 :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6405                 :             :         }
    6406                 :             : 
    6407                 :        3531 :       DECL_INITIAL (decl) = make_node (BLOCK);
    6408                 :        3531 :       current_function_decl = decl;
    6409                 :        3531 :       allocate_struct_function (decl, false);
    6410                 :        3531 :       init_function_start (decl);
    6411                 :             :       /* We're about to hide the function body from callees of final_* by
    6412                 :             :          emitting it directly; tell them we're a thunk, if they care.  */
    6413                 :        3531 :       cfun->is_thunk = true;
    6414                 :        3531 :       first_function_block_is_cold = false;
    6415                 :             :       /* Make sure unwind info is emitted for the thunk if needed.  */
    6416                 :        3531 :       final_start_function (emit_barrier (), asm_out_file, 1);
    6417                 :             : 
    6418                 :             :       /* Pad stack IP move with 4 instructions (two NOPs count
    6419                 :             :          as one instruction).  */
    6420                 :        3531 :       if (TARGET_PAD_SHORT_FUNCTION)
    6421                 :             :         {
    6422                 :             :           int i = 8;
    6423                 :             : 
    6424                 :           0 :           while (i--)
    6425                 :           0 :             fputs ("\tnop\n", asm_out_file);
    6426                 :             :         }
    6427                 :             : 
    6428                 :        3531 :       xops[0] = gen_rtx_REG (Pmode, regno);
    6429                 :        3531 :       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
    6430                 :        3531 :       output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
    6431                 :        3531 :       fputs ("\tret\n", asm_out_file);
    6432                 :        3531 :       final_end_function ();
    6433                 :        3531 :       init_insn_lengths ();
    6434                 :        3531 :       free_after_compilation (cfun);
    6435                 :        3531 :       set_cfun (NULL);
    6436                 :        3531 :       current_function_decl = NULL;
    6437                 :             :     }
    6438                 :             : 
    6439                 :      226834 :   if (flag_split_stack)
    6440                 :        4713 :     file_end_indicate_split_stack ();
    6441                 :      226834 : }
    6442                 :             : 
    6443                 :             : /* Emit code for the SET_GOT patterns.  */
    6444                 :             : 
    6445                 :             : const char *
    6446                 :       33065 : output_set_got (rtx dest, rtx label)
    6447                 :             : {
    6448                 :       33065 :   rtx xops[3];
    6449                 :             : 
    6450                 :       33065 :   xops[0] = dest;
    6451                 :             : 
    6452                 :       33065 :   if (TARGET_VXWORKS_RTP && flag_pic)
    6453                 :             :     {
    6454                 :             :       /* Load (*VXWORKS_GOTT_BASE) into the PIC register.  */
    6455                 :             :       xops[2] = gen_rtx_MEM (Pmode,
    6456                 :             :                              gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
    6457                 :             :       output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
    6458                 :             : 
    6459                 :             :       /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
    6460                 :             :          Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
    6461                 :             :          an unadorned address.  */
    6462                 :             :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
    6463                 :             :       SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
    6464                 :             :       output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
    6465                 :             :       return "";
    6466                 :             :     }
    6467                 :             : 
    6468                 :       33065 :   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
    6469                 :             : 
    6470                 :       33065 :   if (flag_pic)
    6471                 :             :     {
    6472                 :       33065 :       char name[32];
    6473                 :       33065 :       get_pc_thunk_name (name, REGNO (dest));
    6474                 :       33065 :       pic_labels_used |= 1 << REGNO (dest);
    6475                 :             : 
    6476                 :       33065 :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
    6477                 :       33065 :       xops[2] = gen_rtx_MEM (QImode, xops[2]);
    6478                 :       33065 :       output_asm_insn ("%!call\t%X2", xops);
    6479                 :             : 
    6480                 :             : #if TARGET_MACHO
    6481                 :             :       /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
    6482                 :             :          This is what will be referenced by the Mach-O PIC subsystem.  */
    6483                 :             :       if (machopic_should_output_picbase_label () || !label)
    6484                 :             :         ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
    6485                 :             : 
    6486                 :             :       /* When we are restoring the pic base at the site of a nonlocal label,
    6487                 :             :          and we decided to emit the pic base above, we will still output a
    6488                 :             :          local label used for calculating the correction offset (even though
    6489                 :             :          the offset will be 0 in that case).  */
    6490                 :             :       if (label)
    6491                 :             :         targetm.asm_out.internal_label (asm_out_file, "L",
    6492                 :             :                                            CODE_LABEL_NUMBER (label));
    6493                 :             : #endif
    6494                 :             :     }
    6495                 :             :   else
    6496                 :             :     {
    6497                 :           0 :       if (TARGET_MACHO)
    6498                 :             :         /* We don't need a pic base, we're not producing pic.  */
    6499                 :             :         gcc_unreachable ();
    6500                 :             : 
    6501                 :           0 :       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
    6502                 :           0 :       output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
    6503                 :           0 :       targetm.asm_out.internal_label (asm_out_file, "L",
    6504                 :           0 :                                       CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
    6505                 :             :     }
    6506                 :             : 
    6507                 :       33065 :   if (!TARGET_MACHO)
    6508                 :       33065 :     output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
    6509                 :             : 
    6510                 :       33065 :   return "";
    6511                 :             : }
    6512                 :             : 
    6513                 :             : /* Generate an "push" pattern for input ARG.  */
    6514                 :             : 
    6515                 :             : rtx
    6516                 :     1829893 : gen_push (rtx arg, bool ppx_p)
    6517                 :             : {
    6518                 :     1829893 :   struct machine_function *m = cfun->machine;
    6519                 :             : 
    6520                 :     1829893 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6521                 :     1566775 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6522                 :     1829893 :   m->fs.sp_offset += UNITS_PER_WORD;
    6523                 :             : 
    6524                 :     1829893 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6525                 :          36 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6526                 :             : 
    6527                 :     1829893 :   rtx stack = gen_rtx_MEM (word_mode,
    6528                 :     1829893 :                            gen_rtx_PRE_DEC (Pmode,
    6529                 :             :                                             stack_pointer_rtx));
    6530                 :     3659772 :   return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
    6531                 :             : }
    6532                 :             : 
    6533                 :             : rtx
    6534                 :          23 : gen_pushfl (void)
    6535                 :             : {
    6536                 :          23 :   struct machine_function *m = cfun->machine;
    6537                 :          23 :   rtx flags, mem;
    6538                 :             : 
    6539                 :          23 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6540                 :           0 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6541                 :          23 :   m->fs.sp_offset += UNITS_PER_WORD;
    6542                 :             : 
    6543                 :          23 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6544                 :             : 
    6545                 :          23 :   mem = gen_rtx_MEM (word_mode,
    6546                 :          23 :                      gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
    6547                 :             : 
    6548                 :          23 :   return gen_pushfl2 (word_mode, mem, flags);
    6549                 :             : }
    6550                 :             : 
    6551                 :             : /* Generate an "pop" pattern for input ARG.  */
    6552                 :             : 
    6553                 :             : rtx
    6554                 :     1445289 : gen_pop (rtx arg, bool ppx_p)
    6555                 :             : {
    6556                 :     1445289 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6557                 :          32 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6558                 :             : 
    6559                 :     1445289 :   rtx stack = gen_rtx_MEM (word_mode,
    6560                 :     1445289 :                            gen_rtx_POST_INC (Pmode,
    6561                 :             :                                              stack_pointer_rtx));
    6562                 :             : 
    6563                 :     2890564 :   return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
    6564                 :             : }
    6565                 :             : 
    6566                 :             : rtx
    6567                 :          21 : gen_popfl (void)
    6568                 :             : {
    6569                 :          21 :   rtx flags, mem;
    6570                 :             : 
    6571                 :          21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6572                 :             : 
    6573                 :          21 :   mem = gen_rtx_MEM (word_mode,
    6574                 :          21 :                      gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
    6575                 :             : 
    6576                 :          21 :   return gen_popfl1 (word_mode, flags, mem);
    6577                 :             : }
    6578                 :             : 
    6579                 :             : /* Generate a "push2" pattern for input ARG.  */
    6580                 :             : rtx
    6581                 :          17 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
    6582                 :             : {
    6583                 :          17 :   struct machine_function *m = cfun->machine;
    6584                 :          17 :   const int offset = UNITS_PER_WORD * 2;
    6585                 :             : 
    6586                 :          17 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6587                 :          12 :     m->fs.cfa_offset += offset;
    6588                 :          17 :   m->fs.sp_offset += offset;
    6589                 :             : 
    6590                 :          17 :   if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
    6591                 :           0 :     reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
    6592                 :             : 
    6593                 :          17 :   if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
    6594                 :           0 :     reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
    6595                 :             : 
    6596                 :          17 :   return ppx_p ? gen_push2p_di (mem, reg1, reg2)
    6597                 :           4 :                : gen_push2_di (mem, reg1, reg2);
    6598                 :             : }
    6599                 :             : 
    6600                 :             : /* Return >= 0 if there is an unused call-clobbered register available
    6601                 :             :    for the entire function.  */
    6602                 :             : 
    6603                 :             : static unsigned int
    6604                 :           0 : ix86_select_alt_pic_regnum (void)
    6605                 :             : {
    6606                 :           0 :   if (ix86_use_pseudo_pic_reg ())
    6607                 :             :     return INVALID_REGNUM;
    6608                 :             : 
    6609                 :           0 :   if (crtl->is_leaf
    6610                 :           0 :       && !crtl->profile
    6611                 :           0 :       && !ix86_current_function_calls_tls_descriptor)
    6612                 :             :     {
    6613                 :           0 :       int i, drap;
    6614                 :             :       /* Can't use the same register for both PIC and DRAP.  */
    6615                 :           0 :       if (crtl->drap_reg)
    6616                 :           0 :         drap = REGNO (crtl->drap_reg);
    6617                 :             :       else
    6618                 :             :         drap = -1;
    6619                 :           0 :       for (i = 2; i >= 0; --i)
    6620                 :           0 :         if (i != drap && !df_regs_ever_live_p (i))
    6621                 :             :           return i;
    6622                 :             :     }
    6623                 :             : 
    6624                 :             :   return INVALID_REGNUM;
    6625                 :             : }
    6626                 :             : 
    6627                 :             : /* Return true if REGNO is used by the epilogue.  */
    6628                 :             : 
    6629                 :             : bool
    6630                 :  1543761126 : ix86_epilogue_uses (int regno)
    6631                 :             : {
    6632                 :             :   /* If there are no caller-saved registers, we preserve all registers,
    6633                 :             :      except for MMX and x87 registers which aren't supported when saving
    6634                 :             :      and restoring registers.  Don't explicitly save SP register since
    6635                 :             :      it is always preserved.  */
    6636                 :  1543761126 :   return (epilogue_completed
    6637                 :   254384813 :           && (cfun->machine->call_saved_registers
    6638                 :   254384813 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    6639                 :       24840 :           && !fixed_regs[regno]
    6640                 :        4114 :           && !STACK_REGNO_P (regno)
    6641                 :  1543765240 :           && !MMX_REGNO_P (regno));
    6642                 :             : }
    6643                 :             : 
    6644                 :             : /* Return nonzero if register REGNO can be used as a scratch register
    6645                 :             :    in peephole2.  */
    6646                 :             : 
    6647                 :             : static bool
    6648                 :     1167025 : ix86_hard_regno_scratch_ok (unsigned int regno)
    6649                 :             : {
    6650                 :             :   /* If there are no caller-saved registers, we can't use any register
    6651                 :             :      as a scratch register after epilogue and use REGNO as scratch
    6652                 :             :      register only if it has been used before to avoid saving and
    6653                 :             :      restoring it.  */
    6654                 :     1167025 :   return ((cfun->machine->call_saved_registers
    6655                 :     1167025 :            != TYPE_NO_CALLER_SAVED_REGISTERS)
    6656                 :     1167025 :           || (!epilogue_completed
    6657                 :           0 :               && df_regs_ever_live_p (regno)));
    6658                 :             : }
    6659                 :             : 
    6660                 :             : /* Return TRUE if we need to save REGNO.  */
    6661                 :             : 
    6662                 :             : bool
    6663                 :   318774088 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
    6664                 :             : {
    6665                 :   318774088 :   rtx reg;
    6666                 :             : 
    6667                 :   318774088 :   switch (cfun->machine->call_saved_registers)
    6668                 :             :     {
    6669                 :             :     case TYPE_DEFAULT_CALL_SAVED_REGISTERS:
    6670                 :             :       break;
    6671                 :             : 
    6672                 :       30432 :     case TYPE_NO_CALLER_SAVED_REGISTERS:
    6673                 :             :       /* If there are no caller-saved registers, we preserve all
    6674                 :             :          registers, except for MMX and x87 registers which aren't
    6675                 :             :          supported when saving and restoring registers.  Don't
    6676                 :             :          explicitly save SP register since it is always preserved.
    6677                 :             : 
    6678                 :             :          Don't preserve registers used for function return value.  */
    6679                 :       30432 :       reg = crtl->return_rtx;
    6680                 :       30432 :       if (reg)
    6681                 :             :         {
    6682                 :         448 :           unsigned int i = REGNO (reg);
    6683                 :         448 :           unsigned int nregs = REG_NREGS (reg);
    6684                 :         882 :           while (nregs-- > 0)
    6685                 :         448 :             if ((i + nregs) == regno)
    6686                 :             :               return false;
    6687                 :             :         }
    6688                 :             : 
    6689                 :       30418 :       return (df_regs_ever_live_p (regno)
    6690                 :        4835 :               && !fixed_regs[regno]
    6691                 :        3953 :               && !STACK_REGNO_P (regno)
    6692                 :        3953 :               && !MMX_REGNO_P (regno)
    6693                 :       34371 :               && (regno != HARD_FRAME_POINTER_REGNUM
    6694                 :         228 :                   || !frame_pointer_needed));
    6695                 :             : 
    6696                 :             :     case TYPE_NO_CALLEE_SAVED_REGISTERS:
    6697                 :             :       return false;
    6698                 :             : 
    6699                 :        1664 :     case TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP:
    6700                 :        1664 :       if (regno != HARD_FRAME_POINTER_REGNUM)
    6701                 :             :         return false;
    6702                 :             :       break;
    6703                 :             :     }
    6704                 :             : 
    6705                 :   350610268 :   if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
    6706                 :     9668010 :       && pic_offset_table_rtx)
    6707                 :             :     {
    6708                 :      334205 :       if (ix86_use_pseudo_pic_reg ())
    6709                 :             :         {
    6710                 :             :           /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
    6711                 :             :           _mcount in prologue.  */
    6712                 :      334205 :           if (!TARGET_64BIT && flag_pic && crtl->profile)
    6713                 :             :             return true;
    6714                 :             :         }
    6715                 :           0 :       else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
    6716                 :           0 :                || crtl->profile
    6717                 :           0 :                || crtl->calls_eh_return
    6718                 :           0 :                || crtl->uses_const_pool
    6719                 :           0 :                || cfun->has_nonlocal_label)
    6720                 :           0 :         return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
    6721                 :             :     }
    6722                 :             : 
    6723                 :   318736476 :   if (crtl->calls_eh_return && maybe_eh_return)
    6724                 :             :     {
    6725                 :             :       unsigned i;
    6726                 :       14335 :       for (i = 0; ; i++)
    6727                 :             :         {
    6728                 :       21855 :           unsigned test = EH_RETURN_DATA_REGNO (i);
    6729                 :       14805 :           if (test == INVALID_REGNUM)
    6730                 :             :             break;
    6731                 :       14805 :           if (test == regno)
    6732                 :             :             return true;
    6733                 :       14335 :         }
    6734                 :             :     }
    6735                 :             : 
    6736                 :   318736006 :   if (ignore_outlined && cfun->machine->call_ms2sysv)
    6737                 :             :     {
    6738                 :     2650688 :       unsigned count = cfun->machine->call_ms2sysv_extra_regs
    6739                 :             :                        + xlogue_layout::MIN_REGS;
    6740                 :     2650688 :       if (xlogue_layout::is_stub_managed_reg (regno, count))
    6741                 :             :         return false;
    6742                 :             :     }
    6743                 :             : 
    6744                 :   318236137 :   if (crtl->drap_reg
    6745                 :     2131034 :       && regno == REGNO (crtl->drap_reg)
    6746                 :   318289841 :       && !cfun->machine->no_drap_save_restore)
    6747                 :             :     return true;
    6748                 :             : 
    6749                 :   318182433 :   return (df_regs_ever_live_p (regno)
    6750                 :   334629344 :           && !call_used_or_fixed_reg_p (regno)
    6751                 :   334037689 :           && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
    6752                 :             : }
    6753                 :             : 
    6754                 :             : /* Return number of saved general prupose registers.  */
    6755                 :             : 
    6756                 :             : static int
    6757                 :     7899814 : ix86_nsaved_regs (void)
    6758                 :             : {
    6759                 :     7899814 :   int nregs = 0;
    6760                 :     7899814 :   int regno;
    6761                 :             : 
    6762                 :   734682702 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6763                 :   726782888 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6764                 :     7895072 :       nregs ++;
    6765                 :     7899814 :   return nregs;
    6766                 :             : }
    6767                 :             : 
    6768                 :             : /* Return number of saved SSE registers.  */
    6769                 :             : 
    6770                 :             : static int
    6771                 :     7935357 : ix86_nsaved_sseregs (void)
    6772                 :             : {
    6773                 :     7935357 :   int nregs = 0;
    6774                 :     7935357 :   int regno;
    6775                 :             : 
    6776                 :     7935357 :   if (!TARGET_64BIT_MS_ABI)
    6777                 :     7709654 :     return 0;
    6778                 :    20990379 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6779                 :    20764676 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6780                 :     1899215 :       nregs ++;
    6781                 :             :   return nregs;
    6782                 :             : }
    6783                 :             : 
    6784                 :             : /* Given FROM and TO register numbers, say whether this elimination is
    6785                 :             :    allowed.  If stack alignment is needed, we can only replace argument
    6786                 :             :    pointer with hard frame pointer, or replace frame pointer with stack
    6787                 :             :    pointer.  Otherwise, frame pointer elimination is automatically
    6788                 :             :    handled and all other eliminations are valid.  */
    6789                 :             : 
    6790                 :             : static bool
    6791                 :    46745909 : ix86_can_eliminate (const int from, const int to)
    6792                 :             : {
    6793                 :    46745909 :   if (stack_realign_fp)
    6794                 :     1749620 :     return ((from == ARG_POINTER_REGNUM
    6795                 :     1749620 :              && to == HARD_FRAME_POINTER_REGNUM)
    6796                 :     1749620 :             || (from == FRAME_POINTER_REGNUM
    6797                 :     1749620 :                 && to == STACK_POINTER_REGNUM));
    6798                 :             :   else
    6799                 :    83624032 :     return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
    6800                 :             : }
    6801                 :             : 
    6802                 :             : /* Return the offset between two registers, one to be eliminated, and the other
    6803                 :             :    its replacement, at the start of a routine.  */
    6804                 :             : 
    6805                 :             : HOST_WIDE_INT
    6806                 :   138531352 : ix86_initial_elimination_offset (int from, int to)
    6807                 :             : {
    6808                 :   138531352 :   struct ix86_frame &frame = cfun->machine->frame;
    6809                 :             : 
    6810                 :   138531352 :   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    6811                 :    10082428 :     return frame.hard_frame_pointer_offset;
    6812                 :   128448924 :   else if (from == FRAME_POINTER_REGNUM
    6813                 :   128448924 :            && to == HARD_FRAME_POINTER_REGNUM)
    6814                 :     7864008 :     return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
    6815                 :             :   else
    6816                 :             :     {
    6817                 :   120584916 :       gcc_assert (to == STACK_POINTER_REGNUM);
    6818                 :             : 
    6819                 :   120584916 :       if (from == ARG_POINTER_REGNUM)
    6820                 :   112720908 :         return frame.stack_pointer_offset;
    6821                 :             : 
    6822                 :     7864008 :       gcc_assert (from == FRAME_POINTER_REGNUM);
    6823                 :     7864008 :       return frame.stack_pointer_offset - frame.frame_pointer_offset;
    6824                 :             :     }
    6825                 :             : }
    6826                 :             : 
    6827                 :             : /* Emits a warning for unsupported msabi to sysv pro/epilogues.  */
    6828                 :             : void
    6829                 :           0 : warn_once_call_ms2sysv_xlogues (const char *feature)
    6830                 :             : {
    6831                 :           0 :   static bool warned_once = false;
    6832                 :           0 :   if (!warned_once)
    6833                 :             :     {
    6834                 :           0 :       warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
    6835                 :             :                feature);
    6836                 :           0 :       warned_once = true;
    6837                 :             :     }
    6838                 :           0 : }
    6839                 :             : 
    6840                 :             : /* Return the probing interval for -fstack-clash-protection.  */
    6841                 :             : 
    6842                 :             : static HOST_WIDE_INT
    6843                 :         351 : get_probe_interval (void)
    6844                 :             : {
    6845                 :         221 :   if (flag_stack_clash_protection)
    6846                 :         268 :     return (HOST_WIDE_INT_1U
    6847                 :         268 :             << param_stack_clash_protection_probe_interval);
    6848                 :             :   else
    6849                 :             :     return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
    6850                 :             : }
    6851                 :             : 
    6852                 :             : /* When using -fsplit-stack, the allocation routines set a field in
    6853                 :             :    the TCB to the bottom of the stack plus this much space, measured
    6854                 :             :    in bytes.  */
    6855                 :             : 
    6856                 :             : #define SPLIT_STACK_AVAILABLE 256
    6857                 :             : 
    6858                 :             : /* Return true if push2/pop2 can be generated.  */
    6859                 :             : 
    6860                 :             : static bool
    6861                 :     7900272 : ix86_can_use_push2pop2 (void)
    6862                 :             : {
    6863                 :             :   /* Use push2/pop2 only if the incoming stack is 16-byte aligned.  */
    6864                 :     7900272 :   unsigned int incoming_stack_boundary
    6865                 :     7900272 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    6866                 :     7900272 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    6867                 :     7900272 :   return incoming_stack_boundary % 128 == 0;
    6868                 :             : }
    6869                 :             : 
    6870                 :             : /* Helper function to determine whether push2/pop2 can be used in prologue or
    6871                 :             :    epilogue for register save/restore.  */
    6872                 :             : static bool
    6873                 :     7899814 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
    6874                 :             : {
    6875                 :     7899814 :   if (!ix86_can_use_push2pop2 ())
    6876                 :             :     return false;
    6877                 :     7863971 :   int aligned = cfun->machine->fs.sp_offset % 16 == 0;
    6878                 :     7863971 :   return TARGET_APX_PUSH2POP2
    6879                 :        2253 :          && !cfun->machine->frame.save_regs_using_mov
    6880                 :        2253 :          && cfun->machine->func_type == TYPE_NORMAL
    6881                 :     7866216 :          && (nregs + aligned) >= 3;
    6882                 :             : }
    6883                 :             : 
    6884                 :             : /* Fill structure ix86_frame about frame of currently computed function.  */
    6885                 :             : 
    6886                 :             : static void
    6887                 :     7899814 : ix86_compute_frame_layout (void)
    6888                 :             : {
    6889                 :     7899814 :   struct ix86_frame *frame = &cfun->machine->frame;
    6890                 :     7899814 :   struct machine_function *m = cfun->machine;
    6891                 :     7899814 :   unsigned HOST_WIDE_INT stack_alignment_needed;
    6892                 :     7899814 :   HOST_WIDE_INT offset;
    6893                 :     7899814 :   unsigned HOST_WIDE_INT preferred_alignment;
    6894                 :     7899814 :   HOST_WIDE_INT size = ix86_get_frame_size ();
    6895                 :     7899814 :   HOST_WIDE_INT to_allocate;
    6896                 :             : 
    6897                 :             :   /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
    6898                 :             :    * ms_abi functions that call a sysv function.  We now need to prune away
    6899                 :             :    * cases where it should be disabled.  */
    6900                 :     7899814 :   if (TARGET_64BIT && m->call_ms2sysv)
    6901                 :             :     {
    6902                 :       35225 :       gcc_assert (TARGET_64BIT_MS_ABI);
    6903                 :       35225 :       gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
    6904                 :       35225 :       gcc_assert (!TARGET_SEH);
    6905                 :       35225 :       gcc_assert (TARGET_SSE);
    6906                 :       35225 :       gcc_assert (!ix86_using_red_zone ());
    6907                 :             : 
    6908                 :       35225 :       if (crtl->calls_eh_return)
    6909                 :             :         {
    6910                 :           0 :           gcc_assert (!reload_completed);
    6911                 :           0 :           m->call_ms2sysv = false;
    6912                 :           0 :           warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
    6913                 :             :         }
    6914                 :             : 
    6915                 :       35225 :       else if (ix86_static_chain_on_stack)
    6916                 :             :         {
    6917                 :           0 :           gcc_assert (!reload_completed);
    6918                 :           0 :           m->call_ms2sysv = false;
    6919                 :           0 :           warn_once_call_ms2sysv_xlogues ("static call chains");
    6920                 :             :         }
    6921                 :             : 
    6922                 :             :       /* Finally, compute which registers the stub will manage.  */
    6923                 :             :       else
    6924                 :             :         {
    6925                 :       35225 :           unsigned count = xlogue_layout::count_stub_managed_regs ();
    6926                 :       35225 :           m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
    6927                 :       35225 :           m->call_ms2sysv_pad_in = 0;
    6928                 :             :         }
    6929                 :             :     }
    6930                 :             : 
    6931                 :     7899814 :   frame->nregs = ix86_nsaved_regs ();
    6932                 :     7899814 :   frame->nsseregs = ix86_nsaved_sseregs ();
    6933                 :             : 
    6934                 :             :   /* 64-bit MS ABI seem to require stack alignment to be always 16,
    6935                 :             :      except for function prologues, leaf functions and when the defult
    6936                 :             :      incoming stack boundary is overriden at command line or via
    6937                 :             :      force_align_arg_pointer attribute.
    6938                 :             : 
    6939                 :             :      Darwin's ABI specifies 128b alignment for both 32 and  64 bit variants
    6940                 :             :      at call sites, including profile function calls.
    6941                 :             : 
    6942                 :             :      For APX push2/pop2, the stack also requires 128b alignment.  */
    6943                 :     7899814 :   if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
    6944                 :          60 :        && crtl->preferred_stack_boundary < 128)
    6945                 :     7899873 :       || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
    6946                 :      225701 :            && crtl->preferred_stack_boundary < 128)
    6947                 :           0 :           && (!crtl->is_leaf || cfun->calls_alloca != 0
    6948                 :           0 :               || ix86_current_function_calls_tls_descriptor
    6949                 :           0 :               || (TARGET_MACHO && crtl->profile)
    6950                 :           0 :               || ix86_incoming_stack_boundary < 128)))
    6951                 :             :     {
    6952                 :           1 :       crtl->preferred_stack_boundary = 128;
    6953                 :           1 :       if (crtl->stack_alignment_needed < 128)
    6954                 :           0 :         crtl->stack_alignment_needed = 128;
    6955                 :             :     }
    6956                 :             : 
    6957                 :     7899814 :   stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
    6958                 :     7899814 :   preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
    6959                 :             : 
    6960                 :     7899814 :   gcc_assert (!size || stack_alignment_needed);
    6961                 :     8693275 :   gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
    6962                 :     7899814 :   gcc_assert (preferred_alignment <= stack_alignment_needed);
    6963                 :             : 
    6964                 :             :   /* The only ABI saving SSE regs should be 64-bit ms_abi.  */
    6965                 :     7899814 :   gcc_assert (TARGET_64BIT || !frame->nsseregs);
    6966                 :     7899814 :   if (TARGET_64BIT && m->call_ms2sysv)
    6967                 :             :     {
    6968                 :       35225 :       gcc_assert (stack_alignment_needed >= 16);
    6969                 :       35225 :       gcc_assert (!frame->nsseregs);
    6970                 :             :     }
    6971                 :             : 
    6972                 :             :   /* For SEH we have to limit the amount of code movement into the prologue.
    6973                 :             :      At present we do this via a BLOCKAGE, at which point there's very little
    6974                 :             :      scheduling that can be done, which means that there's very little point
    6975                 :             :      in doing anything except PUSHs.  */
    6976                 :     7899814 :   if (TARGET_SEH)
    6977                 :             :     m->use_fast_prologue_epilogue = false;
    6978                 :     7899814 :   else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    6979                 :             :     {
    6980                 :     7578371 :       int count = frame->nregs;
    6981                 :     7578371 :       struct cgraph_node *node = cgraph_node::get (current_function_decl);
    6982                 :             : 
    6983                 :             :       /* The fast prologue uses move instead of push to save registers.  This
    6984                 :             :          is significantly longer, but also executes faster as modern hardware
    6985                 :             :          can execute the moves in parallel, but can't do that for push/pop.
    6986                 :             : 
    6987                 :             :          Be careful about choosing what prologue to emit:  When function takes
    6988                 :             :          many instructions to execute we may use slow version as well as in
    6989                 :             :          case function is known to be outside hot spot (this is known with
    6990                 :             :          feedback only).  Weight the size of function by number of registers
    6991                 :             :          to save as it is cheap to use one or two push instructions but very
    6992                 :             :          slow to use many of them.
    6993                 :             : 
    6994                 :             :          Calling this hook multiple times with the same frame requirements
    6995                 :             :          must produce the same layout, since the RA might otherwise be
    6996                 :             :          unable to reach a fixed point or might fail its final sanity checks.
    6997                 :             :          This means that once we've assumed that a function does or doesn't
    6998                 :             :          have a particular size, we have to stick to that assumption
    6999                 :             :          regardless of how the function has changed since.  */
    7000                 :     7578371 :       if (count)
    7001                 :     2518542 :         count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
    7002                 :     7578371 :       if (node->frequency < NODE_FREQUENCY_NORMAL
    7003                 :     6916922 :           || (flag_branch_probabilities
    7004                 :         981 :               && node->frequency < NODE_FREQUENCY_HOT))
    7005                 :      661764 :         m->use_fast_prologue_epilogue = false;
    7006                 :             :       else
    7007                 :             :         {
    7008                 :     6916607 :           if (count != frame->expensive_count)
    7009                 :             :             {
    7010                 :      278524 :               frame->expensive_count = count;
    7011                 :      278524 :               frame->expensive_p = expensive_function_p (count);
    7012                 :             :             }
    7013                 :     6916607 :           m->use_fast_prologue_epilogue = !frame->expensive_p;
    7014                 :             :         }
    7015                 :             :     }
    7016                 :             : 
    7017                 :     7899814 :   frame->save_regs_using_mov
    7018                 :     7899814 :     = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
    7019                 :             : 
    7020                 :             :   /* Skip return address and error code in exception handler.  */
    7021                 :     7899814 :   offset = INCOMING_FRAME_SP_OFFSET;
    7022                 :             : 
    7023                 :             :   /* Skip pushed static chain.  */
    7024                 :     7899814 :   if (ix86_static_chain_on_stack)
    7025                 :           0 :     offset += UNITS_PER_WORD;
    7026                 :             : 
    7027                 :             :   /* Skip saved base pointer.  */
    7028                 :     7899814 :   if (frame_pointer_needed)
    7029                 :     2723991 :     offset += UNITS_PER_WORD;
    7030                 :     7899814 :   frame->hfp_save_offset = offset;
    7031                 :             : 
    7032                 :             :   /* The traditional frame pointer location is at the top of the frame.  */
    7033                 :     7899814 :   frame->hard_frame_pointer_offset = offset;
    7034                 :             : 
    7035                 :             :   /* Register save area */
    7036                 :     7899814 :   offset += frame->nregs * UNITS_PER_WORD;
    7037                 :     7899814 :   frame->reg_save_offset = offset;
    7038                 :             : 
    7039                 :             :   /* Calculate the size of the va-arg area (not including padding, if any).  */
    7040                 :     7899814 :   frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
    7041                 :             : 
    7042                 :             :   /* Also adjust stack_realign_offset for the largest alignment of
    7043                 :             :      stack slot actually used.  */
    7044                 :     7899814 :   if (stack_realign_fp
    7045                 :     7584447 :       || (cfun->machine->max_used_stack_alignment != 0
    7046                 :         122 :           && (offset % cfun->machine->max_used_stack_alignment) != 0))
    7047                 :             :     {
    7048                 :             :       /* We may need a 16-byte aligned stack for the remainder of the
    7049                 :             :          register save area, but the stack frame for the local function
    7050                 :             :          may require a greater alignment if using AVX/2/512.  In order
    7051                 :             :          to avoid wasting space, we first calculate the space needed for
    7052                 :             :          the rest of the register saves, add that to the stack pointer,
    7053                 :             :          and then realign the stack to the boundary of the start of the
    7054                 :             :          frame for the local function.  */
    7055                 :      315432 :       HOST_WIDE_INT space_needed = 0;
    7056                 :      315432 :       HOST_WIDE_INT sse_reg_space_needed = 0;
    7057                 :             : 
    7058                 :      315432 :       if (TARGET_64BIT)
    7059                 :             :         {
    7060                 :      313637 :           if (m->call_ms2sysv)
    7061                 :             :             {
    7062                 :        6415 :               m->call_ms2sysv_pad_in = 0;
    7063                 :        6415 :               space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
    7064                 :             :             }
    7065                 :             : 
    7066                 :      307222 :           else if (frame->nsseregs)
    7067                 :             :             /* The only ABI that has saved SSE registers (Win64) also has a
    7068                 :             :                16-byte aligned default stack.  However, many programs violate
    7069                 :             :                the ABI, and Wine64 forces stack realignment to compensate.  */
    7070                 :        6447 :             space_needed = frame->nsseregs * 16;
    7071                 :             : 
    7072                 :      313637 :           sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
    7073                 :             : 
    7074                 :             :           /* 64-bit frame->va_arg_size should always be a multiple of 16, but
    7075                 :             :              rounding to be pedantic.  */
    7076                 :      313637 :           space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
    7077                 :             :         }
    7078                 :             :       else
    7079                 :        1795 :         space_needed = frame->va_arg_size;
    7080                 :             : 
    7081                 :             :       /* Record the allocation size required prior to the realignment AND.  */
    7082                 :      315432 :       frame->stack_realign_allocate = space_needed;
    7083                 :             : 
    7084                 :             :       /* The re-aligned stack starts at frame->stack_realign_offset.  Values
    7085                 :             :          before this point are not directly comparable with values below
    7086                 :             :          this point.  Use sp_valid_at to determine if the stack pointer is
    7087                 :             :          valid for a given offset, fp_valid_at for the frame pointer, or
    7088                 :             :          choose_baseaddr to have a base register chosen for you.
    7089                 :             : 
    7090                 :             :          Note that the result of (frame->stack_realign_offset
    7091                 :             :          & (stack_alignment_needed - 1)) may not equal zero.  */
    7092                 :      315432 :       offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
    7093                 :      315432 :       frame->stack_realign_offset = offset - space_needed;
    7094                 :      315432 :       frame->sse_reg_save_offset = frame->stack_realign_offset
    7095                 :      315432 :                                                         + sse_reg_space_needed;
    7096                 :      315432 :     }
    7097                 :             :   else
    7098                 :             :     {
    7099                 :     7584382 :       frame->stack_realign_offset = offset;
    7100                 :             : 
    7101                 :     7584382 :       if (TARGET_64BIT && m->call_ms2sysv)
    7102                 :             :         {
    7103                 :       28810 :           m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
    7104                 :       28810 :           offset += xlogue_layout::get_instance ().get_stack_space_used ();
    7105                 :             :         }
    7106                 :             : 
    7107                 :             :       /* Align and set SSE register save area.  */
    7108                 :     7555572 :       else if (frame->nsseregs)
    7109                 :             :         {
    7110                 :             :           /* If the incoming stack boundary is at least 16 bytes, or DRAP is
    7111                 :             :              required and the DRAP re-alignment boundary is at least 16 bytes,
    7112                 :             :              then we want the SSE register save area properly aligned.  */
    7113                 :      183479 :           if (ix86_incoming_stack_boundary >= 128
    7114                 :        6400 :                   || (stack_realign_drap && stack_alignment_needed >= 16))
    7115                 :      183479 :             offset = ROUND_UP (offset, 16);
    7116                 :      183479 :           offset += frame->nsseregs * 16;
    7117                 :             :         }
    7118                 :     7584382 :       frame->sse_reg_save_offset = offset;
    7119                 :     7584382 :       offset += frame->va_arg_size;
    7120                 :             :     }
    7121                 :             : 
    7122                 :             :   /* Align start of frame for local function.  When a function call
    7123                 :             :      is removed, it may become a leaf function.  But if argument may
    7124                 :             :      be passed on stack, we need to align the stack when there is no
    7125                 :             :      tail call.  */
    7126                 :     7899814 :   if (m->call_ms2sysv
    7127                 :     7864589 :       || frame->va_arg_size != 0
    7128                 :     7786652 :       || size != 0
    7129                 :     4209458 :       || !crtl->is_leaf
    7130                 :     1963746 :       || (!crtl->tail_call_emit
    7131                 :     1663476 :           && cfun->machine->outgoing_args_on_stack)
    7132                 :     1963696 :       || cfun->calls_alloca
    7133                 :     9861879 :       || ix86_current_function_calls_tls_descriptor)
    7134                 :     5938156 :     offset = ROUND_UP (offset, stack_alignment_needed);
    7135                 :             : 
    7136                 :             :   /* Frame pointer points here.  */
    7137                 :     7899814 :   frame->frame_pointer_offset = offset;
    7138                 :             : 
    7139                 :     7899814 :   offset += size;
    7140                 :             : 
    7141                 :             :   /* Add outgoing arguments area.  Can be skipped if we eliminated
    7142                 :             :      all the function calls as dead code.
    7143                 :             :      Skipping is however impossible when function calls alloca.  Alloca
    7144                 :             :      expander assumes that last crtl->outgoing_args_size
    7145                 :             :      of stack frame are unused.  */
    7146                 :     7899814 :   if (ACCUMULATE_OUTGOING_ARGS
    7147                 :     8537687 :       && (!crtl->is_leaf || cfun->calls_alloca
    7148                 :      411407 :           || ix86_current_function_calls_tls_descriptor))
    7149                 :             :     {
    7150                 :      226466 :       offset += crtl->outgoing_args_size;
    7151                 :      226466 :       frame->outgoing_arguments_size = crtl->outgoing_args_size;
    7152                 :             :     }
    7153                 :             :   else
    7154                 :     7673348 :     frame->outgoing_arguments_size = 0;
    7155                 :             : 
    7156                 :             :   /* Align stack boundary.  Only needed if we're calling another function
    7157                 :             :      or using alloca.  */
    7158                 :     2672488 :   if (!crtl->is_leaf || cfun->calls_alloca
    7159                 :    10568842 :       || ix86_current_function_calls_tls_descriptor)
    7160                 :     5232579 :     offset = ROUND_UP (offset, preferred_alignment);
    7161                 :             : 
    7162                 :             :   /* We've reached end of stack frame.  */
    7163                 :     7899814 :   frame->stack_pointer_offset = offset;
    7164                 :             : 
    7165                 :             :   /* Size prologue needs to allocate.  */
    7166                 :     7899814 :   to_allocate = offset - frame->sse_reg_save_offset;
    7167                 :             : 
    7168                 :     2696351 :   if ((!to_allocate && frame->nregs <= 1)
    7169                 :     5422524 :       || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
    7170                 :             :        /* If static stack checking is enabled and done with probes,
    7171                 :             :           the registers need to be saved before allocating the frame.  */
    7172                 :     5421870 :       || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
    7173                 :             :       /* If stack clash probing needs a loop, then it needs a
    7174                 :             :          scratch register.  But the returned register is only guaranteed
    7175                 :             :          to be safe to use after register saves are complete.  So if
    7176                 :             :          stack clash protections are enabled and the allocated frame is
    7177                 :             :          larger than the probe interval, then use pushes to save
    7178                 :             :          callee saved registers.  */
    7179                 :    13321614 :       || (flag_stack_clash_protection
    7180                 :         221 :           && !ix86_target_stack_probe ()
    7181                 :         221 :           && to_allocate > get_probe_interval ()))
    7182                 :     2478103 :     frame->save_regs_using_mov = false;
    7183                 :             : 
    7184                 :     7899814 :   if (ix86_using_red_zone ()
    7185                 :     6880507 :       && crtl->sp_is_unchanging
    7186                 :     6256742 :       && crtl->is_leaf
    7187                 :     2574747 :       && !cfun->machine->asm_redzone_clobber_seen
    7188                 :     2574747 :       && !ix86_pc_thunk_call_expanded
    7189                 :    10474548 :       && !ix86_current_function_calls_tls_descriptor)
    7190                 :             :     {
    7191                 :     2574734 :       frame->red_zone_size = to_allocate;
    7192                 :     2574734 :       if (frame->save_regs_using_mov)
    7193                 :      147581 :         frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
    7194                 :     2574734 :       if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
    7195                 :      107310 :         frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
    7196                 :             :     }
    7197                 :             :   else
    7198                 :     5325080 :     frame->red_zone_size = 0;
    7199                 :     7899814 :   frame->stack_pointer_offset -= frame->red_zone_size;
    7200                 :             : 
    7201                 :             :   /* The SEH frame pointer location is near the bottom of the frame.
    7202                 :             :      This is enforced by the fact that the difference between the
    7203                 :             :      stack pointer and the frame pointer is limited to 240 bytes in
    7204                 :             :      the unwind data structure.  */
    7205                 :     7899814 :   if (TARGET_SEH)
    7206                 :             :     {
    7207                 :             :       /* Force the frame pointer to point at or below the lowest register save
    7208                 :             :          area, see the SEH code in config/i386/winnt.cc for the rationale.  */
    7209                 :             :       frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
    7210                 :             : 
    7211                 :             :       /* If we can leave the frame pointer where it is, do so; however return
    7212                 :             :          the establisher frame for __builtin_frame_address (0) or else if the
    7213                 :             :          frame overflows the SEH maximum frame size.
    7214                 :             : 
    7215                 :             :          Note that the value returned by __builtin_frame_address (0) is quite
    7216                 :             :          constrained, because setjmp is piggybacked on the SEH machinery with
    7217                 :             :          recent versions of MinGW:
    7218                 :             : 
    7219                 :             :           #    elif defined(__SEH__)
    7220                 :             :           #     if defined(__aarch64__) || defined(_ARM64_)
    7221                 :             :           #      define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
    7222                 :             :           #     elif (__MINGW_GCC_VERSION < 40702)
    7223                 :             :           #      define setjmp(BUF) _setjmp((BUF), mingw_getsp())
    7224                 :             :           #     else
    7225                 :             :           #      define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
    7226                 :             :           #     endif
    7227                 :             : 
    7228                 :             :          and the second argument passed to _setjmp, if not null, is forwarded
    7229                 :             :          to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
    7230                 :             :          built an ExceptionRecord on the fly describing the setjmp buffer).  */
    7231                 :             :       const HOST_WIDE_INT diff
    7232                 :             :         = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
    7233                 :             :       if (diff <= 255 && !crtl->accesses_prior_frames)
    7234                 :             :         {
    7235                 :             :           /* The resulting diff will be a multiple of 16 lower than 255,
    7236                 :             :              i.e. at most 240 as required by the unwind data structure.  */
    7237                 :             :           frame->hard_frame_pointer_offset += (diff & 15);
    7238                 :             :         }
    7239                 :             :       else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
    7240                 :             :         {
    7241                 :             :           /* Ideally we'd determine what portion of the local stack frame
    7242                 :             :              (within the constraint of the lowest 240) is most heavily used.
    7243                 :             :              But without that complication, simply bias the frame pointer
    7244                 :             :              by 128 bytes so as to maximize the amount of the local stack
    7245                 :             :              frame that is addressable with 8-bit offsets.  */
    7246                 :             :           frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
    7247                 :             :         }
    7248                 :             :       else
    7249                 :             :         frame->hard_frame_pointer_offset = frame->hfp_save_offset;
    7250                 :             :     }
    7251                 :     7899814 : }
    7252                 :             : 
    7253                 :             : /* This is semi-inlined memory_address_length, but simplified
    7254                 :             :    since we know that we're always dealing with reg+offset, and
    7255                 :             :    to avoid having to create and discard all that rtl.  */
    7256                 :             : 
    7257                 :             : static inline int
    7258                 :      692477 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
    7259                 :             : {
    7260                 :      692477 :   int len = 4;
    7261                 :             : 
    7262                 :           0 :   if (offset == 0)
    7263                 :             :     {
    7264                 :             :       /* EBP and R13 cannot be encoded without an offset.  */
    7265                 :           0 :       len = (regno == BP_REG || regno == R13_REG);
    7266                 :             :     }
    7267                 :      688457 :   else if (IN_RANGE (offset, -128, 127))
    7268                 :      425004 :     len = 1;
    7269                 :             : 
    7270                 :             :   /* ESP and R12 must be encoded with a SIB byte.  */
    7271                 :           0 :   if (regno == SP_REG || regno == R12_REG)
    7272                 :           0 :     len++;
    7273                 :             : 
    7274                 :      692477 :   return len;
    7275                 :             : }
    7276                 :             : 
    7277                 :             : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
    7278                 :             :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7279                 :             : 
    7280                 :             : static bool
    7281                 :     2743401 : sp_valid_at (HOST_WIDE_INT cfa_offset)
    7282                 :             : {
    7283                 :     2743401 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7284                 :     2743401 :   if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
    7285                 :             :     {
    7286                 :             :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7287                 :       47764 :       gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
    7288                 :             :       return false;
    7289                 :             :     }
    7290                 :     2695637 :   return fs.sp_valid;
    7291                 :             : }
    7292                 :             : 
    7293                 :             : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
    7294                 :             :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7295                 :             : 
    7296                 :             : static inline bool
    7297                 :      725883 : fp_valid_at (HOST_WIDE_INT cfa_offset)
    7298                 :             : {
    7299                 :      725883 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7300                 :      725883 :   if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
    7301                 :             :     {
    7302                 :             :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7303                 :       28328 :       gcc_assert (cfa_offset >= fs.sp_realigned_offset);
    7304                 :             :       return false;
    7305                 :             :     }
    7306                 :      697555 :   return fs.fp_valid;
    7307                 :             : }
    7308                 :             : 
    7309                 :             : /* Choose a base register based upon alignment requested, speed and/or
    7310                 :             :    size.  */
    7311                 :             : 
    7312                 :             : static void
    7313                 :      725883 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
    7314                 :             :                 HOST_WIDE_INT &base_offset,
    7315                 :             :                 unsigned int align_reqested, unsigned int *align)
    7316                 :             : {
    7317                 :      725883 :   const struct machine_function *m = cfun->machine;
    7318                 :      725883 :   unsigned int hfp_align;
    7319                 :      725883 :   unsigned int drap_align;
    7320                 :      725883 :   unsigned int sp_align;
    7321                 :      725883 :   bool hfp_ok  = fp_valid_at (cfa_offset);
    7322                 :      725883 :   bool drap_ok = m->fs.drap_valid;
    7323                 :      725883 :   bool sp_ok   = sp_valid_at (cfa_offset);
    7324                 :             : 
    7325                 :      725883 :   hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
    7326                 :             : 
    7327                 :             :   /* Filter out any registers that don't meet the requested alignment
    7328                 :             :      criteria.  */
    7329                 :      725883 :   if (align_reqested)
    7330                 :             :     {
    7331                 :      683548 :       if (m->fs.realigned)
    7332                 :       28160 :         hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
    7333                 :             :       /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
    7334                 :             :          notes (which we would need to use a realigned stack pointer),
    7335                 :             :          so disable on SEH targets.  */
    7336                 :      655388 :       else if (m->fs.sp_realigned)
    7337                 :       28328 :         sp_align = crtl->stack_alignment_needed;
    7338                 :             : 
    7339                 :      683548 :       hfp_ok = hfp_ok && hfp_align >= align_reqested;
    7340                 :      683548 :       drap_ok = drap_ok && drap_align >= align_reqested;
    7341                 :      683548 :       sp_ok = sp_ok && sp_align >= align_reqested;
    7342                 :             :     }
    7343                 :             : 
    7344                 :      725883 :   if (m->use_fast_prologue_epilogue)
    7345                 :             :     {
    7346                 :             :       /* Choose the base register most likely to allow the most scheduling
    7347                 :             :          opportunities.  Generally FP is valid throughout the function,
    7348                 :             :          while DRAP must be reloaded within the epilogue.  But choose either
    7349                 :             :          over the SP due to increased encoding size.  */
    7350                 :             : 
    7351                 :      322169 :       if (hfp_ok)
    7352                 :             :         {
    7353                 :       98059 :           base_reg = hard_frame_pointer_rtx;
    7354                 :       98059 :           base_offset = m->fs.fp_offset - cfa_offset;
    7355                 :             :         }
    7356                 :      224110 :       else if (drap_ok)
    7357                 :             :         {
    7358                 :           0 :           base_reg = crtl->drap_reg;
    7359                 :           0 :           base_offset = 0 - cfa_offset;
    7360                 :             :         }
    7361                 :      224110 :       else if (sp_ok)
    7362                 :             :         {
    7363                 :      224110 :           base_reg = stack_pointer_rtx;
    7364                 :      224110 :           base_offset = m->fs.sp_offset - cfa_offset;
    7365                 :             :         }
    7366                 :             :     }
    7367                 :             :   else
    7368                 :             :     {
    7369                 :      403714 :       HOST_WIDE_INT toffset;
    7370                 :      403714 :       int len = 16, tlen;
    7371                 :             : 
    7372                 :             :       /* Choose the base register with the smallest address encoding.
    7373                 :             :          With a tie, choose FP > DRAP > SP.  */
    7374                 :      403714 :       if (sp_ok)
    7375                 :             :         {
    7376                 :      386509 :           base_reg = stack_pointer_rtx;
    7377                 :      386509 :           base_offset = m->fs.sp_offset - cfa_offset;
    7378                 :      768998 :           len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
    7379                 :             :         }
    7380                 :      403714 :       if (drap_ok)
    7381                 :             :         {
    7382                 :           0 :           toffset = 0 - cfa_offset;
    7383                 :           0 :           tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
    7384                 :           0 :           if (tlen <= len)
    7385                 :             :             {
    7386                 :           0 :               base_reg = crtl->drap_reg;
    7387                 :           0 :               base_offset = toffset;
    7388                 :           0 :               len = tlen;
    7389                 :             :             }
    7390                 :             :         }
    7391                 :      403714 :       if (hfp_ok)
    7392                 :             :         {
    7393                 :      305968 :           toffset = m->fs.fp_offset - cfa_offset;
    7394                 :      305968 :           tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
    7395                 :      305968 :           if (tlen <= len)
    7396                 :             :             {
    7397                 :      215324 :               base_reg = hard_frame_pointer_rtx;
    7398                 :      215324 :               base_offset = toffset;
    7399                 :             :             }
    7400                 :             :         }
    7401                 :             :     }
    7402                 :             : 
    7403                 :             :     /* Set the align return value.  */
    7404                 :      725883 :     if (align)
    7405                 :             :       {
    7406                 :      683548 :         if (base_reg == stack_pointer_rtx)
    7407                 :      412458 :           *align = sp_align;
    7408                 :      271090 :         else if (base_reg == crtl->drap_reg)
    7409                 :           0 :           *align = drap_align;
    7410                 :      271090 :         else if (base_reg == hard_frame_pointer_rtx)
    7411                 :      271090 :           *align = hfp_align;
    7412                 :             :       }
    7413                 :      725883 : }
    7414                 :             : 
    7415                 :             : /* Return an RTX that points to CFA_OFFSET within the stack frame and
    7416                 :             :    the alignment of address.  If ALIGN is non-null, it should point to
    7417                 :             :    an alignment value (in bits) that is preferred or zero and will
    7418                 :             :    recieve the alignment of the base register that was selected,
    7419                 :             :    irrespective of rather or not CFA_OFFSET is a multiple of that
    7420                 :             :    alignment value.  If it is possible for the base register offset to be
    7421                 :             :    non-immediate then SCRATCH_REGNO should specify a scratch register to
    7422                 :             :    use.
    7423                 :             : 
    7424                 :             :    The valid base registers are taken from CFUN->MACHINE->FS.  */
    7425                 :             : 
    7426                 :             : static rtx
    7427                 :      725883 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
    7428                 :             :                  unsigned int scratch_regno = INVALID_REGNUM)
    7429                 :             : {
    7430                 :      725883 :   rtx base_reg = NULL;
    7431                 :      725883 :   HOST_WIDE_INT base_offset = 0;
    7432                 :             : 
    7433                 :             :   /* If a specific alignment is requested, try to get a base register
    7434                 :             :      with that alignment first.  */
    7435                 :      725883 :   if (align && *align)
    7436                 :      683548 :     choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
    7437                 :             : 
    7438                 :      725883 :   if (!base_reg)
    7439                 :       42335 :     choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
    7440                 :             : 
    7441                 :      725883 :   gcc_assert (base_reg != NULL);
    7442                 :             : 
    7443                 :      725883 :   rtx base_offset_rtx = GEN_INT (base_offset);
    7444                 :             : 
    7445                 :      725883 :   if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
    7446                 :             :     {
    7447                 :           1 :       gcc_assert (scratch_regno != INVALID_REGNUM);
    7448                 :             : 
    7449                 :           1 :       rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
    7450                 :           1 :       emit_move_insn (scratch_reg, base_offset_rtx);
    7451                 :             : 
    7452                 :           1 :       return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
    7453                 :             :     }
    7454                 :             : 
    7455                 :      725882 :   return plus_constant (Pmode, base_reg, base_offset);
    7456                 :             : }
    7457                 :             : 
    7458                 :             : /* Emit code to save registers in the prologue.  */
    7459                 :             : 
    7460                 :             : static void
    7461                 :      414251 : ix86_emit_save_regs (void)
    7462                 :             : {
    7463                 :      414251 :   int regno;
    7464                 :      414251 :   rtx_insn *insn;
    7465                 :      414251 :   bool use_ppx = TARGET_APX_PPX && !crtl->calls_eh_return;
    7466                 :             : 
    7467                 :      414251 :   if (!TARGET_APX_PUSH2POP2
    7468                 :          13 :       || !ix86_can_use_push2pop2 ()
    7469                 :      414262 :       || cfun->machine->func_type != TYPE_NORMAL)
    7470                 :             :     {
    7471                 :    38524413 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7472                 :    38110172 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7473                 :             :           {
    7474                 :     1157341 :             insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7475                 :             :                                         use_ppx));
    7476                 :     1157341 :             RTX_FRAME_RELATED_P (insn) = 1;
    7477                 :             :           }
    7478                 :             :     }
    7479                 :             :   else
    7480                 :             :     {
    7481                 :          10 :       int regno_list[2];
    7482                 :          10 :       regno_list[0] = regno_list[1] = -1;
    7483                 :          10 :       int loaded_regnum = 0;
    7484                 :          10 :       bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    7485                 :             : 
    7486                 :         930 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7487                 :         920 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7488                 :             :           {
    7489                 :          49 :             if (aligned)
    7490                 :             :               {
    7491                 :          43 :                 regno_list[loaded_regnum++] = regno;
    7492                 :          43 :                 if (loaded_regnum == 2)
    7493                 :             :                   {
    7494                 :          17 :                     gcc_assert (regno_list[0] != -1
    7495                 :             :                                 && regno_list[1] != -1
    7496                 :             :                                 && regno_list[0] != regno_list[1]);
    7497                 :          17 :                     const int offset = UNITS_PER_WORD * 2;
    7498                 :          17 :                     rtx mem = gen_rtx_MEM (TImode,
    7499                 :          17 :                                            gen_rtx_PRE_DEC (Pmode,
    7500                 :             :                                                             stack_pointer_rtx));
    7501                 :          17 :                     insn = emit_insn (gen_push2 (mem,
    7502                 :             :                                                  gen_rtx_REG (word_mode,
    7503                 :             :                                                               regno_list[0]),
    7504                 :             :                                                  gen_rtx_REG (word_mode,
    7505                 :             :                                                               regno_list[1]),
    7506                 :             :                                                  use_ppx));
    7507                 :          17 :                     RTX_FRAME_RELATED_P (insn) = 1;
    7508                 :          17 :                     rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
    7509                 :             : 
    7510                 :          51 :                     for (int i = 0; i < 2; i++)
    7511                 :             :                       {
    7512                 :          68 :                         rtx dwarf_reg = gen_rtx_REG (word_mode,
    7513                 :          34 :                                                      regno_list[i]);
    7514                 :          34 :                         rtx sp_offset = plus_constant (Pmode,
    7515                 :             :                                                        stack_pointer_rtx,
    7516                 :          34 :                                                        + UNITS_PER_WORD
    7517                 :          34 :                                                          * (1 - i));
    7518                 :          34 :                         rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
    7519                 :             :                                                               sp_offset),
    7520                 :             :                                                dwarf_reg);
    7521                 :          34 :                         RTX_FRAME_RELATED_P (tmp) = 1;
    7522                 :          34 :                         XVECEXP (dwarf, 0, i + 1) = tmp;
    7523                 :             :                       }
    7524                 :          17 :                     rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
    7525                 :             :                                               plus_constant (Pmode,
    7526                 :             :                                                              stack_pointer_rtx,
    7527                 :             :                                                              -offset));
    7528                 :          17 :                     RTX_FRAME_RELATED_P (sp_tmp) = 1;
    7529                 :          17 :                     XVECEXP (dwarf, 0, 0) = sp_tmp;
    7530                 :          17 :                     add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
    7531                 :             : 
    7532                 :          17 :                     loaded_regnum = 0;
    7533                 :          17 :                     regno_list[0] = regno_list[1] = -1;
    7534                 :             :                   }
    7535                 :             :               }
    7536                 :             :             else
    7537                 :             :               {
    7538                 :           6 :                 insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7539                 :             :                                             use_ppx));
    7540                 :           6 :                 RTX_FRAME_RELATED_P (insn) = 1;
    7541                 :           6 :                 aligned = true;
    7542                 :             :               }
    7543                 :             :           }
    7544                 :          10 :       if (loaded_regnum == 1)
    7545                 :             :         {
    7546                 :           9 :           insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
    7547                 :           9 :                                                    regno_list[0]),
    7548                 :             :                                       use_ppx));
    7549                 :           9 :           RTX_FRAME_RELATED_P (insn) = 1;
    7550                 :             :         }
    7551                 :             :     }
    7552                 :      414251 : }
    7553                 :             : 
    7554                 :             : /* Emit a single register save at CFA - CFA_OFFSET.  */
    7555                 :             : 
    7556                 :             : static void
    7557                 :      331601 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
    7558                 :             :                               HOST_WIDE_INT cfa_offset)
    7559                 :             : {
    7560                 :      331601 :   struct machine_function *m = cfun->machine;
    7561                 :      331601 :   rtx reg = gen_rtx_REG (mode, regno);
    7562                 :      331601 :   rtx mem, addr, base, insn;
    7563                 :      331601 :   unsigned int align = GET_MODE_ALIGNMENT (mode);
    7564                 :             : 
    7565                 :      331601 :   addr = choose_baseaddr (cfa_offset, &align);
    7566                 :      331601 :   mem = gen_frame_mem (mode, addr);
    7567                 :             : 
    7568                 :             :   /* The location aligment depends upon the base register.  */
    7569                 :      331601 :   align = MIN (GET_MODE_ALIGNMENT (mode), align);
    7570                 :      331601 :   gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    7571                 :      331601 :   set_mem_align (mem, align);
    7572                 :             : 
    7573                 :      331601 :   insn = emit_insn (gen_rtx_SET (mem, reg));
    7574                 :      331601 :   RTX_FRAME_RELATED_P (insn) = 1;
    7575                 :             : 
    7576                 :      331601 :   base = addr;
    7577                 :      331601 :   if (GET_CODE (base) == PLUS)
    7578                 :      324924 :     base = XEXP (base, 0);
    7579                 :      331601 :   gcc_checking_assert (REG_P (base));
    7580                 :             : 
    7581                 :             :   /* When saving registers into a re-aligned local stack frame, avoid
    7582                 :             :      any tricky guessing by dwarf2out.  */
    7583                 :      331601 :   if (m->fs.realigned)
    7584                 :             :     {
    7585                 :       12800 :       gcc_checking_assert (stack_realign_drap);
    7586                 :             : 
    7587                 :       12800 :       if (regno == REGNO (crtl->drap_reg))
    7588                 :             :         {
    7589                 :             :           /* A bit of a hack.  We force the DRAP register to be saved in
    7590                 :             :              the re-aligned stack frame, which provides us with a copy
    7591                 :             :              of the CFA that will last past the prologue.  Install it.  */
    7592                 :           0 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7593                 :           0 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7594                 :           0 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7595                 :           0 :           mem = gen_rtx_MEM (mode, addr);
    7596                 :           0 :           add_reg_note (insn, REG_CFA_DEF_CFA, mem);
    7597                 :             :         }
    7598                 :             :       else
    7599                 :             :         {
    7600                 :             :           /* The frame pointer is a stable reference within the
    7601                 :             :              aligned frame.  Use it.  */
    7602                 :       12800 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7603                 :       12800 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7604                 :       12800 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7605                 :       12800 :           mem = gen_rtx_MEM (mode, addr);
    7606                 :       12800 :           add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7607                 :             :         }
    7608                 :             :     }
    7609                 :             : 
    7610                 :      318801 :   else if (base == stack_pointer_rtx && m->fs.sp_realigned
    7611                 :       12881 :            && cfa_offset >= m->fs.sp_realigned_offset)
    7612                 :             :     {
    7613                 :       12881 :       gcc_checking_assert (stack_realign_fp);
    7614                 :       12881 :       add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7615                 :             :     }
    7616                 :             : 
    7617                 :             :   /* The memory may not be relative to the current CFA register,
    7618                 :             :      which means that we may need to generate a new pattern for
    7619                 :             :      use by the unwind info.  */
    7620                 :      305920 :   else if (base != m->fs.cfa_reg)
    7621                 :             :     {
    7622                 :       45084 :       addr = plus_constant (Pmode, m->fs.cfa_reg,
    7623                 :       45084 :                             m->fs.cfa_offset - cfa_offset);
    7624                 :       45084 :       mem = gen_rtx_MEM (mode, addr);
    7625                 :       45084 :       add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
    7626                 :             :     }
    7627                 :      331601 : }
    7628                 :             : 
    7629                 :             : /* Emit code to save registers using MOV insns.
    7630                 :             :    First register is stored at CFA - CFA_OFFSET.  */
    7631                 :             : static void
    7632                 :          55 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7633                 :             : {
    7634                 :          55 :   unsigned int regno;
    7635                 :             : 
    7636                 :        5115 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7637                 :        5060 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7638                 :             :       {
    7639                 :          80 :         ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
    7640                 :          80 :         cfa_offset -= UNITS_PER_WORD;
    7641                 :             :       }
    7642                 :          55 : }
    7643                 :             : 
    7644                 :             : /* Emit code to save SSE registers using MOV insns.
    7645                 :             :    First register is stored at CFA - CFA_OFFSET.  */
    7646                 :             : static void
    7647                 :       33153 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7648                 :             : {
    7649                 :       33153 :   unsigned int regno;
    7650                 :             : 
    7651                 :     3083229 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7652                 :     3050076 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7653                 :             :       {
    7654                 :      331521 :         ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
    7655                 :      331521 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    7656                 :             :       }
    7657                 :       33153 : }
    7658                 :             : 
    7659                 :             : static GTY(()) rtx queued_cfa_restores;
    7660                 :             : 
    7661                 :             : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
    7662                 :             :    manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
    7663                 :             :    Don't add the note if the previously saved value will be left untouched
    7664                 :             :    within stack red-zone till return, as unwinders can find the same value
    7665                 :             :    in the register and on the stack.  */
    7666                 :             : 
    7667                 :             : static void
    7668                 :     2158829 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
    7669                 :             : {
    7670                 :     2158829 :   if (!crtl->shrink_wrapped
    7671                 :     2145646 :       && cfa_offset <= cfun->machine->fs.red_zone_offset)
    7672                 :             :     return;
    7673                 :             : 
    7674                 :      761476 :   if (insn)
    7675                 :             :     {
    7676                 :      368980 :       add_reg_note (insn, REG_CFA_RESTORE, reg);
    7677                 :      368980 :       RTX_FRAME_RELATED_P (insn) = 1;
    7678                 :             :     }
    7679                 :             :   else
    7680                 :      392496 :     queued_cfa_restores
    7681                 :      392496 :       = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
    7682                 :             : }
    7683                 :             : 
    7684                 :             : /* Add queued REG_CFA_RESTORE notes if any to INSN.  */
    7685                 :             : 
    7686                 :             : static void
    7687                 :     2421494 : ix86_add_queued_cfa_restore_notes (rtx insn)
    7688                 :             : {
    7689                 :     2421494 :   rtx last;
    7690                 :     2421494 :   if (!queued_cfa_restores)
    7691                 :             :     return;
    7692                 :      392496 :   for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
    7693                 :             :     ;
    7694                 :       44525 :   XEXP (last, 1) = REG_NOTES (insn);
    7695                 :       44525 :   REG_NOTES (insn) = queued_cfa_restores;
    7696                 :       44525 :   queued_cfa_restores = NULL_RTX;
    7697                 :       44525 :   RTX_FRAME_RELATED_P (insn) = 1;
    7698                 :             : }
    7699                 :             : 
    7700                 :             : /* Expand prologue or epilogue stack adjustment.
    7701                 :             :    The pattern exist to put a dependency on all ebp-based memory accesses.
    7702                 :             :    STYLE should be negative if instructions should be marked as frame related,
    7703                 :             :    zero if %r11 register is live and cannot be freely used and positive
    7704                 :             :    otherwise.  */
    7705                 :             : 
    7706                 :             : static rtx
    7707                 :     1442968 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
    7708                 :             :                            int style, bool set_cfa)
    7709                 :             : {
    7710                 :     1442968 :   struct machine_function *m = cfun->machine;
    7711                 :     1442968 :   rtx addend = offset;
    7712                 :     1442968 :   rtx insn;
    7713                 :     1442968 :   bool add_frame_related_expr = false;
    7714                 :             : 
    7715                 :     1442968 :   if (!x86_64_immediate_operand (offset, Pmode))
    7716                 :             :     {
    7717                 :             :       /* r11 is used by indirect sibcall return as well, set before the
    7718                 :             :          epilogue and used after the epilogue.  */
    7719                 :         197 :       if (style)
    7720                 :         177 :         addend = gen_rtx_REG (Pmode, R11_REG);
    7721                 :             :       else
    7722                 :             :         {
    7723                 :          20 :           gcc_assert (src != hard_frame_pointer_rtx
    7724                 :             :                       && dest != hard_frame_pointer_rtx);
    7725                 :             :           addend = hard_frame_pointer_rtx;
    7726                 :             :         }
    7727                 :         197 :       emit_insn (gen_rtx_SET (addend, offset));
    7728                 :         197 :       if (style < 0)
    7729                 :          90 :         add_frame_related_expr = true;
    7730                 :             :     }
    7731                 :             : 
    7732                 :     1442968 :   insn = emit_insn (gen_pro_epilogue_adjust_stack_add
    7733                 :     1442968 :                     (Pmode, dest, src, addend));
    7734                 :     1442968 :   if (style >= 0)
    7735                 :      629248 :     ix86_add_queued_cfa_restore_notes (insn);
    7736                 :             : 
    7737                 :     1442968 :   if (set_cfa)
    7738                 :             :     {
    7739                 :     1090924 :       rtx r;
    7740                 :             : 
    7741                 :     1090924 :       gcc_assert (m->fs.cfa_reg == src);
    7742                 :     1090924 :       m->fs.cfa_offset += INTVAL (offset);
    7743                 :     1090924 :       m->fs.cfa_reg = dest;
    7744                 :             : 
    7745                 :     1090924 :       r = gen_rtx_PLUS (Pmode, src, offset);
    7746                 :     1090924 :       r = gen_rtx_SET (dest, r);
    7747                 :     1090924 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
    7748                 :     1090924 :       RTX_FRAME_RELATED_P (insn) = 1;
    7749                 :             :     }
    7750                 :      352044 :   else if (style < 0)
    7751                 :             :     {
    7752                 :      286597 :       RTX_FRAME_RELATED_P (insn) = 1;
    7753                 :      286597 :       if (add_frame_related_expr)
    7754                 :             :         {
    7755                 :          20 :           rtx r = gen_rtx_PLUS (Pmode, src, offset);
    7756                 :          20 :           r = gen_rtx_SET (dest, r);
    7757                 :          20 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
    7758                 :             :         }
    7759                 :             :     }
    7760                 :             : 
    7761                 :     1442968 :   if (dest == stack_pointer_rtx)
    7762                 :             :     {
    7763                 :     1442968 :       HOST_WIDE_INT ooffset = m->fs.sp_offset;
    7764                 :     1442968 :       bool valid = m->fs.sp_valid;
    7765                 :     1442968 :       bool realigned = m->fs.sp_realigned;
    7766                 :             : 
    7767                 :     1442968 :       if (src == hard_frame_pointer_rtx)
    7768                 :             :         {
    7769                 :       28794 :           valid = m->fs.fp_valid;
    7770                 :       28794 :           realigned = false;
    7771                 :       28794 :           ooffset = m->fs.fp_offset;
    7772                 :             :         }
    7773                 :     1414174 :       else if (src == crtl->drap_reg)
    7774                 :             :         {
    7775                 :           0 :           valid = m->fs.drap_valid;
    7776                 :           0 :           realigned = false;
    7777                 :           0 :           ooffset = 0;
    7778                 :             :         }
    7779                 :             :       else
    7780                 :             :         {
    7781                 :             :           /* Else there are two possibilities: SP itself, which we set
    7782                 :             :              up as the default above.  Or EH_RETURN_STACKADJ_RTX, which is
    7783                 :             :              taken care of this by hand along the eh_return path.  */
    7784                 :     1414174 :           gcc_checking_assert (src == stack_pointer_rtx
    7785                 :             :                                || offset == const0_rtx);
    7786                 :             :         }
    7787                 :             : 
    7788                 :     1442968 :       m->fs.sp_offset = ooffset - INTVAL (offset);
    7789                 :     1442968 :       m->fs.sp_valid = valid;
    7790                 :     1442968 :       m->fs.sp_realigned = realigned;
    7791                 :             :     }
    7792                 :     1442968 :   return insn;
    7793                 :             : }
    7794                 :             : 
    7795                 :             : /* Find an available register to be used as dynamic realign argument
    7796                 :             :    pointer regsiter.  Such a register will be written in prologue and
    7797                 :             :    used in begin of body, so it must not be
    7798                 :             :         1. parameter passing register.
    7799                 :             :         2. GOT pointer.
    7800                 :             :    We reuse static-chain register if it is available.  Otherwise, we
    7801                 :             :    use DI for i386 and R13 for x86-64.  We chose R13 since it has
    7802                 :             :    shorter encoding.
    7803                 :             : 
    7804                 :             :    Return: the regno of chosen register.  */
    7805                 :             : 
    7806                 :             : static unsigned int
    7807                 :        7117 : find_drap_reg (void)
    7808                 :             : {
    7809                 :        7117 :   tree decl = cfun->decl;
    7810                 :             : 
    7811                 :             :   /* Always use callee-saved register if there are no caller-saved
    7812                 :             :      registers.  */
    7813                 :        7117 :   if (TARGET_64BIT)
    7814                 :             :     {
    7815                 :             :       /* Use R13 for nested function or function need static chain.
    7816                 :             :          Since function with tail call may use any caller-saved
    7817                 :             :          registers in epilogue, DRAP must not use caller-saved
    7818                 :             :          register in such case.  */
    7819                 :        6835 :       if (DECL_STATIC_CHAIN (decl)
    7820                 :        6793 :           || (cfun->machine->call_saved_registers
    7821                 :        6793 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7822                 :       13628 :           || crtl->tail_call_emit)
    7823                 :         181 :         return R13_REG;
    7824                 :             : 
    7825                 :             :       return R10_REG;
    7826                 :             :     }
    7827                 :             :   else
    7828                 :             :     {
    7829                 :             :       /* Use DI for nested function or function need static chain.
    7830                 :             :          Since function with tail call may use any caller-saved
    7831                 :             :          registers in epilogue, DRAP must not use caller-saved
    7832                 :             :          register in such case.  */
    7833                 :         282 :       if (DECL_STATIC_CHAIN (decl)
    7834                 :         282 :           || (cfun->machine->call_saved_registers
    7835                 :         282 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7836                 :         282 :           || crtl->tail_call_emit
    7837                 :         544 :           || crtl->calls_eh_return)
    7838                 :             :         return DI_REG;
    7839                 :             : 
    7840                 :             :       /* Reuse static chain register if it isn't used for parameter
    7841                 :             :          passing.  */
    7842                 :         262 :       if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
    7843                 :             :         {
    7844                 :         262 :           unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
    7845                 :         262 :           if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
    7846                 :             :             return CX_REG;
    7847                 :             :         }
    7848                 :           0 :       return DI_REG;
    7849                 :             :     }
    7850                 :             : }
    7851                 :             : 
    7852                 :             : /* Return minimum incoming stack alignment.  */
    7853                 :             : 
    7854                 :             : static unsigned int
    7855                 :     1557261 : ix86_minimum_incoming_stack_boundary (bool sibcall)
    7856                 :             : {
    7857                 :     1557261 :   unsigned int incoming_stack_boundary;
    7858                 :             : 
    7859                 :             :   /* Stack of interrupt handler is aligned to 128 bits in 64bit mode.  */
    7860                 :     1557261 :   if (cfun->machine->func_type != TYPE_NORMAL)
    7861                 :         118 :     incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
    7862                 :             :   /* Prefer the one specified at command line. */
    7863                 :     1557143 :   else if (ix86_user_incoming_stack_boundary)
    7864                 :             :     incoming_stack_boundary = ix86_user_incoming_stack_boundary;
    7865                 :             :   /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
    7866                 :             :      if -mstackrealign is used, it isn't used for sibcall check and
    7867                 :             :      estimated stack alignment is 128bit.  */
    7868                 :     1557121 :   else if (!sibcall
    7869                 :     1433702 :            && ix86_force_align_arg_pointer
    7870                 :        4567 :            && crtl->stack_alignment_estimated == 128)
    7871                 :         596 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7872                 :             :   else
    7873                 :     1556525 :     incoming_stack_boundary = ix86_default_incoming_stack_boundary;
    7874                 :             : 
    7875                 :             :   /* Incoming stack alignment can be changed on individual functions
    7876                 :             :      via force_align_arg_pointer attribute.  We use the smallest
    7877                 :             :      incoming stack boundary.  */
    7878                 :     1557261 :   if (incoming_stack_boundary > MIN_STACK_BOUNDARY
    7879                 :     3113916 :       && lookup_attribute ("force_align_arg_pointer",
    7880                 :     1556655 :                            TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    7881                 :        5707 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7882                 :             : 
    7883                 :             :   /* The incoming stack frame has to be aligned at least at
    7884                 :             :      parm_stack_boundary.  */
    7885                 :     1557261 :   if (incoming_stack_boundary < crtl->parm_stack_boundary)
    7886                 :             :     incoming_stack_boundary = crtl->parm_stack_boundary;
    7887                 :             : 
    7888                 :             :   /* Stack at entrance of main is aligned by runtime.  We use the
    7889                 :             :      smallest incoming stack boundary. */
    7890                 :     1557261 :   if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
    7891                 :      138999 :       && DECL_NAME (current_function_decl)
    7892                 :      138999 :       && MAIN_NAME_P (DECL_NAME (current_function_decl))
    7893                 :     1559721 :       && DECL_FILE_SCOPE_P (current_function_decl))
    7894                 :             :     incoming_stack_boundary = MAIN_STACK_BOUNDARY;
    7895                 :             : 
    7896                 :     1557261 :   return incoming_stack_boundary;
    7897                 :             : }
    7898                 :             : 
    7899                 :             : /* Update incoming stack boundary and estimated stack alignment.  */
    7900                 :             : 
    7901                 :             : static void
    7902                 :     1433837 : ix86_update_stack_boundary (void)
    7903                 :             : {
    7904                 :     1433837 :   ix86_incoming_stack_boundary
    7905                 :     1433837 :     = ix86_minimum_incoming_stack_boundary (false);
    7906                 :             : 
    7907                 :             :   /* x86_64 vararg needs 16byte stack alignment for register save area.  */
    7908                 :     1433837 :   if (TARGET_64BIT
    7909                 :     1308565 :       && cfun->stdarg
    7910                 :       21083 :       && crtl->stack_alignment_estimated < 128)
    7911                 :       10071 :     crtl->stack_alignment_estimated = 128;
    7912                 :             : 
    7913                 :             :   /* __tls_get_addr needs to be called with 16-byte aligned stack.  */
    7914                 :     1433837 :   if (ix86_tls_descriptor_calls_expanded_in_cfun
    7915                 :        1285 :       && crtl->preferred_stack_boundary < 128)
    7916                 :         937 :     crtl->preferred_stack_boundary = 128;
    7917                 :     1433837 : }
    7918                 :             : 
    7919                 :             : /* Handle the TARGET_GET_DRAP_RTX hook.  Return NULL if no DRAP is
    7920                 :             :    needed or an rtx for DRAP otherwise.  */
    7921                 :             : 
    7922                 :             : static rtx
    7923                 :     1534300 : ix86_get_drap_rtx (void)
    7924                 :             : {
    7925                 :             :   /* We must use DRAP if there are outgoing arguments on stack or
    7926                 :             :      the stack pointer register is clobbered by asm statment and
    7927                 :             :      ACCUMULATE_OUTGOING_ARGS is false.  */
    7928                 :     1534300 :   if (ix86_force_drap
    7929                 :     1534300 :       || ((cfun->machine->outgoing_args_on_stack
    7930                 :     1208900 :            || crtl->sp_is_clobbered_by_asm)
    7931                 :      323455 :           && !ACCUMULATE_OUTGOING_ARGS))
    7932                 :      303258 :     crtl->need_drap = true;
    7933                 :             : 
    7934                 :     1534300 :   if (stack_realign_drap)
    7935                 :             :     {
    7936                 :             :       /* Assign DRAP to vDRAP and returns vDRAP */
    7937                 :        7117 :       unsigned int regno = find_drap_reg ();
    7938                 :        7117 :       rtx drap_vreg;
    7939                 :        7117 :       rtx arg_ptr;
    7940                 :        7117 :       rtx_insn *seq, *insn;
    7941                 :             : 
    7942                 :        7117 :       arg_ptr = gen_rtx_REG (Pmode, regno);
    7943                 :        7117 :       crtl->drap_reg = arg_ptr;
    7944                 :             : 
    7945                 :        7117 :       start_sequence ();
    7946                 :        7117 :       drap_vreg = copy_to_reg (arg_ptr);
    7947                 :        7117 :       seq = get_insns ();
    7948                 :        7117 :       end_sequence ();
    7949                 :             : 
    7950                 :        7117 :       insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
    7951                 :        7117 :       if (!optimize)
    7952                 :             :         {
    7953                 :        1882 :           add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
    7954                 :        1882 :           RTX_FRAME_RELATED_P (insn) = 1;
    7955                 :             :         }
    7956                 :        7117 :       return drap_vreg;
    7957                 :             :     }
    7958                 :             :   else
    7959                 :             :     return NULL;
    7960                 :             : }
    7961                 :             : 
    7962                 :             : /* Handle the TARGET_INTERNAL_ARG_POINTER hook.  */
    7963                 :             : 
    7964                 :             : static rtx
    7965                 :     1433837 : ix86_internal_arg_pointer (void)
    7966                 :             : {
    7967                 :     1433837 :   return virtual_incoming_args_rtx;
    7968                 :             : }
    7969                 :             : 
    7970                 :             : struct scratch_reg {
    7971                 :             :   rtx reg;
    7972                 :             :   bool saved;
    7973                 :             : };
    7974                 :             : 
    7975                 :             : /* Return a short-lived scratch register for use on function entry.
    7976                 :             :    In 32-bit mode, it is valid only after the registers are saved
    7977                 :             :    in the prologue.  This register must be released by means of
    7978                 :             :    release_scratch_register_on_entry once it is dead.  */
    7979                 :             : 
    7980                 :             : static void
    7981                 :          18 : get_scratch_register_on_entry (struct scratch_reg *sr)
    7982                 :             : {
    7983                 :          18 :   int regno;
    7984                 :             : 
    7985                 :          18 :   sr->saved = false;
    7986                 :             : 
    7987                 :          18 :   if (TARGET_64BIT)
    7988                 :             :     {
    7989                 :             :       /* We always use R11 in 64-bit mode.  */
    7990                 :             :       regno = R11_REG;
    7991                 :             :     }
    7992                 :             :   else
    7993                 :             :     {
    7994                 :           0 :       tree decl = current_function_decl, fntype = TREE_TYPE (decl);
    7995                 :           0 :       bool fastcall_p
    7996                 :           0 :         = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    7997                 :           0 :       bool thiscall_p
    7998                 :           0 :         = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    7999                 :           0 :       bool static_chain_p = DECL_STATIC_CHAIN (decl);
    8000                 :           0 :       int regparm = ix86_function_regparm (fntype, decl);
    8001                 :           0 :       int drap_regno
    8002                 :           0 :         = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
    8003                 :             : 
    8004                 :             :       /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
    8005                 :             :           for the static chain register.  */
    8006                 :           0 :       if ((regparm < 1 || (fastcall_p && !static_chain_p))
    8007                 :           0 :           && drap_regno != AX_REG)
    8008                 :             :         regno = AX_REG;
    8009                 :             :       /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
    8010                 :             :           for the static chain register.  */
    8011                 :           0 :       else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
    8012                 :             :         regno = AX_REG;
    8013                 :           0 :       else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
    8014                 :             :         regno = DX_REG;
    8015                 :             :       /* ecx is the static chain register.  */
    8016                 :           0 :       else if (regparm < 3 && !fastcall_p && !thiscall_p
    8017                 :           0 :                && !static_chain_p
    8018                 :           0 :                && drap_regno != CX_REG)
    8019                 :             :         regno = CX_REG;
    8020                 :           0 :       else if (ix86_save_reg (BX_REG, true, false))
    8021                 :             :         regno = BX_REG;
    8022                 :             :       /* esi is the static chain register.  */
    8023                 :           0 :       else if (!(regparm == 3 && static_chain_p)
    8024                 :           0 :                && ix86_save_reg (SI_REG, true, false))
    8025                 :             :         regno = SI_REG;
    8026                 :           0 :       else if (ix86_save_reg (DI_REG, true, false))
    8027                 :             :         regno = DI_REG;
    8028                 :             :       else
    8029                 :             :         {
    8030                 :           0 :           regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
    8031                 :           0 :           sr->saved = true;
    8032                 :             :         }
    8033                 :             :     }
    8034                 :             : 
    8035                 :          18 :   sr->reg = gen_rtx_REG (Pmode, regno);
    8036                 :          18 :   if (sr->saved)
    8037                 :             :     {
    8038                 :           0 :       rtx_insn *insn = emit_insn (gen_push (sr->reg));
    8039                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    8040                 :             :     }
    8041                 :          18 : }
    8042                 :             : 
    8043                 :             : /* Release a scratch register obtained from the preceding function.
    8044                 :             : 
    8045                 :             :    If RELEASE_VIA_POP is true, we just pop the register off the stack
    8046                 :             :    to release it.  This is what non-Linux systems use with -fstack-check.
    8047                 :             : 
    8048                 :             :    Otherwise we use OFFSET to locate the saved register and the
    8049                 :             :    allocated stack space becomes part of the local frame and is
    8050                 :             :    deallocated by the epilogue.  */
    8051                 :             : 
    8052                 :             : static void
    8053                 :          18 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
    8054                 :             :                                    bool release_via_pop)
    8055                 :             : {
    8056                 :          18 :   if (sr->saved)
    8057                 :             :     {
    8058                 :           0 :       if (release_via_pop)
    8059                 :             :         {
    8060                 :           0 :           struct machine_function *m = cfun->machine;
    8061                 :           0 :           rtx x, insn = emit_insn (gen_pop (sr->reg));
    8062                 :             : 
    8063                 :             :           /* The RX FRAME_RELATED_P mechanism doesn't know about pop.  */
    8064                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8065                 :           0 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8066                 :           0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8067                 :           0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
    8068                 :           0 :           m->fs.sp_offset -= UNITS_PER_WORD;
    8069                 :             :         }
    8070                 :             :       else
    8071                 :             :         {
    8072                 :           0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    8073                 :           0 :           x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
    8074                 :           0 :           emit_insn (x);
    8075                 :             :         }
    8076                 :             :     }
    8077                 :          18 : }
    8078                 :             : 
    8079                 :             : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
    8080                 :             : 
    8081                 :             :    If INT_REGISTERS_SAVED is true, then integer registers have already been
    8082                 :             :    pushed on the stack.
    8083                 :             : 
    8084                 :             :    If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
    8085                 :             :    beyond SIZE bytes.
    8086                 :             : 
    8087                 :             :    This assumes no knowledge of the current probing state, i.e. it is never
    8088                 :             :    allowed to allocate more than PROBE_INTERVAL bytes of stack space without
    8089                 :             :    a suitable probe.  */
    8090                 :             : 
    8091                 :             : static void
    8092                 :         109 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
    8093                 :             :                              const bool int_registers_saved,
    8094                 :             :                              const bool protection_area)
    8095                 :             : {
    8096                 :         109 :   struct machine_function *m = cfun->machine;
    8097                 :             : 
    8098                 :             :   /* If this function does not statically allocate stack space, then
    8099                 :             :      no probes are needed.  */
    8100                 :         109 :   if (!size)
    8101                 :             :     {
    8102                 :             :       /* However, the allocation of space via pushes for register
    8103                 :             :          saves could be viewed as allocating space, but without the
    8104                 :             :          need to probe.  */
    8105                 :          42 :       if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
    8106                 :          22 :         dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8107                 :             :       else
    8108                 :          20 :         dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
    8109                 :          42 :       return;
    8110                 :             :     }
    8111                 :             : 
    8112                 :             :   /* If we are a noreturn function, then we have to consider the
    8113                 :             :      possibility that we're called via a jump rather than a call.
    8114                 :             : 
    8115                 :             :      Thus we don't have the implicit probe generated by saving the
    8116                 :             :      return address into the stack at the call.  Thus, the stack
    8117                 :             :      pointer could be anywhere in the guard page.  The safe thing
    8118                 :             :      to do is emit a probe now.
    8119                 :             : 
    8120                 :             :      The probe can be avoided if we have already emitted any callee
    8121                 :             :      register saves into the stack or have a frame pointer (which will
    8122                 :             :      have been saved as well).  Those saves will function as implicit
    8123                 :             :      probes.
    8124                 :             : 
    8125                 :             :      ?!? This should be revamped to work like aarch64 and s390 where
    8126                 :             :      we track the offset from the most recent probe.  Normally that
    8127                 :             :      offset would be zero.  For a noreturn function we would reset
    8128                 :             :      it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT).   Then
    8129                 :             :      we just probe when we cross PROBE_INTERVAL.  */
    8130                 :          67 :   if (TREE_THIS_VOLATILE (cfun->decl)
    8131                 :           8 :       && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
    8132                 :             :     {
    8133                 :             :       /* We can safely use any register here since we're just going to push
    8134                 :             :          its value and immediately pop it back.  But we do try and avoid
    8135                 :             :          argument passing registers so as not to introduce dependencies in
    8136                 :             :          the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
    8137                 :           8 :       rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
    8138                 :           8 :       rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
    8139                 :           8 :       rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
    8140                 :           8 :       m->fs.sp_offset -= UNITS_PER_WORD;
    8141                 :           8 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8142                 :             :         {
    8143                 :           8 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    8144                 :           8 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8145                 :           8 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8146                 :           8 :           add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
    8147                 :           8 :           RTX_FRAME_RELATED_P (insn_push) = 1;
    8148                 :           8 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8149                 :           8 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8150                 :           8 :           add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
    8151                 :           8 :           RTX_FRAME_RELATED_P (insn_pop) = 1;
    8152                 :             :         }
    8153                 :           8 :       emit_insn (gen_blockage ());
    8154                 :             :     }
    8155                 :             : 
    8156                 :          67 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8157                 :          67 :   const int dope = 4 * UNITS_PER_WORD;
    8158                 :             : 
    8159                 :             :   /* If there is protection area, take it into account in the size.  */
    8160                 :          67 :   if (protection_area)
    8161                 :          25 :     size += probe_interval + dope;
    8162                 :             : 
    8163                 :             :   /* If we allocate less than the size of the guard statically,
    8164                 :             :      then no probing is necessary, but we do need to allocate
    8165                 :             :      the stack.  */
    8166                 :          42 :   else if (size < (1 << param_stack_clash_protection_guard_size))
    8167                 :             :     {
    8168                 :          28 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8169                 :             :                                  GEN_INT (-size), -1,
    8170                 :          28 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    8171                 :          28 :       dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8172                 :          28 :       return;
    8173                 :             :     }
    8174                 :             : 
    8175                 :             :   /* We're allocating a large enough stack frame that we need to
    8176                 :             :      emit probes.  Either emit them inline or in a loop depending
    8177                 :             :      on the size.  */
    8178                 :          39 :   if (size <= 4 * probe_interval)
    8179                 :             :     {
    8180                 :             :       HOST_WIDE_INT i;
    8181                 :          49 :       for (i = probe_interval; i <= size; i += probe_interval)
    8182                 :             :         {
    8183                 :             :           /* Allocate PROBE_INTERVAL bytes.  */
    8184                 :          28 :           rtx insn
    8185                 :          28 :             = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8186                 :             :                                          GEN_INT (-probe_interval), -1,
    8187                 :          28 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    8188                 :          28 :           add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
    8189                 :             : 
    8190                 :             :           /* And probe at *sp.  */
    8191                 :          28 :           emit_stack_probe (stack_pointer_rtx);
    8192                 :          28 :           emit_insn (gen_blockage ());
    8193                 :             :         }
    8194                 :             : 
    8195                 :             :       /* We need to allocate space for the residual, but we do not need
    8196                 :             :          to probe the residual...  */
    8197                 :          21 :       HOST_WIDE_INT residual = (i - probe_interval - size);
    8198                 :          21 :       if (residual)
    8199                 :             :         {
    8200                 :          21 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8201                 :             :                                      GEN_INT (residual), -1,
    8202                 :          21 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8203                 :             : 
    8204                 :             :           /* ...except if there is a protection area to maintain.  */
    8205                 :          21 :           if (protection_area)
    8206                 :          12 :             emit_stack_probe (stack_pointer_rtx);
    8207                 :             :         }
    8208                 :             : 
    8209                 :          21 :       dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
    8210                 :             :     }
    8211                 :             :   else
    8212                 :             :     {
    8213                 :             :       /* We expect the GP registers to be saved when probes are used
    8214                 :             :          as the probing sequences might need a scratch register and
    8215                 :             :          the routine to allocate one assumes the integer registers
    8216                 :             :          have already been saved.  */
    8217                 :          18 :       gcc_assert (int_registers_saved);
    8218                 :             : 
    8219                 :          18 :       struct scratch_reg sr;
    8220                 :          18 :       get_scratch_register_on_entry (&sr);
    8221                 :             : 
    8222                 :             :       /* If we needed to save a register, then account for any space
    8223                 :             :          that was pushed (we are not going to pop the register when
    8224                 :             :          we do the restore).  */
    8225                 :          18 :       if (sr.saved)
    8226                 :           0 :         size -= UNITS_PER_WORD;
    8227                 :             : 
    8228                 :             :       /* Step 1: round SIZE down to a multiple of the interval.  */
    8229                 :          18 :       HOST_WIDE_INT rounded_size = size & -probe_interval;
    8230                 :             : 
    8231                 :             :       /* Step 2: compute final value of the loop counter.  Use lea if
    8232                 :             :          possible.  */
    8233                 :          18 :       rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    8234                 :          18 :       rtx insn;
    8235                 :          18 :       if (address_no_seg_operand (addr, Pmode))
    8236                 :           6 :         insn = emit_insn (gen_rtx_SET (sr.reg, addr));
    8237                 :             :       else
    8238                 :             :         {
    8239                 :          12 :           emit_move_insn (sr.reg, GEN_INT (-rounded_size));
    8240                 :          12 :           insn = emit_insn (gen_rtx_SET (sr.reg,
    8241                 :             :                                          gen_rtx_PLUS (Pmode, sr.reg,
    8242                 :             :                                                        stack_pointer_rtx)));
    8243                 :             :         }
    8244                 :          18 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8245                 :             :         {
    8246                 :          16 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8247                 :          16 :                         plus_constant (Pmode, sr.reg,
    8248                 :          16 :                                        m->fs.cfa_offset + rounded_size));
    8249                 :          16 :           RTX_FRAME_RELATED_P (insn) = 1;
    8250                 :             :         }
    8251                 :             : 
    8252                 :             :       /* Step 3: the loop.  */
    8253                 :          18 :       rtx size_rtx = GEN_INT (rounded_size);
    8254                 :          18 :       insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
    8255                 :             :                                                     size_rtx));
    8256                 :          18 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8257                 :             :         {
    8258                 :          16 :           m->fs.cfa_offset += rounded_size;
    8259                 :          16 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8260                 :          16 :                         plus_constant (Pmode, stack_pointer_rtx,
    8261                 :          16 :                                        m->fs.cfa_offset));
    8262                 :          16 :           RTX_FRAME_RELATED_P (insn) = 1;
    8263                 :             :         }
    8264                 :          18 :       m->fs.sp_offset += rounded_size;
    8265                 :          18 :       emit_insn (gen_blockage ());
    8266                 :             : 
    8267                 :             :       /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
    8268                 :             :          is equal to ROUNDED_SIZE.  */
    8269                 :             : 
    8270                 :          18 :       if (size != rounded_size)
    8271                 :             :         {
    8272                 :          18 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8273                 :             :                                      GEN_INT (rounded_size - size), -1,
    8274                 :          18 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8275                 :             : 
    8276                 :          18 :           if (protection_area)
    8277                 :          13 :             emit_stack_probe (stack_pointer_rtx);
    8278                 :             :         }
    8279                 :             : 
    8280                 :          18 :       dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
    8281                 :             : 
    8282                 :             :       /* This does not deallocate the space reserved for the scratch
    8283                 :             :          register.  That will be deallocated in the epilogue.  */
    8284                 :          18 :       release_scratch_register_on_entry (&sr, size, false);
    8285                 :             :     }
    8286                 :             : 
    8287                 :             :   /* Adjust back to account for the protection area.  */
    8288                 :          39 :   if (protection_area)
    8289                 :          25 :     pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8290                 :          25 :                                GEN_INT (probe_interval + dope), -1,
    8291                 :          25 :                                m->fs.cfa_reg == stack_pointer_rtx);
    8292                 :             : 
    8293                 :             :   /* Make sure nothing is scheduled before we are done.  */
    8294                 :          39 :   emit_insn (gen_blockage ());
    8295                 :             : }
    8296                 :             : 
    8297                 :             : /* Adjust the stack pointer up to REG while probing it.  */
    8298                 :             : 
    8299                 :             : const char *
    8300                 :          18 : output_adjust_stack_and_probe (rtx reg)
    8301                 :             : {
    8302                 :          18 :   static int labelno = 0;
    8303                 :          18 :   char loop_lab[32];
    8304                 :          18 :   rtx xops[2];
    8305                 :             : 
    8306                 :          18 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8307                 :             : 
    8308                 :             :   /* Loop.  */
    8309                 :          18 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8310                 :             : 
    8311                 :             :   /* SP = SP + PROBE_INTERVAL.  */
    8312                 :          18 :   xops[0] = stack_pointer_rtx;
    8313                 :          23 :   xops[1] = GEN_INT (get_probe_interval ());
    8314                 :          18 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8315                 :             : 
    8316                 :             :   /* Probe at SP.  */
    8317                 :          18 :   xops[1] = const0_rtx;
    8318                 :          18 :   output_asm_insn ("or%z0\t{%1, (%0)|DWORD PTR [%0], %1}", xops);
    8319                 :             : 
    8320                 :             :   /* Test if SP == LAST_ADDR.  */
    8321                 :          18 :   xops[0] = stack_pointer_rtx;
    8322                 :          18 :   xops[1] = reg;
    8323                 :          18 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8324                 :             : 
    8325                 :             :   /* Branch.  */
    8326                 :          18 :   fputs ("\tjne\t", asm_out_file);
    8327                 :          18 :   assemble_name_raw (asm_out_file, loop_lab);
    8328                 :          18 :   fputc ('\n', asm_out_file);
    8329                 :             : 
    8330                 :          18 :   return "";
    8331                 :             : }
    8332                 :             : 
    8333                 :             : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
    8334                 :             :    inclusive.  These are offsets from the current stack pointer.
    8335                 :             : 
    8336                 :             :    INT_REGISTERS_SAVED is true if integer registers have already been
    8337                 :             :    pushed on the stack.  */
    8338                 :             : 
    8339                 :             : static void
    8340                 :           0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
    8341                 :             :                              const bool int_registers_saved)
    8342                 :             : {
    8343                 :           0 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8344                 :             : 
    8345                 :             :   /* See if we have a constant small number of probes to generate.  If so,
    8346                 :             :      that's the easy case.  The run-time loop is made up of 6 insns in the
    8347                 :             :      generic case while the compile-time loop is made up of n insns for n #
    8348                 :             :      of intervals.  */
    8349                 :           0 :   if (size <= 6 * probe_interval)
    8350                 :             :     {
    8351                 :             :       HOST_WIDE_INT i;
    8352                 :             : 
    8353                 :             :       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
    8354                 :             :          it exceeds SIZE.  If only one probe is needed, this will not
    8355                 :             :          generate any code.  Then probe at FIRST + SIZE.  */
    8356                 :           0 :       for (i = probe_interval; i < size; i += probe_interval)
    8357                 :           0 :         emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8358                 :           0 :                                          -(first + i)));
    8359                 :             : 
    8360                 :           0 :       emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8361                 :           0 :                                        -(first + size)));
    8362                 :             :     }
    8363                 :             : 
    8364                 :             :   /* Otherwise, do the same as above, but in a loop.  Note that we must be
    8365                 :             :      extra careful with variables wrapping around because we might be at
    8366                 :             :      the very top (or the very bottom) of the address space and we have
    8367                 :             :      to be able to handle this case properly; in particular, we use an
    8368                 :             :      equality test for the loop condition.  */
    8369                 :             :   else
    8370                 :             :     {
    8371                 :             :       /* We expect the GP registers to be saved when probes are used
    8372                 :             :          as the probing sequences might need a scratch register and
    8373                 :             :          the routine to allocate one assumes the integer registers
    8374                 :             :          have already been saved.  */
    8375                 :           0 :       gcc_assert (int_registers_saved);
    8376                 :             : 
    8377                 :           0 :       HOST_WIDE_INT rounded_size, last;
    8378                 :           0 :       struct scratch_reg sr;
    8379                 :             : 
    8380                 :           0 :       get_scratch_register_on_entry (&sr);
    8381                 :             : 
    8382                 :             : 
    8383                 :             :       /* Step 1: round SIZE to the previous multiple of the interval.  */
    8384                 :             : 
    8385                 :           0 :       rounded_size = ROUND_DOWN (size, probe_interval);
    8386                 :             : 
    8387                 :             : 
    8388                 :             :       /* Step 2: compute initial and final value of the loop counter.  */
    8389                 :             : 
    8390                 :             :       /* TEST_OFFSET = FIRST.  */
    8391                 :           0 :       emit_move_insn (sr.reg, GEN_INT (-first));
    8392                 :             : 
    8393                 :             :       /* LAST_OFFSET = FIRST + ROUNDED_SIZE.  */
    8394                 :           0 :       last = first + rounded_size;
    8395                 :             : 
    8396                 :             : 
    8397                 :             :       /* Step 3: the loop
    8398                 :             : 
    8399                 :             :          do
    8400                 :             :            {
    8401                 :             :              TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
    8402                 :             :              probe at TEST_ADDR
    8403                 :             :            }
    8404                 :             :          while (TEST_ADDR != LAST_ADDR)
    8405                 :             : 
    8406                 :             :          probes at FIRST + N * PROBE_INTERVAL for values of N from 1
    8407                 :             :          until it is equal to ROUNDED_SIZE.  */
    8408                 :             : 
    8409                 :           0 :       emit_insn
    8410                 :           0 :         (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
    8411                 :             : 
    8412                 :             : 
    8413                 :             :       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
    8414                 :             :          that SIZE is equal to ROUNDED_SIZE.  */
    8415                 :             : 
    8416                 :           0 :       if (size != rounded_size)
    8417                 :           0 :         emit_stack_probe (plus_constant (Pmode,
    8418                 :           0 :                                          gen_rtx_PLUS (Pmode,
    8419                 :             :                                                        stack_pointer_rtx,
    8420                 :             :                                                        sr.reg),
    8421                 :           0 :                                          rounded_size - size));
    8422                 :             : 
    8423                 :           0 :       release_scratch_register_on_entry (&sr, size, true);
    8424                 :             :     }
    8425                 :             : 
    8426                 :             :   /* Make sure nothing is scheduled before we are done.  */
    8427                 :           0 :   emit_insn (gen_blockage ());
    8428                 :           0 : }
    8429                 :             : 
    8430                 :             : /* Probe a range of stack addresses from REG to END, inclusive.  These are
    8431                 :             :    offsets from the current stack pointer.  */
    8432                 :             : 
    8433                 :             : const char *
    8434                 :           0 : output_probe_stack_range (rtx reg, rtx end)
    8435                 :             : {
    8436                 :           0 :   static int labelno = 0;
    8437                 :           0 :   char loop_lab[32];
    8438                 :           0 :   rtx xops[3];
    8439                 :             : 
    8440                 :           0 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8441                 :             : 
    8442                 :             :   /* Loop.  */
    8443                 :           0 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8444                 :             : 
    8445                 :             :   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
    8446                 :           0 :   xops[0] = reg;
    8447                 :           0 :   xops[1] = GEN_INT (get_probe_interval ());
    8448                 :           0 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8449                 :             : 
    8450                 :             :   /* Probe at TEST_ADDR.  */
    8451                 :           0 :   xops[0] = stack_pointer_rtx;
    8452                 :           0 :   xops[1] = reg;
    8453                 :           0 :   xops[2] = const0_rtx;
    8454                 :           0 :   output_asm_insn ("or%z0\t{%2, (%0,%1)|DWORD PTR [%0+%1], %2}", xops);
    8455                 :             : 
    8456                 :             :   /* Test if TEST_ADDR == LAST_ADDR.  */
    8457                 :           0 :   xops[0] = reg;
    8458                 :           0 :   xops[1] = end;
    8459                 :           0 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8460                 :             : 
    8461                 :             :   /* Branch.  */
    8462                 :           0 :   fputs ("\tjne\t", asm_out_file);
    8463                 :           0 :   assemble_name_raw (asm_out_file, loop_lab);
    8464                 :           0 :   fputc ('\n', asm_out_file);
    8465                 :             : 
    8466                 :           0 :   return "";
    8467                 :             : }
    8468                 :             : 
    8469                 :             : /* Set stack_frame_required to false if stack frame isn't required.
    8470                 :             :    Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
    8471                 :             :    slot used if stack frame is required and CHECK_STACK_SLOT is true.  */
    8472                 :             : 
    8473                 :             : static void
    8474                 :     1433028 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
    8475                 :             :                                     bool check_stack_slot)
    8476                 :             : {
    8477                 :     1433028 :   HARD_REG_SET set_up_by_prologue, prologue_used;
    8478                 :     1433028 :   basic_block bb;
    8479                 :             : 
    8480                 :     5732112 :   CLEAR_HARD_REG_SET (prologue_used);
    8481                 :     1433028 :   CLEAR_HARD_REG_SET (set_up_by_prologue);
    8482                 :     1433028 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
    8483                 :     1433028 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
    8484                 :     1433028 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode,
    8485                 :             :                        HARD_FRAME_POINTER_REGNUM);
    8486                 :             : 
    8487                 :             :   /* The preferred stack alignment is the minimum stack alignment.  */
    8488                 :     1433028 :   if (stack_alignment > crtl->preferred_stack_boundary)
    8489                 :      146394 :     stack_alignment = crtl->preferred_stack_boundary;
    8490                 :             : 
    8491                 :     1433028 :   bool require_stack_frame = false;
    8492                 :             : 
    8493                 :    15031000 :   FOR_EACH_BB_FN (bb, cfun)
    8494                 :             :     {
    8495                 :    13597972 :       rtx_insn *insn;
    8496                 :   158978612 :       FOR_BB_INSNS (bb, insn)
    8497                 :   145380640 :         if (NONDEBUG_INSN_P (insn)
    8498                 :   145380640 :             && requires_stack_frame_p (insn, prologue_used,
    8499                 :             :                                        set_up_by_prologue))
    8500                 :             :           {
    8501                 :    31750350 :             require_stack_frame = true;
    8502                 :             : 
    8503                 :    31750350 :             if (check_stack_slot)
    8504                 :             :               {
    8505                 :             :                 /* Find the maximum stack alignment.  */
    8506                 :    28283039 :                 subrtx_iterator::array_type array;
    8507                 :   195724157 :                 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
    8508                 :   167441118 :                   if (MEM_P (*iter)
    8509                 :   167441118 :                       && (reg_mentioned_p (stack_pointer_rtx,
    8510                 :             :                                            *iter)
    8511                 :    12395119 :                           || reg_mentioned_p (frame_pointer_rtx,
    8512                 :             :                                               *iter)))
    8513                 :             :                     {
    8514                 :    10301829 :                       unsigned int alignment = MEM_ALIGN (*iter);
    8515                 :    10301829 :                       if (alignment > stack_alignment)
    8516                 :       26283 :                         stack_alignment = alignment;
    8517                 :             :                     }
    8518                 :    28283039 :               }
    8519                 :             :           }
    8520                 :             :     }
    8521                 :             : 
    8522                 :     1433028 :   cfun->machine->stack_frame_required = require_stack_frame;
    8523                 :     1433028 : }
    8524                 :             : 
    8525                 :             : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
    8526                 :             :    will guide prologue/epilogue to be generated in correct form.  */
    8527                 :             : 
    8528                 :             : static void
    8529                 :     3240668 : ix86_finalize_stack_frame_flags (void)
    8530                 :             : {
    8531                 :             :   /* Check if stack realign is really needed after reload, and
    8532                 :             :      stores result in cfun */
    8533                 :     3240668 :   unsigned int incoming_stack_boundary
    8534                 :     3240668 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    8535                 :     3240668 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    8536                 :     3240668 :   unsigned int stack_alignment
    8537                 :     1133788 :     = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
    8538                 :     4374456 :        ? crtl->max_used_stack_slot_alignment
    8539                 :     3240668 :        : crtl->stack_alignment_needed);
    8540                 :     3240668 :   unsigned int stack_realign
    8541                 :     3240668 :     = (incoming_stack_boundary < stack_alignment);
    8542                 :     3240668 :   bool recompute_frame_layout_p = false;
    8543                 :             : 
    8544                 :     3240668 :   if (crtl->stack_realign_finalized)
    8545                 :             :     {
    8546                 :             :       /* After stack_realign_needed is finalized, we can't no longer
    8547                 :             :          change it.  */
    8548                 :     1807640 :       gcc_assert (crtl->stack_realign_needed == stack_realign);
    8549                 :     1807640 :       return;
    8550                 :             :     }
    8551                 :             : 
    8552                 :             :   /* It is always safe to compute max_used_stack_alignment.  We
    8553                 :             :      compute it only if 128-bit aligned load/store may be generated
    8554                 :             :      on misaligned stack slot which will lead to segfault. */
    8555                 :     2866056 :   bool check_stack_slot
    8556                 :     1433028 :     = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
    8557                 :     1433028 :   ix86_find_max_used_stack_alignment (stack_alignment,
    8558                 :             :                                       check_stack_slot);
    8559                 :             : 
    8560                 :             :   /* If the only reason for frame_pointer_needed is that we conservatively
    8561                 :             :      assumed stack realignment might be needed or -fno-omit-frame-pointer
    8562                 :             :      is used, but in the end nothing that needed the stack alignment had
    8563                 :             :      been spilled nor stack access, clear frame_pointer_needed and say we
    8564                 :             :      don't need stack realignment.
    8565                 :             : 
    8566                 :             :      When vector register is used for piecewise move and store, we don't
    8567                 :             :      increase stack_alignment_needed as there is no register spill for
    8568                 :             :      piecewise move and store.  Since stack_realign_needed is set to true
    8569                 :             :      by checking stack_alignment_estimated which is updated by pseudo
    8570                 :             :      vector register usage, we also need to check stack_realign_needed to
    8571                 :             :      eliminate frame pointer.  */
    8572                 :     1433028 :   if ((stack_realign
    8573                 :     1365606 :        || (!flag_omit_frame_pointer && optimize)
    8574                 :     1355374 :        || crtl->stack_realign_needed)
    8575                 :       78185 :       && frame_pointer_needed
    8576                 :       78185 :       && crtl->is_leaf
    8577                 :       53930 :       && crtl->sp_is_unchanging
    8578                 :       53878 :       && !ix86_current_function_calls_tls_descriptor
    8579                 :       53878 :       && !crtl->accesses_prior_frames
    8580                 :       53878 :       && !cfun->calls_alloca
    8581                 :       53878 :       && !crtl->calls_eh_return
    8582                 :             :       /* See ira_setup_eliminable_regset for the rationale.  */
    8583                 :       53878 :       && !(STACK_CHECK_MOVING_SP
    8584                 :       53878 :            && flag_stack_check
    8585                 :           0 :            && flag_exceptions
    8586                 :           0 :            && cfun->can_throw_non_call_exceptions)
    8587                 :       53878 :       && !ix86_frame_pointer_required ()
    8588                 :       53877 :       && ix86_get_frame_size () == 0
    8589                 :       35543 :       && ix86_nsaved_sseregs () == 0
    8590                 :     1468571 :       && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
    8591                 :             :     {
    8592                 :       35543 :       if (cfun->machine->stack_frame_required)
    8593                 :             :         {
    8594                 :             :           /* Stack frame is required.  If stack alignment needed is less
    8595                 :             :              than incoming stack boundary, don't realign stack.  */
    8596                 :         217 :           stack_realign = incoming_stack_boundary < stack_alignment;
    8597                 :         217 :           if (!stack_realign)
    8598                 :             :             {
    8599                 :         217 :               crtl->max_used_stack_slot_alignment
    8600                 :         217 :                 = incoming_stack_boundary;
    8601                 :         217 :               crtl->stack_alignment_needed
    8602                 :         217 :                 = incoming_stack_boundary;
    8603                 :             :               /* Also update preferred_stack_boundary for leaf
    8604                 :             :                  functions.  */
    8605                 :         217 :               crtl->preferred_stack_boundary
    8606                 :         217 :                 = incoming_stack_boundary;
    8607                 :             :             }
    8608                 :             :         }
    8609                 :             :       else
    8610                 :             :         {
    8611                 :             :           /* If drap has been set, but it actually isn't live at the
    8612                 :             :              start of the function, there is no reason to set it up.  */
    8613                 :       35326 :           if (crtl->drap_reg)
    8614                 :             :             {
    8615                 :          32 :               basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    8616                 :          64 :               if (! REGNO_REG_SET_P (DF_LR_IN (bb),
    8617                 :             :                                      REGNO (crtl->drap_reg)))
    8618                 :             :                 {
    8619                 :          32 :                   crtl->drap_reg = NULL_RTX;
    8620                 :          32 :                   crtl->need_drap = false;
    8621                 :             :                 }
    8622                 :             :             }
    8623                 :             :           else
    8624                 :       35294 :             cfun->machine->no_drap_save_restore = true;
    8625                 :             : 
    8626                 :       35326 :           frame_pointer_needed = false;
    8627                 :       35326 :           stack_realign = false;
    8628                 :       35326 :           crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
    8629                 :       35326 :           crtl->stack_alignment_needed = incoming_stack_boundary;
    8630                 :       35326 :           crtl->stack_alignment_estimated = incoming_stack_boundary;
    8631                 :       35326 :           if (crtl->preferred_stack_boundary > incoming_stack_boundary)
    8632                 :           0 :             crtl->preferred_stack_boundary = incoming_stack_boundary;
    8633                 :       35326 :           df_finish_pass (true);
    8634                 :       35326 :           df_scan_alloc (NULL);
    8635                 :       35326 :           df_scan_blocks ();
    8636                 :       35326 :           df_compute_regs_ever_live (true);
    8637                 :       35326 :           df_analyze ();
    8638                 :             : 
    8639                 :       35326 :           if (flag_var_tracking)
    8640                 :             :             {
    8641                 :             :               /* Since frame pointer is no longer available, replace it with
    8642                 :             :                  stack pointer - UNITS_PER_WORD in debug insns.  */
    8643                 :         132 :               df_ref ref, next;
    8644                 :         132 :               for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
    8645                 :         132 :                    ref; ref = next)
    8646                 :             :                 {
    8647                 :           0 :                   next = DF_REF_NEXT_REG (ref);
    8648                 :           0 :                   if (!DF_REF_INSN_INFO (ref))
    8649                 :           0 :                     continue;
    8650                 :             : 
    8651                 :             :                   /* Make sure the next ref is for a different instruction,
    8652                 :             :                      so that we're not affected by the rescan.  */
    8653                 :           0 :                   rtx_insn *insn = DF_REF_INSN (ref);
    8654                 :           0 :                   while (next && DF_REF_INSN (next) == insn)
    8655                 :           0 :                     next = DF_REF_NEXT_REG (next);
    8656                 :             : 
    8657                 :           0 :                   if (DEBUG_INSN_P (insn))
    8658                 :             :                     {
    8659                 :             :                       bool changed = false;
    8660                 :           0 :                       for (; ref != next; ref = DF_REF_NEXT_REG (ref))
    8661                 :             :                         {
    8662                 :           0 :                           rtx *loc = DF_REF_LOC (ref);
    8663                 :           0 :                           if (*loc == hard_frame_pointer_rtx)
    8664                 :             :                             {
    8665                 :           0 :                               *loc = plus_constant (Pmode,
    8666                 :             :                                                     stack_pointer_rtx,
    8667                 :           0 :                                                     -UNITS_PER_WORD);
    8668                 :           0 :                               changed = true;
    8669                 :             :                             }
    8670                 :             :                         }
    8671                 :           0 :                       if (changed)
    8672                 :           0 :                         df_insn_rescan (insn);
    8673                 :             :                     }
    8674                 :             :                 }
    8675                 :             :             }
    8676                 :             : 
    8677                 :             :           recompute_frame_layout_p = true;
    8678                 :             :         }
    8679                 :             :     }
    8680                 :     1397485 :   else if (crtl->max_used_stack_slot_alignment >= 128
    8681                 :      641187 :            && cfun->machine->stack_frame_required)
    8682                 :             :     {
    8683                 :             :       /* We don't need to realign stack.  max_used_stack_alignment is
    8684                 :             :          used to decide how stack frame should be aligned.  This is
    8685                 :             :          independent of any psABIs nor 32-bit vs 64-bit.  */
    8686                 :      597647 :       cfun->machine->max_used_stack_alignment
    8687                 :      597647 :         = stack_alignment / BITS_PER_UNIT;
    8688                 :             :     }
    8689                 :             : 
    8690                 :     1433028 :   if (crtl->stack_realign_needed != stack_realign)
    8691                 :       35731 :     recompute_frame_layout_p = true;
    8692                 :     1433028 :   crtl->stack_realign_needed = stack_realign;
    8693                 :     1433028 :   crtl->stack_realign_finalized = true;
    8694                 :     1433028 :   if (recompute_frame_layout_p)
    8695                 :       35806 :     ix86_compute_frame_layout ();
    8696                 :             : }
    8697                 :             : 
    8698                 :             : /* Delete SET_GOT right after entry block if it is allocated to reg.  */
    8699                 :             : 
    8700                 :             : static void
    8701                 :           0 : ix86_elim_entry_set_got (rtx reg)
    8702                 :             : {
    8703                 :           0 :   basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    8704                 :           0 :   rtx_insn *c_insn = BB_HEAD (bb);
    8705                 :           0 :   if (!NONDEBUG_INSN_P (c_insn))
    8706                 :           0 :     c_insn = next_nonnote_nondebug_insn (c_insn);
    8707                 :           0 :   if (c_insn && NONJUMP_INSN_P (c_insn))
    8708                 :             :     {
    8709                 :           0 :       rtx pat = PATTERN (c_insn);
    8710                 :           0 :       if (GET_CODE (pat) == PARALLEL)
    8711                 :             :         {
    8712                 :           0 :           rtx set = XVECEXP (pat, 0, 0);
    8713                 :           0 :           if (GET_CODE (set) == SET
    8714                 :           0 :               && GET_CODE (SET_SRC (set)) == UNSPEC
    8715                 :           0 :               && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
    8716                 :           0 :               && REGNO (SET_DEST (set)) == REGNO (reg))
    8717                 :           0 :             delete_insn (c_insn);
    8718                 :             :         }
    8719                 :             :     }
    8720                 :           0 : }
    8721                 :             : 
    8722                 :             : static rtx
    8723                 :      193166 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
    8724                 :             : {
    8725                 :      193166 :   rtx addr, mem;
    8726                 :             : 
    8727                 :      193166 :   if (offset)
    8728                 :      184480 :     addr = plus_constant (Pmode, frame_reg, offset);
    8729                 :      193166 :   mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
    8730                 :      193166 :   return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
    8731                 :             : }
    8732                 :             : 
    8733                 :             : static inline rtx
    8734                 :      100333 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
    8735                 :             : {
    8736                 :      100333 :   return gen_frame_set (reg, frame_reg, offset, false);
    8737                 :             : }
    8738                 :             : 
    8739                 :             : static inline rtx
    8740                 :       92833 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
    8741                 :             : {
    8742                 :       92833 :   return gen_frame_set (reg, frame_reg, offset, true);
    8743                 :             : }
    8744                 :             : 
    8745                 :             : static void
    8746                 :        7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
    8747                 :             : {
    8748                 :        7045 :   struct machine_function *m = cfun->machine;
    8749                 :        7045 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    8750                 :        7045 :                           + m->call_ms2sysv_extra_regs;
    8751                 :        7045 :   rtvec v = rtvec_alloc (ncregs + 1);
    8752                 :        7045 :   unsigned int align, i, vi = 0;
    8753                 :        7045 :   rtx_insn *insn;
    8754                 :        7045 :   rtx sym, addr;
    8755                 :        7045 :   rtx rax = gen_rtx_REG (word_mode, AX_REG);
    8756                 :        7045 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    8757                 :             : 
    8758                 :             :   /* AL should only be live with sysv_abi.  */
    8759                 :        7045 :   gcc_assert (!ix86_eax_live_at_start_p ());
    8760                 :        7045 :   gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
    8761                 :             : 
    8762                 :             :   /* Setup RAX as the stub's base pointer.  We use stack_realign_offset rather
    8763                 :             :      we've actually realigned the stack or not.  */
    8764                 :        7045 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    8765                 :        7045 :   addr = choose_baseaddr (frame.stack_realign_offset
    8766                 :        7045 :                           + xlogue.get_stub_ptr_offset (), &align, AX_REG);
    8767                 :        7045 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    8768                 :             : 
    8769                 :        7045 :   emit_insn (gen_rtx_SET (rax, addr));
    8770                 :             : 
    8771                 :             :   /* Get the stub symbol.  */
    8772                 :        8327 :   sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
    8773                 :             :                                                   : XLOGUE_STUB_SAVE);
    8774                 :        7045 :   RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    8775                 :             : 
    8776                 :       99878 :   for (i = 0; i < ncregs; ++i)
    8777                 :             :     {
    8778                 :       92833 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    8779                 :       92833 :       rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
    8780                 :       92833 :                              r.regno);
    8781                 :       92833 :       RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
    8782                 :             :     }
    8783                 :             : 
    8784                 :        7045 :   gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
    8785                 :             : 
    8786                 :        7045 :   insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
    8787                 :        7045 :   RTX_FRAME_RELATED_P (insn) = true;
    8788                 :        7045 : }
    8789                 :             : 
    8790                 :             : /* Generate and return an insn body to AND X with Y.  */
    8791                 :             : 
    8792                 :             : static rtx_insn *
    8793                 :       32222 : gen_and2_insn (rtx x, rtx y)
    8794                 :             : {
    8795                 :       32222 :   enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
    8796                 :             : 
    8797                 :       32222 :   gcc_assert (insn_operand_matches (icode, 0, x));
    8798                 :       32222 :   gcc_assert (insn_operand_matches (icode, 1, x));
    8799                 :       32222 :   gcc_assert (insn_operand_matches (icode, 2, y));
    8800                 :             : 
    8801                 :       32222 :   return GEN_FCN (icode) (x, x, y);
    8802                 :             : }
    8803                 :             : 
    8804                 :             : /* Expand the prologue into a bunch of separate insns.  */
    8805                 :             : 
    8806                 :             : void
    8807                 :     1433102 : ix86_expand_prologue (void)
    8808                 :             : {
    8809                 :     1433102 :   struct machine_function *m = cfun->machine;
    8810                 :     1433102 :   rtx insn, t;
    8811                 :     1433102 :   HOST_WIDE_INT allocate;
    8812                 :     1433102 :   bool int_registers_saved;
    8813                 :     1433102 :   bool sse_registers_saved;
    8814                 :     1433102 :   bool save_stub_call_needed;
    8815                 :     1433102 :   rtx static_chain = NULL_RTX;
    8816                 :             : 
    8817                 :     1433102 :   ix86_last_zero_store_uid = 0;
    8818                 :     1433102 :   if (ix86_function_naked (current_function_decl))
    8819                 :             :     {
    8820                 :          74 :       if (flag_stack_usage_info)
    8821                 :           0 :         current_function_static_stack_size = 0;
    8822                 :          74 :       return;
    8823                 :             :     }
    8824                 :             : 
    8825                 :     1433028 :   ix86_finalize_stack_frame_flags ();
    8826                 :             : 
    8827                 :             :   /* DRAP should not coexist with stack_realign_fp */
    8828                 :     1433028 :   gcc_assert (!(crtl->drap_reg && stack_realign_fp));
    8829                 :             : 
    8830                 :     1433028 :   memset (&m->fs, 0, sizeof (m->fs));
    8831                 :             : 
    8832                 :             :   /* Initialize CFA state for before the prologue.  */
    8833                 :     1433028 :   m->fs.cfa_reg = stack_pointer_rtx;
    8834                 :     1433028 :   m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
    8835                 :             : 
    8836                 :             :   /* Track SP offset to the CFA.  We continue tracking this after we've
    8837                 :             :      swapped the CFA register away from SP.  In the case of re-alignment
    8838                 :             :      this is fudged; we're interested to offsets within the local frame.  */
    8839                 :     1433028 :   m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    8840                 :     1433028 :   m->fs.sp_valid = true;
    8841                 :     1433028 :   m->fs.sp_realigned = false;
    8842                 :             : 
    8843                 :     1433028 :   const struct ix86_frame &frame = cfun->machine->frame;
    8844                 :             : 
    8845                 :     1433028 :   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
    8846                 :             :     {
    8847                 :             :       /* We should have already generated an error for any use of
    8848                 :             :          ms_hook on a nested function.  */
    8849                 :           0 :       gcc_checking_assert (!ix86_static_chain_on_stack);
    8850                 :             : 
    8851                 :             :       /* Check if profiling is active and we shall use profiling before
    8852                 :             :          prologue variant. If so sorry.  */
    8853                 :           0 :       if (crtl->profile && flag_fentry != 0)
    8854                 :           0 :         sorry ("%<ms_hook_prologue%> attribute is not compatible "
    8855                 :             :                "with %<-mfentry%> for 32-bit");
    8856                 :             : 
    8857                 :             :       /* In ix86_asm_output_function_label we emitted:
    8858                 :             :          8b ff     movl.s %edi,%edi
    8859                 :             :          55        push   %ebp
    8860                 :             :          8b ec     movl.s %esp,%ebp
    8861                 :             : 
    8862                 :             :          This matches the hookable function prologue in Win32 API
    8863                 :             :          functions in Microsoft Windows XP Service Pack 2 and newer.
    8864                 :             :          Wine uses this to enable Windows apps to hook the Win32 API
    8865                 :             :          functions provided by Wine.
    8866                 :             : 
    8867                 :             :          What that means is that we've already set up the frame pointer.  */
    8868                 :             : 
    8869                 :           0 :       if (frame_pointer_needed
    8870                 :           0 :           && !(crtl->drap_reg && crtl->stack_realign_needed))
    8871                 :             :         {
    8872                 :           0 :           rtx push, mov;
    8873                 :             : 
    8874                 :             :           /* We've decided to use the frame pointer already set up.
    8875                 :             :              Describe this to the unwinder by pretending that both
    8876                 :             :              push and mov insns happen right here.
    8877                 :             : 
    8878                 :             :              Putting the unwind info here at the end of the ms_hook
    8879                 :             :              is done so that we can make absolutely certain we get
    8880                 :             :              the required byte sequence at the start of the function,
    8881                 :             :              rather than relying on an assembler that can produce
    8882                 :             :              the exact encoding required.
    8883                 :             : 
    8884                 :             :              However it does mean (in the unpatched case) that we have
    8885                 :             :              a 1 insn window where the asynchronous unwind info is
    8886                 :             :              incorrect.  However, if we placed the unwind info at
    8887                 :             :              its correct location we would have incorrect unwind info
    8888                 :             :              in the patched case.  Which is probably all moot since
    8889                 :             :              I don't expect Wine generates dwarf2 unwind info for the
    8890                 :             :              system libraries that use this feature.  */
    8891                 :             : 
    8892                 :           0 :           insn = emit_insn (gen_blockage ());
    8893                 :             : 
    8894                 :           0 :           push = gen_push (hard_frame_pointer_rtx);
    8895                 :           0 :           mov = gen_rtx_SET (hard_frame_pointer_rtx,
    8896                 :             :                              stack_pointer_rtx);
    8897                 :           0 :           RTX_FRAME_RELATED_P (push) = 1;
    8898                 :           0 :           RTX_FRAME_RELATED_P (mov) = 1;
    8899                 :             : 
    8900                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8901                 :           0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    8902                 :             :                         gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
    8903                 :             : 
    8904                 :             :           /* Note that gen_push incremented m->fs.cfa_offset, even
    8905                 :             :              though we didn't emit the push insn here.  */
    8906                 :           0 :           m->fs.cfa_reg = hard_frame_pointer_rtx;
    8907                 :           0 :           m->fs.fp_offset = m->fs.cfa_offset;
    8908                 :           0 :           m->fs.fp_valid = true;
    8909                 :           0 :         }
    8910                 :             :       else
    8911                 :             :         {
    8912                 :             :           /* The frame pointer is not needed so pop %ebp again.
    8913                 :             :              This leaves us with a pristine state.  */
    8914                 :           0 :           emit_insn (gen_pop (hard_frame_pointer_rtx));
    8915                 :             :         }
    8916                 :             :     }
    8917                 :             : 
    8918                 :             :   /* The first insn of a function that accepts its static chain on the
    8919                 :             :      stack is to push the register that would be filled in by a direct
    8920                 :             :      call.  This insn will be skipped by the trampoline.  */
    8921                 :     1433028 :   else if (ix86_static_chain_on_stack)
    8922                 :             :     {
    8923                 :           0 :       static_chain = ix86_static_chain (cfun->decl, false);
    8924                 :           0 :       insn = emit_insn (gen_push (static_chain));
    8925                 :           0 :       emit_insn (gen_blockage ());
    8926                 :             : 
    8927                 :             :       /* We don't want to interpret this push insn as a register save,
    8928                 :             :          only as a stack adjustment.  The real copy of the register as
    8929                 :             :          a save will be done later, if needed.  */
    8930                 :           0 :       t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8931                 :           0 :       t = gen_rtx_SET (stack_pointer_rtx, t);
    8932                 :           0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
    8933                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    8934                 :             :     }
    8935                 :             : 
    8936                 :             :   /* Emit prologue code to adjust stack alignment and setup DRAP, in case
    8937                 :             :      of DRAP is needed and stack realignment is really needed after reload */
    8938                 :     1433028 :   if (stack_realign_drap)
    8939                 :             :     {
    8940                 :        6899 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    8941                 :             : 
    8942                 :             :       /* Can't use DRAP in interrupt function.  */
    8943                 :        6899 :       if (cfun->machine->func_type != TYPE_NORMAL)
    8944                 :           0 :         sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
    8945                 :             :                "in interrupt service routine.  This may be worked "
    8946                 :             :                "around by avoiding functions with aggregate return.");
    8947                 :             : 
    8948                 :             :       /* Only need to push parameter pointer reg if it is caller saved.  */
    8949                 :        6899 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    8950                 :             :         {
    8951                 :             :           /* Push arg pointer reg */
    8952                 :         129 :           insn = emit_insn (gen_push (crtl->drap_reg));
    8953                 :         129 :           RTX_FRAME_RELATED_P (insn) = 1;
    8954                 :             :         }
    8955                 :             : 
    8956                 :             :       /* Grab the argument pointer.  */
    8957                 :        6899 :       t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
    8958                 :        6899 :       insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    8959                 :        6899 :       RTX_FRAME_RELATED_P (insn) = 1;
    8960                 :        6899 :       m->fs.cfa_reg = crtl->drap_reg;
    8961                 :        6899 :       m->fs.cfa_offset = 0;
    8962                 :             : 
    8963                 :             :       /* Align the stack.  */
    8964                 :        6899 :       insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
    8965                 :        6899 :                                        GEN_INT (-align_bytes)));
    8966                 :        6899 :       RTX_FRAME_RELATED_P (insn) = 1;
    8967                 :             : 
    8968                 :             :       /* Replicate the return address on the stack so that return
    8969                 :             :          address can be reached via (argp - 1) slot.  This is needed
    8970                 :             :          to implement macro RETURN_ADDR_RTX and intrinsic function
    8971                 :             :          expand_builtin_return_addr etc.  */
    8972                 :        7181 :       t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
    8973                 :        6899 :       t = gen_frame_mem (word_mode, t);
    8974                 :        6899 :       insn = emit_insn (gen_push (t));
    8975                 :        6899 :       RTX_FRAME_RELATED_P (insn) = 1;
    8976                 :             : 
    8977                 :             :       /* For the purposes of frame and register save area addressing,
    8978                 :             :          we've started over with a new frame.  */
    8979                 :        6899 :       m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    8980                 :        6899 :       m->fs.realigned = true;
    8981                 :             : 
    8982                 :        6899 :       if (static_chain)
    8983                 :             :         {
    8984                 :             :           /* Replicate static chain on the stack so that static chain
    8985                 :             :              can be reached via (argp - 2) slot.  This is needed for
    8986                 :             :              nested function with stack realignment.  */
    8987                 :           0 :           insn = emit_insn (gen_push (static_chain));
    8988                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8989                 :             :         }
    8990                 :             :     }
    8991                 :             : 
    8992                 :     1433028 :   int_registers_saved = (frame.nregs == 0);
    8993                 :     1433028 :   sse_registers_saved = (frame.nsseregs == 0);
    8994                 :     1433028 :   save_stub_call_needed = (m->call_ms2sysv);
    8995                 :     1433028 :   gcc_assert (sse_registers_saved || !save_stub_call_needed);
    8996                 :             : 
    8997                 :     1433028 :   if (frame_pointer_needed && !m->fs.fp_valid)
    8998                 :             :     {
    8999                 :             :       /* Note: AT&T enter does NOT have reversed args.  Enter is probably
    9000                 :             :          slower on all targets.  Also sdb didn't like it.  */
    9001                 :      469666 :       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
    9002                 :      469666 :       RTX_FRAME_RELATED_P (insn) = 1;
    9003                 :             : 
    9004                 :      469666 :       if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
    9005                 :             :         {
    9006                 :      469666 :           insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
    9007                 :      469666 :           RTX_FRAME_RELATED_P (insn) = 1;
    9008                 :             : 
    9009                 :      469666 :           if (m->fs.cfa_reg == stack_pointer_rtx)
    9010                 :      462767 :             m->fs.cfa_reg = hard_frame_pointer_rtx;
    9011                 :      469666 :           m->fs.fp_offset = m->fs.sp_offset;
    9012                 :      469666 :           m->fs.fp_valid = true;
    9013                 :             :         }
    9014                 :             :     }
    9015                 :             : 
    9016                 :     1433028 :   if (!int_registers_saved)
    9017                 :             :     {
    9018                 :             :       /* If saving registers via PUSH, do so now.  */
    9019                 :      414306 :       if (!frame.save_regs_using_mov)
    9020                 :             :         {
    9021                 :      414251 :           ix86_emit_save_regs ();
    9022                 :      414251 :           m->fs.apx_ppx_used = TARGET_APX_PPX && !crtl->calls_eh_return;
    9023                 :      414251 :           int_registers_saved = true;
    9024                 :      414251 :           gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
    9025                 :             :         }
    9026                 :             : 
    9027                 :             :       /* When using red zone we may start register saving before allocating
    9028                 :             :          the stack frame saving one cycle of the prologue.  However, avoid
    9029                 :             :          doing this if we have to probe the stack; at least on x86_64 the
    9030                 :             :          stack probe can turn into a call that clobbers a red zone location. */
    9031                 :          55 :       else if (ix86_using_red_zone ()
    9032                 :          55 :                && (! TARGET_STACK_PROBE
    9033                 :           0 :                    || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
    9034                 :             :         {
    9035                 :          55 :           ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9036                 :          55 :           cfun->machine->red_zone_used = true;
    9037                 :          55 :           int_registers_saved = true;
    9038                 :             :         }
    9039                 :             :     }
    9040                 :             : 
    9041                 :     1433028 :   if (frame.red_zone_size != 0)
    9042                 :      138273 :     cfun->machine->red_zone_used = true;
    9043                 :             : 
    9044                 :     1433028 :   if (stack_realign_fp)
    9045                 :             :     {
    9046                 :       25323 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9047                 :       25674 :       gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
    9048                 :             : 
    9049                 :             :       /* Record last valid frame pointer offset.  */
    9050                 :       25323 :       m->fs.sp_realigned_fp_last = frame.reg_save_offset;
    9051                 :             : 
    9052                 :             :       /* The computation of the size of the re-aligned stack frame means
    9053                 :             :          that we must allocate the size of the register save area before
    9054                 :             :          performing the actual alignment.  Otherwise we cannot guarantee
    9055                 :             :          that there's enough storage above the realignment point.  */
    9056                 :       25323 :       allocate = frame.reg_save_offset - m->fs.sp_offset
    9057                 :       25323 :                  + frame.stack_realign_allocate;
    9058                 :       25323 :       if (allocate)
    9059                 :        2691 :         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9060                 :             :                                    GEN_INT (-allocate), -1, false);
    9061                 :             : 
    9062                 :             :       /* Align the stack.  */
    9063                 :       25323 :       emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
    9064                 :       25323 :       m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
    9065                 :       25323 :       m->fs.sp_realigned_offset = m->fs.sp_offset
    9066                 :       25323 :                                               - frame.stack_realign_allocate;
    9067                 :             :       /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
    9068                 :             :          Beyond this point, stack access should be done via choose_baseaddr or
    9069                 :             :          by using sp_valid_at and fp_valid_at to determine the correct base
    9070                 :             :          register.  Henceforth, any CFA offset should be thought of as logical
    9071                 :             :          and not physical.  */
    9072                 :       25323 :       gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
    9073                 :       25323 :       gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
    9074                 :       25323 :       m->fs.sp_realigned = true;
    9075                 :             : 
    9076                 :             :       /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
    9077                 :             :          is needed to describe where a register is saved using a realigned
    9078                 :             :          stack pointer, so we need to invalidate the stack pointer for that
    9079                 :             :          target.  */
    9080                 :       25323 :       if (TARGET_SEH)
    9081                 :             :         m->fs.sp_valid = false;
    9082                 :             : 
    9083                 :             :       /* If SP offset is non-immediate after allocation of the stack frame,
    9084                 :             :          then emit SSE saves or stub call prior to allocating the rest of the
    9085                 :             :          stack frame.  This is less efficient for the out-of-line stub because
    9086                 :             :          we can't combine allocations across the call barrier, but it's better
    9087                 :             :          than using a scratch register.  */
    9088                 :       25323 :       else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
    9089                 :             :                                                    - m->fs.sp_realigned_offset),
    9090                 :       25323 :                                           Pmode))
    9091                 :             :         {
    9092                 :           3 :           if (!sse_registers_saved)
    9093                 :             :             {
    9094                 :           1 :               ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9095                 :           1 :               sse_registers_saved = true;
    9096                 :             :             }
    9097                 :           2 :           else if (save_stub_call_needed)
    9098                 :             :             {
    9099                 :           1 :               ix86_emit_outlined_ms2sysv_save (frame);
    9100                 :           1 :               save_stub_call_needed = false;
    9101                 :             :             }
    9102                 :             :         }
    9103                 :             :     }
    9104                 :             : 
    9105                 :     1433028 :   allocate = frame.stack_pointer_offset - m->fs.sp_offset;
    9106                 :             : 
    9107                 :     1433028 :   if (flag_stack_usage_info)
    9108                 :             :     {
    9109                 :             :       /* We start to count from ARG_POINTER.  */
    9110                 :         355 :       HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
    9111                 :             : 
    9112                 :             :       /* If it was realigned, take into account the fake frame.  */
    9113                 :         355 :       if (stack_realign_drap)
    9114                 :             :         {
    9115                 :           1 :           if (ix86_static_chain_on_stack)
    9116                 :           0 :             stack_size += UNITS_PER_WORD;
    9117                 :             : 
    9118                 :           1 :           if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9119                 :           0 :             stack_size += UNITS_PER_WORD;
    9120                 :             : 
    9121                 :             :           /* This over-estimates by 1 minimal-stack-alignment-unit but
    9122                 :             :              mitigates that by counting in the new return address slot.  */
    9123                 :           1 :           current_function_dynamic_stack_size
    9124                 :           1 :             += crtl->stack_alignment_needed / BITS_PER_UNIT;
    9125                 :             :         }
    9126                 :             : 
    9127                 :         355 :       current_function_static_stack_size = stack_size;
    9128                 :             :     }
    9129                 :             : 
    9130                 :             :   /* On SEH target with very large frame size, allocate an area to save
    9131                 :             :      SSE registers (as the very large allocation won't be described).  */
    9132                 :     1433028 :   if (TARGET_SEH
    9133                 :             :       && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
    9134                 :             :       && !sse_registers_saved)
    9135                 :             :     {
    9136                 :             :       HOST_WIDE_INT sse_size
    9137                 :             :         = frame.sse_reg_save_offset - frame.reg_save_offset;
    9138                 :             : 
    9139                 :             :       gcc_assert (int_registers_saved);
    9140                 :             : 
    9141                 :             :       /* No need to do stack checking as the area will be immediately
    9142                 :             :          written.  */
    9143                 :             :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9144                 :             :                                  GEN_INT (-sse_size), -1,
    9145                 :             :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9146                 :             :       allocate -= sse_size;
    9147                 :             :       ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9148                 :             :       sse_registers_saved = true;
    9149                 :             :     }
    9150                 :             : 
    9151                 :             :   /* If stack clash protection is requested, then probe the stack, unless it
    9152                 :             :      is already probed on the target.  */
    9153                 :     1433028 :   if (allocate >= 0
    9154                 :     1433024 :       && flag_stack_clash_protection
    9155                 :     1433108 :       && !ix86_target_stack_probe ())
    9156                 :             :     {
    9157                 :          80 :       ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
    9158                 :          80 :       allocate = 0;
    9159                 :             :     }
    9160                 :             : 
    9161                 :             :   /* The stack has already been decremented by the instruction calling us
    9162                 :             :      so probe if the size is non-negative to preserve the protection area.  */
    9163                 :     1432948 :   else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    9164                 :             :     {
    9165                 :          45 :       const HOST_WIDE_INT probe_interval = get_probe_interval ();
    9166                 :             : 
    9167                 :          45 :       if (STACK_CHECK_MOVING_SP)
    9168                 :             :         {
    9169                 :          45 :           if (crtl->is_leaf
    9170                 :          17 :               && !cfun->calls_alloca
    9171                 :          17 :               && allocate <= probe_interval)
    9172                 :             :             ;
    9173                 :             : 
    9174                 :             :           else
    9175                 :             :             {
    9176                 :          29 :               ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
    9177                 :          29 :               allocate = 0;
    9178                 :             :             }
    9179                 :             :         }
    9180                 :             : 
    9181                 :             :       else
    9182                 :             :         {
    9183                 :             :           HOST_WIDE_INT size = allocate;
    9184                 :             : 
    9185                 :             :           if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
    9186                 :             :             size = 0x80000000 - get_stack_check_protect () - 1;
    9187                 :             : 
    9188                 :             :           if (TARGET_STACK_PROBE)
    9189                 :             :             {
    9190                 :             :               if (crtl->is_leaf && !cfun->calls_alloca)
    9191                 :             :                 {
    9192                 :             :                   if (size > probe_interval)
    9193                 :             :                     ix86_emit_probe_stack_range (0, size, int_registers_saved);
    9194                 :             :                 }
    9195                 :             :               else
    9196                 :             :                 ix86_emit_probe_stack_range (0,
    9197                 :             :                                              size + get_stack_check_protect (),
    9198                 :             :                                              int_registers_saved);
    9199                 :             :             }
    9200                 :             :           else
    9201                 :             :             {
    9202                 :             :               if (crtl->is_leaf && !cfun->calls_alloca)
    9203                 :             :                 {
    9204                 :             :                   if (size > probe_interval
    9205                 :             :                       && size > get_stack_check_protect ())
    9206                 :             :                     ix86_emit_probe_stack_range (get_stack_check_protect (),
    9207                 :             :                                                  (size
    9208                 :             :                                                   - get_stack_check_protect ()),
    9209                 :             :                                                  int_registers_saved);
    9210                 :             :                 }
    9211                 :             :               else
    9212                 :             :                 ix86_emit_probe_stack_range (get_stack_check_protect (), size,
    9213                 :             :                                              int_registers_saved);
    9214                 :             :             }
    9215                 :             :         }
    9216                 :             :     }
    9217                 :             : 
    9218                 :     1433024 :   if (allocate == 0)
    9219                 :             :     ;
    9220                 :      810953 :   else if (!ix86_target_stack_probe ()
    9221                 :      810953 :            || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
    9222                 :             :     {
    9223                 :      810909 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9224                 :             :                                  GEN_INT (-allocate), -1,
    9225                 :      810909 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9226                 :             :     }
    9227                 :             :   else
    9228                 :             :     {
    9229                 :          44 :       rtx eax = gen_rtx_REG (Pmode, AX_REG);
    9230                 :          44 :       rtx r10 = NULL;
    9231                 :          44 :       const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
    9232                 :          44 :       bool eax_live = ix86_eax_live_at_start_p ();
    9233                 :          44 :       bool r10_live = false;
    9234                 :             : 
    9235                 :          44 :       if (TARGET_64BIT)
    9236                 :          44 :         r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
    9237                 :             : 
    9238                 :          44 :       if (eax_live)
    9239                 :             :         {
    9240                 :           0 :           insn = emit_insn (gen_push (eax));
    9241                 :           0 :           allocate -= UNITS_PER_WORD;
    9242                 :             :           /* Note that SEH directives need to continue tracking the stack
    9243                 :             :              pointer even after the frame pointer has been set up.  */
    9244                 :           0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9245                 :             :             {
    9246                 :           0 :               if (sp_is_cfa_reg)
    9247                 :           0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9248                 :           0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9249                 :           0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9250                 :           0 :                             gen_rtx_SET (stack_pointer_rtx,
    9251                 :             :                                          plus_constant (Pmode,
    9252                 :             :                                                         stack_pointer_rtx,
    9253                 :             :                                                         -UNITS_PER_WORD)));
    9254                 :             :             }
    9255                 :             :         }
    9256                 :             : 
    9257                 :          44 :       if (r10_live)
    9258                 :             :         {
    9259                 :           0 :           r10 = gen_rtx_REG (Pmode, R10_REG);
    9260                 :           0 :           insn = emit_insn (gen_push (r10));
    9261                 :           0 :           allocate -= UNITS_PER_WORD;
    9262                 :           0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9263                 :             :             {
    9264                 :           0 :               if (sp_is_cfa_reg)
    9265                 :           0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9266                 :           0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9267                 :           0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9268                 :           0 :                             gen_rtx_SET (stack_pointer_rtx,
    9269                 :             :                                          plus_constant (Pmode,
    9270                 :             :                                                         stack_pointer_rtx,
    9271                 :             :                                                         -UNITS_PER_WORD)));
    9272                 :             :             }
    9273                 :             :         }
    9274                 :             : 
    9275                 :          44 :       emit_move_insn (eax, GEN_INT (allocate));
    9276                 :          44 :       emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
    9277                 :             : 
    9278                 :             :       /* Use the fact that AX still contains ALLOCATE.  */
    9279                 :          44 :       insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
    9280                 :          44 :                         (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
    9281                 :             : 
    9282                 :          44 :       if (sp_is_cfa_reg || TARGET_SEH)
    9283                 :             :         {
    9284                 :          36 :           if (sp_is_cfa_reg)
    9285                 :          36 :             m->fs.cfa_offset += allocate;
    9286                 :          36 :           RTX_FRAME_RELATED_P (insn) = 1;
    9287                 :          36 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9288                 :          36 :                         gen_rtx_SET (stack_pointer_rtx,
    9289                 :             :                                      plus_constant (Pmode, stack_pointer_rtx,
    9290                 :             :                                                     -allocate)));
    9291                 :             :         }
    9292                 :          44 :       m->fs.sp_offset += allocate;
    9293                 :             : 
    9294                 :             :       /* Use stack_pointer_rtx for relative addressing so that code works for
    9295                 :             :          realigned stack.  But this means that we need a blockage to prevent
    9296                 :             :          stores based on the frame pointer from being scheduled before.  */
    9297                 :          44 :       if (r10_live && eax_live)
    9298                 :             :         {
    9299                 :           0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9300                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
    9301                 :             :                           gen_frame_mem (word_mode, t));
    9302                 :           0 :           t = plus_constant (Pmode, t, UNITS_PER_WORD);
    9303                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
    9304                 :             :                           gen_frame_mem (word_mode, t));
    9305                 :           0 :           emit_insn (gen_memory_blockage ());
    9306                 :             :         }
    9307                 :          44 :       else if (eax_live || r10_live)
    9308                 :             :         {
    9309                 :           0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9310                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode,
    9311                 :             :                                        (eax_live ? AX_REG : R10_REG)),
    9312                 :             :                           gen_frame_mem (word_mode, t));
    9313                 :           0 :           emit_insn (gen_memory_blockage ());
    9314                 :             :         }
    9315                 :             :     }
    9316                 :     1433028 :   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
    9317                 :             : 
    9318                 :             :   /* If we havn't already set up the frame pointer, do so now.  */
    9319                 :     1433028 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9320                 :             :     {
    9321                 :           0 :       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
    9322                 :           0 :                             GEN_INT (frame.stack_pointer_offset
    9323                 :             :                                      - frame.hard_frame_pointer_offset));
    9324                 :           0 :       insn = emit_insn (insn);
    9325                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9326                 :           0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
    9327                 :             : 
    9328                 :           0 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9329                 :           0 :         m->fs.cfa_reg = hard_frame_pointer_rtx;
    9330                 :           0 :       m->fs.fp_offset = frame.hard_frame_pointer_offset;
    9331                 :           0 :       m->fs.fp_valid = true;
    9332                 :             :     }
    9333                 :             : 
    9334                 :     1433028 :   if (!int_registers_saved)
    9335                 :           0 :     ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9336                 :     1433028 :   if (!sse_registers_saved)
    9337                 :       33152 :     ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9338                 :     1399876 :   else if (save_stub_call_needed)
    9339                 :        7044 :     ix86_emit_outlined_ms2sysv_save (frame);
    9340                 :             : 
    9341                 :             :   /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
    9342                 :             :      in PROLOGUE.  */
    9343                 :     1433028 :   if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
    9344                 :             :     {
    9345                 :           0 :       rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
    9346                 :           0 :       insn = emit_insn (gen_set_got (pic));
    9347                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9348                 :           0 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    9349                 :           0 :       emit_insn (gen_prologue_use (pic));
    9350                 :             :       /* Deleting already emmitted SET_GOT if exist and allocated to
    9351                 :             :          REAL_PIC_OFFSET_TABLE_REGNUM.  */
    9352                 :           0 :       ix86_elim_entry_set_got (pic);
    9353                 :             :     }
    9354                 :             : 
    9355                 :     1433028 :   if (crtl->drap_reg && !crtl->stack_realign_needed)
    9356                 :             :     {
    9357                 :             :       /* vDRAP is setup but after reload it turns out stack realign
    9358                 :             :          isn't necessary, here we will emit prologue to setup DRAP
    9359                 :             :          without stack realign adjustment */
    9360                 :         180 :       t = choose_baseaddr (0, NULL);
    9361                 :         180 :       emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9362                 :             :     }
    9363                 :             : 
    9364                 :             :   /* Prevent instructions from being scheduled into register save push
    9365                 :             :      sequence when access to the redzone area is done through frame pointer.
    9366                 :             :      The offset between the frame pointer and the stack pointer is calculated
    9367                 :             :      relative to the value of the stack pointer at the end of the function
    9368                 :             :      prologue, and moving instructions that access redzone area via frame
    9369                 :             :      pointer inside push sequence violates this assumption.  */
    9370                 :     1433028 :   if (frame_pointer_needed && frame.red_zone_size)
    9371                 :      128107 :     emit_insn (gen_memory_blockage ());
    9372                 :             : 
    9373                 :             :   /* SEH requires that the prologue end within 256 bytes of the start of
    9374                 :             :      the function.  Prevent instruction schedules that would extend that.
    9375                 :             :      Further, prevent alloca modifications to the stack pointer from being
    9376                 :             :      combined with prologue modifications.  */
    9377                 :             :   if (TARGET_SEH)
    9378                 :             :     emit_insn (gen_prologue_use (stack_pointer_rtx));
    9379                 :             : }
    9380                 :             : 
    9381                 :             : /* Emit code to restore REG using a POP or POPP insn.  */
    9382                 :             : 
    9383                 :             : static void
    9384                 :     1445241 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
    9385                 :             : {
    9386                 :     1445241 :   struct machine_function *m = cfun->machine;
    9387                 :     1445241 :   rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
    9388                 :             : 
    9389                 :     1445241 :   ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
    9390                 :     1445241 :   m->fs.sp_offset -= UNITS_PER_WORD;
    9391                 :             : 
    9392                 :     1445241 :   if (m->fs.cfa_reg == crtl->drap_reg
    9393                 :     1445241 :       && REGNO (reg) == REGNO (crtl->drap_reg))
    9394                 :             :     {
    9395                 :             :       /* Previously we'd represented the CFA as an expression
    9396                 :             :          like *(%ebp - 8).  We've just popped that value from
    9397                 :             :          the stack, which means we need to reset the CFA to
    9398                 :             :          the drap register.  This will remain until we restore
    9399                 :             :          the stack pointer.  */
    9400                 :        3955 :       add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9401                 :        3955 :       RTX_FRAME_RELATED_P (insn) = 1;
    9402                 :             : 
    9403                 :             :       /* This means that the DRAP register is valid for addressing too.  */
    9404                 :        3955 :       m->fs.drap_valid = true;
    9405                 :        3955 :       return;
    9406                 :             :     }
    9407                 :             : 
    9408                 :     1441286 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9409                 :             :     {
    9410                 :     1194053 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    9411                 :     1002389 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9412                 :     1002389 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9413                 :     1002389 :       RTX_FRAME_RELATED_P (insn) = 1;
    9414                 :             : 
    9415                 :     1194053 :       m->fs.cfa_offset -= UNITS_PER_WORD;
    9416                 :             :     }
    9417                 :             : 
    9418                 :             :   /* When the frame pointer is the CFA, and we pop it, we are
    9419                 :             :      swapping back to the stack pointer as the CFA.  This happens
    9420                 :             :      for stack frames that don't allocate other data, so we assume
    9421                 :             :      the stack pointer is now pointing at the return address, i.e.
    9422                 :             :      the function entry state, which makes the offset be 1 word.  */
    9423                 :     1441286 :   if (reg == hard_frame_pointer_rtx)
    9424                 :             :     {
    9425                 :      233841 :       m->fs.fp_valid = false;
    9426                 :      233841 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9427                 :             :         {
    9428                 :      229873 :           m->fs.cfa_reg = stack_pointer_rtx;
    9429                 :      229873 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    9430                 :             : 
    9431                 :      229873 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9432                 :      229873 :                         plus_constant (Pmode, stack_pointer_rtx,
    9433                 :      229873 :                                        m->fs.cfa_offset));
    9434                 :      229873 :           RTX_FRAME_RELATED_P (insn) = 1;
    9435                 :             :         }
    9436                 :             :     }
    9437                 :             : }
    9438                 :             : 
    9439                 :             : /* Emit code to restore REG using a POP2 insn.  */
    9440                 :             : static void
    9441                 :          17 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
    9442                 :             : {
    9443                 :          17 :   struct machine_function *m = cfun->machine;
    9444                 :          17 :   const int offset = UNITS_PER_WORD * 2;
    9445                 :          17 :   rtx_insn *insn;
    9446                 :             : 
    9447                 :          17 :   rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
    9448                 :             :                                                    stack_pointer_rtx));
    9449                 :             : 
    9450                 :          17 :   if (ppx_p)
    9451                 :          13 :     insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
    9452                 :             :   else
    9453                 :           4 :     insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
    9454                 :             : 
    9455                 :          17 :   RTX_FRAME_RELATED_P (insn) = 1;
    9456                 :             : 
    9457                 :          17 :   rtx dwarf = NULL_RTX;
    9458                 :          17 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
    9459                 :          17 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
    9460                 :          17 :   REG_NOTES (insn) = dwarf;
    9461                 :          17 :   m->fs.sp_offset -= offset;
    9462                 :             : 
    9463                 :          17 :   if (m->fs.cfa_reg == crtl->drap_reg
    9464                 :          17 :       && (REGNO (reg1) == REGNO (crtl->drap_reg)
    9465                 :           3 :           || REGNO (reg2) == REGNO (crtl->drap_reg)))
    9466                 :             :     {
    9467                 :             :       /* Previously we'd represented the CFA as an expression
    9468                 :             :          like *(%ebp - 8).  We've just popped that value from
    9469                 :             :          the stack, which means we need to reset the CFA to
    9470                 :             :          the drap register.  This will remain until we restore
    9471                 :             :          the stack pointer.  */
    9472                 :           1 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9473                 :           1 :                     REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
    9474                 :           1 :       RTX_FRAME_RELATED_P (insn) = 1;
    9475                 :             : 
    9476                 :             :       /* This means that the DRAP register is valid for addressing too.  */
    9477                 :           1 :       m->fs.drap_valid = true;
    9478                 :           1 :       return;
    9479                 :             :     }
    9480                 :             : 
    9481                 :          16 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9482                 :             :     {
    9483                 :          12 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    9484                 :          12 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9485                 :          12 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9486                 :          12 :       RTX_FRAME_RELATED_P (insn) = 1;
    9487                 :             : 
    9488                 :          12 :       m->fs.cfa_offset -= offset;
    9489                 :             :     }
    9490                 :             : 
    9491                 :             :   /* When the frame pointer is the CFA, and we pop it, we are
    9492                 :             :      swapping back to the stack pointer as the CFA.  This happens
    9493                 :             :      for stack frames that don't allocate other data, so we assume
    9494                 :             :      the stack pointer is now pointing at the return address, i.e.
    9495                 :             :      the function entry state, which makes the offset be 1 word.  */
    9496                 :          16 :   if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
    9497                 :             :     {
    9498                 :           0 :       m->fs.fp_valid = false;
    9499                 :           0 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9500                 :             :         {
    9501                 :           0 :           m->fs.cfa_reg = stack_pointer_rtx;
    9502                 :           0 :           m->fs.cfa_offset -= offset;
    9503                 :             : 
    9504                 :           0 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9505                 :           0 :                         plus_constant (Pmode, stack_pointer_rtx,
    9506                 :           0 :                                        m->fs.cfa_offset));
    9507                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9508                 :             :         }
    9509                 :             :     }
    9510                 :             : }
    9511                 :             : 
    9512                 :             : /* Emit code to restore saved registers using POP insns.  */
    9513                 :             : 
    9514                 :             : static void
    9515                 :     1310248 : ix86_emit_restore_regs_using_pop (bool ppx_p)
    9516                 :             : {
    9517                 :     1310248 :   unsigned int regno;
    9518                 :             : 
    9519                 :   121853064 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9520                 :   120542816 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
    9521                 :     1211169 :       ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
    9522                 :     1310248 : }
    9523                 :             : 
    9524                 :             : /* Emit code to restore saved registers using POP2 insns.  */
    9525                 :             : 
    9526                 :             : static void
    9527                 :         442 : ix86_emit_restore_regs_using_pop2 (void)
    9528                 :             : {
    9529                 :         442 :   int regno;
    9530                 :         442 :   int regno_list[2];
    9531                 :         442 :   regno_list[0] = regno_list[1] = -1;
    9532                 :         442 :   int loaded_regnum = 0;
    9533                 :         442 :   bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    9534                 :             : 
    9535                 :       41106 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9536                 :       40664 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
    9537                 :             :       {
    9538                 :          49 :         if (aligned)
    9539                 :             :           {
    9540                 :          40 :             regno_list[loaded_regnum++] = regno;
    9541                 :          40 :             if (loaded_regnum == 2)
    9542                 :             :               {
    9543                 :          17 :                 gcc_assert (regno_list[0] != -1
    9544                 :             :                             && regno_list[1] != -1
    9545                 :             :                             && regno_list[0] != regno_list[1]);
    9546                 :             : 
    9547                 :          17 :                 ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
    9548                 :             :                                                                regno_list[0]),
    9549                 :             :                                                   gen_rtx_REG (word_mode,
    9550                 :             :                                                                regno_list[1]),
    9551                 :          17 :                                                   TARGET_APX_PPX);
    9552                 :          17 :                 loaded_regnum = 0;
    9553                 :          17 :                 regno_list[0] = regno_list[1] = -1;
    9554                 :             :               }
    9555                 :             :           }
    9556                 :             :         else
    9557                 :             :           {
    9558                 :          18 :             ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
    9559                 :           9 :                                              TARGET_APX_PPX);
    9560                 :           9 :             aligned = true;
    9561                 :             :           }
    9562                 :             :       }
    9563                 :             : 
    9564                 :         442 :   if (loaded_regnum == 1)
    9565                 :           6 :     ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
    9566                 :           6 :                                      TARGET_APX_PPX);
    9567                 :         442 : }
    9568                 :             : 
    9569                 :             : /* Emit code and notes for the LEAVE instruction.  If insn is non-null,
    9570                 :             :    omits the emit and only attaches the notes.  */
    9571                 :             : 
    9572                 :             : static void
    9573                 :      236849 : ix86_emit_leave (rtx_insn *insn)
    9574                 :             : {
    9575                 :      236849 :   struct machine_function *m = cfun->machine;
    9576                 :             : 
    9577                 :      236849 :   if (!insn)
    9578                 :      235878 :     insn = emit_insn (gen_leave (word_mode));
    9579                 :             : 
    9580                 :      236849 :   ix86_add_queued_cfa_restore_notes (insn);
    9581                 :             : 
    9582                 :      236849 :   gcc_assert (m->fs.fp_valid);
    9583                 :      236849 :   m->fs.sp_valid = true;
    9584                 :      236849 :   m->fs.sp_realigned = false;
    9585                 :      236849 :   m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
    9586                 :      236849 :   m->fs.fp_valid = false;
    9587                 :             : 
    9588                 :      236849 :   if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9589                 :             :     {
    9590                 :      233819 :       m->fs.cfa_reg = stack_pointer_rtx;
    9591                 :      233819 :       m->fs.cfa_offset = m->fs.sp_offset;
    9592                 :             : 
    9593                 :      233819 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9594                 :      233819 :                     plus_constant (Pmode, stack_pointer_rtx,
    9595                 :      233819 :                                    m->fs.sp_offset));
    9596                 :      233819 :       RTX_FRAME_RELATED_P (insn) = 1;
    9597                 :             :     }
    9598                 :      236849 :   ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
    9599                 :             :                              m->fs.fp_offset);
    9600                 :      236849 : }
    9601                 :             : 
    9602                 :             : /* Emit code to restore saved registers using MOV insns.
    9603                 :             :    First register is restored from CFA - CFA_OFFSET.  */
    9604                 :             : static void
    9605                 :       41936 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
    9606                 :             :                                   bool maybe_eh_return)
    9607                 :             : {
    9608                 :       41936 :   struct machine_function *m = cfun->machine;
    9609                 :       41936 :   unsigned int regno;
    9610                 :             : 
    9611                 :     3900048 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9612                 :     3858112 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
    9613                 :             :       {
    9614                 :       42155 :         rtx reg = gen_rtx_REG (word_mode, regno);
    9615                 :       42155 :         rtx mem;
    9616                 :       42155 :         rtx_insn *insn;
    9617                 :             : 
    9618                 :       42155 :         mem = choose_baseaddr (cfa_offset, NULL);
    9619                 :       42155 :         mem = gen_frame_mem (word_mode, mem);
    9620                 :       42155 :         insn = emit_move_insn (reg, mem);
    9621                 :             : 
    9622                 :       42155 :         if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
    9623                 :             :           {
    9624                 :             :             /* Previously we'd represented the CFA as an expression
    9625                 :             :                like *(%ebp - 8).  We've just popped that value from
    9626                 :             :                the stack, which means we need to reset the CFA to
    9627                 :             :                the drap register.  This will remain until we restore
    9628                 :             :                the stack pointer.  */
    9629                 :        3030 :             add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9630                 :        3030 :             RTX_FRAME_RELATED_P (insn) = 1;
    9631                 :             : 
    9632                 :             :             /* This means that the DRAP register is valid for addressing.  */
    9633                 :        3030 :             m->fs.drap_valid = true;
    9634                 :             :           }
    9635                 :             :         else
    9636                 :       39125 :           ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
    9637                 :             : 
    9638                 :       44011 :         cfa_offset -= UNITS_PER_WORD;
    9639                 :             :       }
    9640                 :       41936 : }
    9641                 :             : 
    9642                 :             : /* Emit code to restore saved registers using MOV insns.
    9643                 :             :    First register is restored from CFA - CFA_OFFSET.  */
    9644                 :             : static void
    9645                 :       33729 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
    9646                 :             :                                       bool maybe_eh_return)
    9647                 :             : {
    9648                 :       33729 :   unsigned int regno;
    9649                 :             : 
    9650                 :     3136797 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9651                 :     3103068 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
    9652                 :             :       {
    9653                 :      337281 :         rtx reg = gen_rtx_REG (V4SFmode, regno);
    9654                 :      337281 :         rtx mem;
    9655                 :      337281 :         unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
    9656                 :             : 
    9657                 :      337281 :         mem = choose_baseaddr (cfa_offset, &align);
    9658                 :      337281 :         mem = gen_rtx_MEM (V4SFmode, mem);
    9659                 :             : 
    9660                 :             :         /* The location aligment depends upon the base register.  */
    9661                 :      337281 :         align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
    9662                 :      337281 :         gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    9663                 :      337281 :         set_mem_align (mem, align);
    9664                 :      337281 :         emit_insn (gen_rtx_SET (reg, mem));
    9665                 :             : 
    9666                 :      337281 :         ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
    9667                 :             : 
    9668                 :      337281 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    9669                 :             :       }
    9670                 :       33729 : }
    9671                 :             : 
    9672                 :             : static void
    9673                 :        7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
    9674                 :             :                                   bool use_call, int style)
    9675                 :             : {
    9676                 :        7621 :   struct machine_function *m = cfun->machine;
    9677                 :        7621 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    9678                 :        7621 :                           + m->call_ms2sysv_extra_regs;
    9679                 :        7621 :   rtvec v;
    9680                 :        7621 :   unsigned int elems_needed, align, i, vi = 0;
    9681                 :        7621 :   rtx_insn *insn;
    9682                 :        7621 :   rtx sym, tmp;
    9683                 :        7621 :   rtx rsi = gen_rtx_REG (word_mode, SI_REG);
    9684                 :        7621 :   rtx r10 = NULL_RTX;
    9685                 :        7621 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    9686                 :        7621 :   HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
    9687                 :        7621 :   HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
    9688                 :        7621 :   rtx rsi_frame_load = NULL_RTX;
    9689                 :        7621 :   HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
    9690                 :        7621 :   enum xlogue_stub stub;
    9691                 :             : 
    9692                 :        7621 :   gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
    9693                 :             : 
    9694                 :             :   /* If using a realigned stack, we should never start with padding.  */
    9695                 :        7621 :   gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
    9696                 :             : 
    9697                 :             :   /* Setup RSI as the stub's base pointer.  */
    9698                 :        7621 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    9699                 :        7621 :   tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
    9700                 :        7621 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    9701                 :             : 
    9702                 :        7621 :   emit_insn (gen_rtx_SET (rsi, tmp));
    9703                 :             : 
    9704                 :             :   /* Get a symbol for the stub.  */
    9705                 :        7621 :   if (frame_pointer_needed)
    9706                 :        5955 :     stub = use_call ? XLOGUE_STUB_RESTORE_HFP
    9707                 :             :                     : XLOGUE_STUB_RESTORE_HFP_TAIL;
    9708                 :             :   else
    9709                 :        1666 :     stub = use_call ? XLOGUE_STUB_RESTORE
    9710                 :             :                     : XLOGUE_STUB_RESTORE_TAIL;
    9711                 :        7621 :   sym = xlogue.get_stub_rtx (stub);
    9712                 :             : 
    9713                 :        7621 :   elems_needed = ncregs;
    9714                 :        7621 :   if (use_call)
    9715                 :        6498 :     elems_needed += 1;
    9716                 :             :   else
    9717                 :        1275 :     elems_needed += frame_pointer_needed ? 5 : 3;
    9718                 :        7621 :   v = rtvec_alloc (elems_needed);
    9719                 :             : 
    9720                 :             :   /* We call the epilogue stub when we need to pop incoming args or we are
    9721                 :             :      doing a sibling call as the tail.  Otherwise, we will emit a jmp to the
    9722                 :             :      epilogue stub and it is the tail-call.  */
    9723                 :        7621 :   if (use_call)
    9724                 :        6498 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9725                 :             :   else
    9726                 :             :     {
    9727                 :        1123 :       RTVEC_ELT (v, vi++) = ret_rtx;
    9728                 :        1123 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9729                 :        1123 :       if (frame_pointer_needed)
    9730                 :             :         {
    9731                 :         971 :           rtx rbp = gen_rtx_REG (DImode, BP_REG);
    9732                 :         971 :           gcc_assert (m->fs.fp_valid);
    9733                 :         971 :           gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
    9734                 :             : 
    9735                 :         971 :           tmp = plus_constant (DImode, rbp, 8);
    9736                 :         971 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
    9737                 :         971 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
    9738                 :         971 :           tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
    9739                 :         971 :           RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
    9740                 :             :         }
    9741                 :             :       else
    9742                 :             :         {
    9743                 :             :           /* If no hard frame pointer, we set R10 to the SP restore value.  */
    9744                 :         152 :           gcc_assert (!m->fs.fp_valid);
    9745                 :         152 :           gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
    9746                 :         152 :           gcc_assert (m->fs.sp_valid);
    9747                 :             : 
    9748                 :         152 :           r10 = gen_rtx_REG (DImode, R10_REG);
    9749                 :         152 :           tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
    9750                 :         152 :           emit_insn (gen_rtx_SET (r10, tmp));
    9751                 :             : 
    9752                 :         152 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
    9753                 :             :         }
    9754                 :             :     }
    9755                 :             : 
    9756                 :             :   /* Generate frame load insns and restore notes.  */
    9757                 :      107954 :   for (i = 0; i < ncregs; ++i)
    9758                 :             :     {
    9759                 :      100333 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    9760                 :      100333 :       machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
    9761                 :      100333 :       rtx reg, frame_load;
    9762                 :             : 
    9763                 :      100333 :       reg = gen_rtx_REG (mode, r.regno);
    9764                 :      100333 :       frame_load = gen_frame_load (reg, rsi, r.offset);
    9765                 :             : 
    9766                 :             :       /* Save RSI frame load insn & note to add last.  */
    9767                 :      100333 :       if (r.regno == SI_REG)
    9768                 :             :         {
    9769                 :        7621 :           gcc_assert (!rsi_frame_load);
    9770                 :        7621 :           rsi_frame_load = frame_load;
    9771                 :        7621 :           rsi_restore_offset = r.offset;
    9772                 :             :         }
    9773                 :             :       else
    9774                 :             :         {
    9775                 :       92712 :           RTVEC_ELT (v, vi++) = frame_load;
    9776                 :       92712 :           ix86_add_cfa_restore_note (NULL, reg, r.offset);
    9777                 :             :         }
    9778                 :             :     }
    9779                 :             : 
    9780                 :             :   /* Add RSI frame load & restore note at the end.  */
    9781                 :        7621 :   gcc_assert (rsi_frame_load);
    9782                 :        7621 :   gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
    9783                 :        7621 :   RTVEC_ELT (v, vi++) = rsi_frame_load;
    9784                 :        7621 :   ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
    9785                 :             :                              rsi_restore_offset);
    9786                 :             : 
    9787                 :             :   /* Finally, for tail-call w/o a hard frame pointer, set SP to R10.  */
    9788                 :        7621 :   if (!use_call && !frame_pointer_needed)
    9789                 :             :     {
    9790                 :         152 :       gcc_assert (m->fs.sp_valid);
    9791                 :         152 :       gcc_assert (!m->fs.sp_realigned);
    9792                 :             : 
    9793                 :             :       /* At this point, R10 should point to frame.stack_realign_offset.  */
    9794                 :         152 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9795                 :         152 :         m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
    9796                 :         152 :       m->fs.sp_offset = frame.stack_realign_offset;
    9797                 :             :     }
    9798                 :             : 
    9799                 :        7621 :   gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
    9800                 :        7621 :   tmp = gen_rtx_PARALLEL (VOIDmode, v);
    9801                 :        7621 :   if (use_call)
    9802                 :        6498 :       insn = emit_insn (tmp);
    9803                 :             :   else
    9804                 :             :     {
    9805                 :        1123 :       insn = emit_jump_insn (tmp);
    9806                 :        1123 :       JUMP_LABEL (insn) = ret_rtx;
    9807                 :             : 
    9808                 :        1123 :       if (frame_pointer_needed)
    9809                 :         971 :         ix86_emit_leave (insn);
    9810                 :             :       else
    9811                 :             :         {
    9812                 :             :           /* Need CFA adjust note.  */
    9813                 :         152 :           tmp = gen_rtx_SET (stack_pointer_rtx, r10);
    9814                 :         152 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
    9815                 :             :         }
    9816                 :             :     }
    9817                 :             : 
    9818                 :        7621 :   RTX_FRAME_RELATED_P (insn) = true;
    9819                 :        7621 :   ix86_add_queued_cfa_restore_notes (insn);
    9820                 :             : 
    9821                 :             :   /* If we're not doing a tail-call, we need to adjust the stack.  */
    9822                 :        7621 :   if (use_call && m->fs.sp_valid)
    9823                 :             :     {
    9824                 :        3706 :       HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
    9825                 :        3706 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9826                 :             :                                 GEN_INT (dealloc), style,
    9827                 :        3706 :                                 m->fs.cfa_reg == stack_pointer_rtx);
    9828                 :             :     }
    9829                 :        7621 : }
    9830                 :             : 
    9831                 :             : /* Restore function stack, frame, and registers.  */
    9832                 :             : 
    9833                 :             : void
    9834                 :     1547918 : ix86_expand_epilogue (int style)
    9835                 :             : {
    9836                 :     1547918 :   struct machine_function *m = cfun->machine;
    9837                 :     1547918 :   struct machine_frame_state frame_state_save = m->fs;
    9838                 :     1547918 :   bool restore_regs_via_mov;
    9839                 :     1547918 :   bool using_drap;
    9840                 :     1547918 :   bool restore_stub_is_tail = false;
    9841                 :             : 
    9842                 :     1547918 :   if (ix86_function_naked (current_function_decl))
    9843                 :             :     {
    9844                 :             :       /* The program should not reach this point.  */
    9845                 :          74 :       emit_insn (gen_ud2 ());
    9846                 :      114935 :       return;
    9847                 :             :     }
    9848                 :             : 
    9849                 :     1547844 :   ix86_finalize_stack_frame_flags ();
    9850                 :     1547844 :   const struct ix86_frame &frame = cfun->machine->frame;
    9851                 :             : 
    9852                 :     1547844 :   m->fs.sp_realigned = stack_realign_fp;
    9853                 :       32359 :   m->fs.sp_valid = stack_realign_fp
    9854                 :     1522471 :                    || !frame_pointer_needed
    9855                 :     1993188 :                    || crtl->sp_is_unchanging;
    9856                 :     1547844 :   gcc_assert (!m->fs.sp_valid
    9857                 :             :               || m->fs.sp_offset == frame.stack_pointer_offset);
    9858                 :             : 
    9859                 :             :   /* The FP must be valid if the frame pointer is present.  */
    9860                 :     1547844 :   gcc_assert (frame_pointer_needed == m->fs.fp_valid);
    9861                 :     1547844 :   gcc_assert (!m->fs.fp_valid
    9862                 :             :               || m->fs.fp_offset == frame.hard_frame_pointer_offset);
    9863                 :             : 
    9864                 :             :   /* We must have *some* valid pointer to the stack frame.  */
    9865                 :     1547844 :   gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
    9866                 :             : 
    9867                 :             :   /* The DRAP is never valid at this point.  */
    9868                 :     1547844 :   gcc_assert (!m->fs.drap_valid);
    9869                 :             : 
    9870                 :             :   /* See the comment about red zone and frame
    9871                 :             :      pointer usage in ix86_expand_prologue.  */
    9872                 :     1547844 :   if (frame_pointer_needed && frame.red_zone_size)
    9873                 :      128113 :     emit_insn (gen_memory_blockage ());
    9874                 :             : 
    9875                 :     1547844 :   using_drap = crtl->drap_reg && crtl->stack_realign_needed;
    9876                 :        6986 :   gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
    9877                 :             : 
    9878                 :             :   /* Determine the CFA offset of the end of the red-zone.  */
    9879                 :     1547844 :   m->fs.red_zone_offset = 0;
    9880                 :     1547844 :   if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
    9881                 :             :     {
    9882                 :             :       /* The red-zone begins below return address and error code in
    9883                 :             :          exception handler.  */
    9884                 :     1376380 :       m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
    9885                 :             : 
    9886                 :             :       /* When the register save area is in the aligned portion of
    9887                 :             :          the stack, determine the maximum runtime displacement that
    9888                 :             :          matches up with the aligned frame.  */
    9889                 :     1376380 :       if (stack_realign_drap)
    9890                 :        8248 :         m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
    9891                 :        4124 :                                   + UNITS_PER_WORD);
    9892                 :             :     }
    9893                 :             : 
    9894                 :     1547844 :   HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
    9895                 :             : 
    9896                 :             :   /* Special care must be taken for the normal return case of a function
    9897                 :             :      using eh_return: the eax and edx registers are marked as saved, but
    9898                 :             :      not restored along this path.  Adjust the save location to match.  */
    9899                 :     1547844 :   if (crtl->calls_eh_return && style != 2)
    9900                 :          37 :     reg_save_offset -= 2 * UNITS_PER_WORD;
    9901                 :             : 
    9902                 :             :   /* EH_RETURN requires the use of moves to function properly.  */
    9903                 :     1547844 :   if (crtl->calls_eh_return)
    9904                 :             :     restore_regs_via_mov = true;
    9905                 :             :   /* SEH requires the use of pops to identify the epilogue.  */
    9906                 :     1547786 :   else if (TARGET_SEH)
    9907                 :             :     restore_regs_via_mov = false;
    9908                 :             :   /* If we already save reg with pushp, don't use move at epilogue.  */
    9909                 :     1547786 :   else if (m->fs.apx_ppx_used)
    9910                 :             :     restore_regs_via_mov = false;
    9911                 :             :   /* If we're only restoring one register and sp cannot be used then
    9912                 :             :      using a move instruction to restore the register since it's
    9913                 :             :      less work than reloading sp and popping the register.  */
    9914                 :     1547776 :   else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
    9915                 :             :     restore_regs_via_mov = true;
    9916                 :     1487186 :   else if (TARGET_EPILOGUE_USING_MOVE
    9917                 :       58491 :            && cfun->machine->use_fast_prologue_epilogue
    9918                 :       58313 :            && (frame.nregs > 1
    9919                 :       58306 :                || m->fs.sp_offset != reg_save_offset))
    9920                 :             :     restore_regs_via_mov = true;
    9921                 :     1486986 :   else if (frame_pointer_needed
    9922                 :      409900 :            && !frame.nregs
    9923                 :      317120 :            && m->fs.sp_offset != reg_save_offset)
    9924                 :             :     restore_regs_via_mov = true;
    9925                 :     1339223 :   else if (frame_pointer_needed
    9926                 :      262137 :            && TARGET_USE_LEAVE
    9927                 :      262108 :            && cfun->machine->use_fast_prologue_epilogue
    9928                 :      206316 :            && frame.nregs == 1)
    9929                 :             :     restore_regs_via_mov = true;
    9930                 :             :   else
    9931                 :             :     restore_regs_via_mov = false;
    9932                 :             : 
    9933                 :     1310842 :   if (restore_regs_via_mov || frame.nsseregs)
    9934                 :             :     {
    9935                 :             :       /* Ensure that the entire register save area is addressable via
    9936                 :             :          the stack pointer, if we will restore SSE regs via sp.  */
    9937                 :      270728 :       if (TARGET_64BIT
    9938                 :      263470 :           && m->fs.sp_offset > 0x7fffffff
    9939                 :          23 :           && sp_valid_at (frame.stack_realign_offset + 1)
    9940                 :      270750 :           && (frame.nsseregs + frame.nregs) != 0)
    9941                 :             :         {
    9942                 :           6 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9943                 :           6 :                                      GEN_INT (m->fs.sp_offset
    9944                 :             :                                               - frame.sse_reg_save_offset),
    9945                 :             :                                      style,
    9946                 :           6 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    9947                 :             :         }
    9948                 :             :     }
    9949                 :             : 
    9950                 :             :   /* If there are any SSE registers to restore, then we have to do it
    9951                 :             :      via moves, since there's obviously no pop for SSE regs.  */
    9952                 :     1547844 :   if (frame.nsseregs)
    9953                 :       33729 :     ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
    9954                 :             :                                           style == 2);
    9955                 :             : 
    9956                 :     1547844 :   if (m->call_ms2sysv)
    9957                 :             :     {
    9958                 :        7621 :       int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
    9959                 :             : 
    9960                 :             :       /* We cannot use a tail-call for the stub if:
    9961                 :             :          1. We have to pop incoming args,
    9962                 :             :          2. We have additional int regs to restore, or
    9963                 :             :          3. A sibling call will be the tail-call, or
    9964                 :             :          4. We are emitting an eh_return_internal epilogue.
    9965                 :             : 
    9966                 :             :          TODO: Item 4 has not yet tested!
    9967                 :             : 
    9968                 :             :          If any of the above are true, we will call the stub rather than
    9969                 :             :          jump to it.  */
    9970                 :        7621 :       restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
    9971                 :        7621 :       ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
    9972                 :             :     }
    9973                 :             : 
    9974                 :             :   /* If using out-of-line stub that is a tail-call, then...*/
    9975                 :     1547844 :   if (m->call_ms2sysv && restore_stub_is_tail)
    9976                 :             :     {
    9977                 :             :       /* TODO: parinoid tests. (remove eventually)  */
    9978                 :        1123 :       gcc_assert (m->fs.sp_valid);
    9979                 :        1123 :       gcc_assert (!m->fs.sp_realigned);
    9980                 :        1123 :       gcc_assert (!m->fs.fp_valid);
    9981                 :        1123 :       gcc_assert (!m->fs.realigned);
    9982                 :        1123 :       gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
    9983                 :        1123 :       gcc_assert (!crtl->drap_reg);
    9984                 :        1123 :       gcc_assert (!frame.nregs);
    9985                 :             :     }
    9986                 :     1546721 :   else if (restore_regs_via_mov)
    9987                 :             :     {
    9988                 :      236031 :       rtx t;
    9989                 :             : 
    9990                 :      236031 :       if (frame.nregs)
    9991                 :       41936 :         ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
    9992                 :             : 
    9993                 :             :       /* eh_return epilogues need %ecx added to the stack pointer.  */
    9994                 :      236031 :       if (style == 2)
    9995                 :             :         {
    9996                 :          29 :           rtx sa = EH_RETURN_STACKADJ_RTX;
    9997                 :          29 :           rtx_insn *insn;
    9998                 :             : 
    9999                 :             :           /* Stack realignment doesn't work with eh_return.  */
   10000                 :          29 :           if (crtl->stack_realign_needed)
   10001                 :           0 :             sorry ("Stack realignment not supported with "
   10002                 :             :                    "%<__builtin_eh_return%>");
   10003                 :             : 
   10004                 :             :           /* regparm nested functions don't work with eh_return.  */
   10005                 :          29 :           if (ix86_static_chain_on_stack)
   10006                 :           0 :             sorry ("regparm nested function not supported with "
   10007                 :             :                    "%<__builtin_eh_return%>");
   10008                 :             : 
   10009                 :          29 :           if (frame_pointer_needed)
   10010                 :             :             {
   10011                 :          27 :               t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
   10012                 :          35 :               t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
   10013                 :          27 :               emit_insn (gen_rtx_SET (sa, t));
   10014                 :             : 
   10015                 :             :               /* NB: eh_return epilogues must restore the frame pointer
   10016                 :             :                  in word_mode since the upper 32 bits of RBP register
   10017                 :             :                  can have any values.  */
   10018                 :          27 :               t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
   10019                 :          27 :               rtx frame_reg = gen_rtx_REG (word_mode,
   10020                 :             :                                            HARD_FRAME_POINTER_REGNUM);
   10021                 :          27 :               insn = emit_move_insn (frame_reg, t);
   10022                 :             : 
   10023                 :             :               /* Note that we use SA as a temporary CFA, as the return
   10024                 :             :                  address is at the proper place relative to it.  We
   10025                 :             :                  pretend this happens at the FP restore insn because
   10026                 :             :                  prior to this insn the FP would be stored at the wrong
   10027                 :             :                  offset relative to SA, and after this insn we have no
   10028                 :             :                  other reasonable register to use for the CFA.  We don't
   10029                 :             :                  bother resetting the CFA to the SP for the duration of
   10030                 :             :                  the return insn, unless the control flow instrumentation
   10031                 :             :                  is done.  In this case the SP is used later and we have
   10032                 :             :                  to reset CFA to SP.  */
   10033                 :          27 :               add_reg_note (insn, REG_CFA_DEF_CFA,
   10034                 :          35 :                             plus_constant (Pmode, sa, UNITS_PER_WORD));
   10035                 :          27 :               ix86_add_queued_cfa_restore_notes (insn);
   10036                 :          27 :               add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
   10037                 :          27 :               RTX_FRAME_RELATED_P (insn) = 1;
   10038                 :             : 
   10039                 :          27 :               m->fs.cfa_reg = sa;
   10040                 :          27 :               m->fs.cfa_offset = UNITS_PER_WORD;
   10041                 :          27 :               m->fs.fp_valid = false;
   10042                 :             : 
   10043                 :          27 :               pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
   10044                 :             :                                          const0_rtx, style,
   10045                 :          27 :                                          flag_cf_protection);
   10046                 :             :             }
   10047                 :             :           else
   10048                 :             :             {
   10049                 :           2 :               t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
   10050                 :           2 :               t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
   10051                 :           2 :               insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
   10052                 :           2 :               ix86_add_queued_cfa_restore_notes (insn);
   10053                 :             : 
   10054                 :           2 :               gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10055                 :           2 :               if (m->fs.cfa_offset != UNITS_PER_WORD)
   10056                 :             :                 {
   10057                 :           2 :                   m->fs.cfa_offset = UNITS_PER_WORD;
   10058                 :           2 :                   add_reg_note (insn, REG_CFA_DEF_CFA,
   10059                 :           2 :                                 plus_constant (Pmode, stack_pointer_rtx,
   10060                 :           2 :                                                UNITS_PER_WORD));
   10061                 :           2 :                   RTX_FRAME_RELATED_P (insn) = 1;
   10062                 :             :                 }
   10063                 :             :             }
   10064                 :          29 :           m->fs.sp_offset = UNITS_PER_WORD;
   10065                 :          29 :           m->fs.sp_valid = true;
   10066                 :          29 :           m->fs.sp_realigned = false;
   10067                 :             :         }
   10068                 :             :     }
   10069                 :             :   else
   10070                 :             :     {
   10071                 :             :       /* SEH requires that the function end with (1) a stack adjustment
   10072                 :             :          if necessary, (2) a sequence of pops, and (3) a return or
   10073                 :             :          jump instruction.  Prevent insns from the function body from
   10074                 :             :          being scheduled into this sequence.  */
   10075                 :     1310690 :       if (TARGET_SEH)
   10076                 :             :         {
   10077                 :             :           /* Prevent a catch region from being adjacent to the standard
   10078                 :             :              epilogue sequence.  Unfortunately neither crtl->uses_eh_lsda
   10079                 :             :              nor several other flags that would be interesting to test are
   10080                 :             :              set up yet.  */
   10081                 :             :           if (flag_non_call_exceptions)
   10082                 :             :             emit_insn (gen_nops (const1_rtx));
   10083                 :             :           else
   10084                 :             :             emit_insn (gen_blockage ());
   10085                 :             :         }
   10086                 :             : 
   10087                 :             :       /* First step is to deallocate the stack frame so that we can
   10088                 :             :          pop the registers.  If the stack pointer was realigned, it needs
   10089                 :             :          to be restored now.  Also do it on SEH target for very large
   10090                 :             :          frame as the emitted instructions aren't allowed by the ABI
   10091                 :             :          in epilogues.  */
   10092                 :     1310690 :       if (!m->fs.sp_valid || m->fs.sp_realigned
   10093                 :             :           || (TARGET_SEH
   10094                 :             :               && (m->fs.sp_offset - reg_save_offset
   10095                 :             :                   >= SEH_MAX_FRAME_SIZE)))
   10096                 :             :         {
   10097                 :       28782 :           pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
   10098                 :       28782 :                                      GEN_INT (m->fs.fp_offset
   10099                 :             :                                               - reg_save_offset),
   10100                 :             :                                      style, false);
   10101                 :             :         }
   10102                 :     1281908 :       else if (m->fs.sp_offset != reg_save_offset)
   10103                 :             :         {
   10104                 :      596618 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10105                 :             :                                      GEN_INT (m->fs.sp_offset
   10106                 :             :                                               - reg_save_offset),
   10107                 :             :                                      style,
   10108                 :      596618 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10109                 :             :         }
   10110                 :             : 
   10111                 :     1310690 :       if (TARGET_APX_PUSH2POP2
   10112                 :         445 :           && ix86_can_use_push2pop2 ()
   10113                 :     1311133 :           && m->func_type == TYPE_NORMAL)
   10114                 :         442 :         ix86_emit_restore_regs_using_pop2 ();
   10115                 :             :       else
   10116                 :     1310248 :         ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
   10117                 :             :     }
   10118                 :             : 
   10119                 :             :   /* If we used a stack pointer and haven't already got rid of it,
   10120                 :             :      then do so now.  */
   10121                 :     1547844 :   if (m->fs.fp_valid)
   10122                 :             :     {
   10123                 :             :       /* If the stack pointer is valid and pointing at the frame
   10124                 :             :          pointer store address, then we only need a pop.  */
   10125                 :      469719 :       if (sp_valid_at (frame.hfp_save_offset)
   10126                 :      469719 :           && m->fs.sp_offset == frame.hfp_save_offset)
   10127                 :      233829 :         ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10128                 :             :       /* Leave results in shorter dependency chains on CPUs that are
   10129                 :             :          able to grok it fast.  */
   10130                 :      235890 :       else if (TARGET_USE_LEAVE
   10131                 :          12 :                || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
   10132                 :      235902 :                || !cfun->machine->use_fast_prologue_epilogue)
   10133                 :      235878 :         ix86_emit_leave (NULL);
   10134                 :             :       else
   10135                 :             :         {
   10136                 :          12 :           pro_epilogue_adjust_stack (stack_pointer_rtx,
   10137                 :             :                                      hard_frame_pointer_rtx,
   10138                 :          12 :                                      const0_rtx, style, !using_drap);
   10139                 :          12 :           ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10140                 :             :         }
   10141                 :             :     }
   10142                 :             : 
   10143                 :     1547844 :   if (using_drap)
   10144                 :             :     {
   10145                 :        6986 :       int param_ptr_offset = UNITS_PER_WORD;
   10146                 :        6986 :       rtx_insn *insn;
   10147                 :             : 
   10148                 :        6986 :       gcc_assert (stack_realign_drap);
   10149                 :             : 
   10150                 :        6986 :       if (ix86_static_chain_on_stack)
   10151                 :           0 :         param_ptr_offset += UNITS_PER_WORD;
   10152                 :        6986 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10153                 :         216 :         param_ptr_offset += UNITS_PER_WORD;
   10154                 :             : 
   10155                 :        6986 :       insn = emit_insn (gen_rtx_SET
   10156                 :             :                         (stack_pointer_rtx,
   10157                 :             :                          plus_constant (Pmode, crtl->drap_reg,
   10158                 :             :                                         -param_ptr_offset)));
   10159                 :        6986 :       m->fs.cfa_reg = stack_pointer_rtx;
   10160                 :        6986 :       m->fs.cfa_offset = param_ptr_offset;
   10161                 :        6986 :       m->fs.sp_offset = param_ptr_offset;
   10162                 :        6986 :       m->fs.realigned = false;
   10163                 :             : 
   10164                 :        7288 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10165                 :        6986 :                     plus_constant (Pmode, stack_pointer_rtx,
   10166                 :             :                                    param_ptr_offset));
   10167                 :        6986 :       RTX_FRAME_RELATED_P (insn) = 1;
   10168                 :             : 
   10169                 :        6986 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10170                 :         216 :         ix86_emit_restore_reg_using_pop (crtl->drap_reg);
   10171                 :             :     }
   10172                 :             : 
   10173                 :             :   /* At this point the stack pointer must be valid, and we must have
   10174                 :             :      restored all of the registers.  We may not have deallocated the
   10175                 :             :      entire stack frame.  We've delayed this until now because it may
   10176                 :             :      be possible to merge the local stack deallocation with the
   10177                 :             :      deallocation forced by ix86_static_chain_on_stack.   */
   10178                 :     1547844 :   gcc_assert (m->fs.sp_valid);
   10179                 :     1547844 :   gcc_assert (!m->fs.sp_realigned);
   10180                 :     1547844 :   gcc_assert (!m->fs.fp_valid);
   10181                 :     1547844 :   gcc_assert (!m->fs.realigned);
   10182                 :     1677800 :   if (m->fs.sp_offset != UNITS_PER_WORD)
   10183                 :             :     {
   10184                 :          97 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10185                 :             :                                  GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
   10186                 :             :                                  style, true);
   10187                 :             :     }
   10188                 :             :   else
   10189                 :     1547747 :     ix86_add_queued_cfa_restore_notes (get_last_insn ());
   10190                 :             : 
   10191                 :             :   /* Sibcall epilogues don't want a return instruction.  */
   10192                 :     1547844 :   if (style == 0)
   10193                 :             :     {
   10194                 :      114787 :       m->fs = frame_state_save;
   10195                 :      114787 :       return;
   10196                 :             :     }
   10197                 :             : 
   10198                 :     1433057 :   if (cfun->machine->func_type != TYPE_NORMAL)
   10199                 :         118 :     emit_jump_insn (gen_interrupt_return ());
   10200                 :     1432939 :   else if (crtl->args.pops_args && crtl->args.size)
   10201                 :             :     {
   10202                 :       25611 :       rtx popc = GEN_INT (crtl->args.pops_args);
   10203                 :             : 
   10204                 :             :       /* i386 can only pop 64K bytes.  If asked to pop more, pop return
   10205                 :             :          address, do explicit add, and jump indirectly to the caller.  */
   10206                 :             : 
   10207                 :       25611 :       if (crtl->args.pops_args >= 65536)
   10208                 :             :         {
   10209                 :           0 :           rtx ecx = gen_rtx_REG (SImode, CX_REG);
   10210                 :           0 :           rtx_insn *insn;
   10211                 :             : 
   10212                 :             :           /* There is no "pascal" calling convention in any 64bit ABI.  */
   10213                 :           0 :           gcc_assert (!TARGET_64BIT);
   10214                 :             : 
   10215                 :           0 :           insn = emit_insn (gen_pop (ecx));
   10216                 :           0 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10217                 :           0 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10218                 :             : 
   10219                 :           0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10220                 :           0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10221                 :           0 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10222                 :           0 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10223                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
   10224                 :             : 
   10225                 :           0 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10226                 :             :                                      popc, -1, true);
   10227                 :           0 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10228                 :             :         }
   10229                 :             :       else
   10230                 :       25611 :         emit_jump_insn (gen_simple_return_pop_internal (popc));
   10231                 :             :     }
   10232                 :     1407328 :   else if (!m->call_ms2sysv || !restore_stub_is_tail)
   10233                 :             :     {
   10234                 :             :       /* In case of return from EH a simple return cannot be used
   10235                 :             :          as a return address will be compared with a shadow stack
   10236                 :             :          return address.  Use indirect jump instead.  */
   10237                 :     1406205 :       if (style == 2 && flag_cf_protection)
   10238                 :             :         {
   10239                 :             :           /* Register used in indirect jump must be in word_mode.  But
   10240                 :             :              Pmode may not be the same as word_mode for x32.  */
   10241                 :          17 :           rtx ecx = gen_rtx_REG (word_mode, CX_REG);
   10242                 :          17 :           rtx_insn *insn;
   10243                 :             : 
   10244                 :          17 :           insn = emit_insn (gen_pop (ecx));
   10245                 :          17 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10246                 :          17 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10247                 :             : 
   10248                 :          25 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10249                 :          17 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10250                 :          17 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10251                 :          17 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10252                 :          17 :           RTX_FRAME_RELATED_P (insn) = 1;
   10253                 :             : 
   10254                 :          17 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10255                 :          17 :         }
   10256                 :             :       else
   10257                 :     1406188 :         emit_jump_insn (gen_simple_return_internal ());
   10258                 :             :     }
   10259                 :             : 
   10260                 :             :   /* Restore the state back to the state from the prologue,
   10261                 :             :      so that it's correct for the next epilogue.  */
   10262                 :     1433057 :   m->fs = frame_state_save;
   10263                 :             : }
   10264                 :             : 
   10265                 :             : /* Reset from the function's potential modifications.  */
   10266                 :             : 
   10267                 :             : static void
   10268                 :     1438408 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
   10269                 :             : {
   10270                 :     1438408 :   if (pic_offset_table_rtx
   10271                 :     1438408 :       && !ix86_use_pseudo_pic_reg ())
   10272                 :           0 :     SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
   10273                 :             : 
   10274                 :     1438408 :   if (TARGET_MACHO)
   10275                 :             :     {
   10276                 :             :       rtx_insn *insn = get_last_insn ();
   10277                 :             :       rtx_insn *deleted_debug_label = NULL;
   10278                 :             : 
   10279                 :             :       /* Mach-O doesn't support labels at the end of objects, so if
   10280                 :             :          it looks like we might want one, take special action.
   10281                 :             :         First, collect any sequence of deleted debug labels.  */
   10282                 :             :       while (insn
   10283                 :             :              && NOTE_P (insn)
   10284                 :             :              && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
   10285                 :             :         {
   10286                 :             :           /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
   10287                 :             :              notes only, instead set their CODE_LABEL_NUMBER to -1,
   10288                 :             :              otherwise there would be code generation differences
   10289                 :             :              in between -g and -g0.  */
   10290                 :             :           if (NOTE_P (insn) && NOTE_KIND (insn)
   10291                 :             :               == NOTE_INSN_DELETED_DEBUG_LABEL)
   10292                 :             :             deleted_debug_label = insn;
   10293                 :             :           insn = PREV_INSN (insn);
   10294                 :             :         }
   10295                 :             : 
   10296                 :             :       /* If we have:
   10297                 :             :          label:
   10298                 :             :             barrier
   10299                 :             :           then this needs to be detected, so skip past the barrier.  */
   10300                 :             : 
   10301                 :             :       if (insn && BARRIER_P (insn))
   10302                 :             :         insn = PREV_INSN (insn);
   10303                 :             : 
   10304                 :             :       /* Up to now we've only seen notes or barriers.  */
   10305                 :             :       if (insn)
   10306                 :             :         {
   10307                 :             :           if (LABEL_P (insn)
   10308                 :             :               || (NOTE_P (insn)
   10309                 :             :                   && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
   10310                 :             :             /* Trailing label.  */
   10311                 :             :             fputs ("\tnop\n", file);
   10312                 :             :           else if (cfun && ! cfun->is_thunk)
   10313                 :             :             {
   10314                 :             :               /* See if we have a completely empty function body, skipping
   10315                 :             :                  the special case of the picbase thunk emitted as asm.  */
   10316                 :             :               while (insn && ! INSN_P (insn))
   10317                 :             :                 insn = PREV_INSN (insn);
   10318                 :             :               /* If we don't find any insns, we've got an empty function body;
   10319                 :             :                  I.e. completely empty - without a return or branch.  This is
   10320                 :             :                  taken as the case where a function body has been removed
   10321                 :             :                  because it contains an inline __builtin_unreachable().  GCC
   10322                 :             :                  declares that reaching __builtin_unreachable() means UB so
   10323                 :             :                  we're not obliged to do anything special; however, we want
   10324                 :             :                  non-zero-sized function bodies.  To meet this, and help the
   10325                 :             :                  user out, let's trap the case.  */
   10326                 :             :               if (insn == NULL)
   10327                 :             :                 fputs ("\tud2\n", file);
   10328                 :             :             }
   10329                 :             :         }
   10330                 :             :       else if (deleted_debug_label)
   10331                 :             :         for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
   10332                 :             :           if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
   10333                 :             :             CODE_LABEL_NUMBER (insn) = -1;
   10334                 :             :     }
   10335                 :     1438408 : }
   10336                 :             : 
   10337                 :             : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY.  */
   10338                 :             : 
   10339                 :             : void
   10340                 :          59 : ix86_print_patchable_function_entry (FILE *file,
   10341                 :             :                                      unsigned HOST_WIDE_INT patch_area_size,
   10342                 :             :                                      bool record_p)
   10343                 :             : {
   10344                 :          59 :   if (cfun->machine->function_label_emitted)
   10345                 :             :     {
   10346                 :             :       /* NB: When ix86_print_patchable_function_entry is called after
   10347                 :             :          function table has been emitted, we have inserted or queued
   10348                 :             :          a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
   10349                 :             :          place.  There is nothing to do here.  */
   10350                 :             :       return;
   10351                 :             :     }
   10352                 :             : 
   10353                 :           8 :   default_print_patchable_function_entry (file, patch_area_size,
   10354                 :             :                                           record_p);
   10355                 :             : }
   10356                 :             : 
   10357                 :             : /* Output patchable area.  NB: default_print_patchable_function_entry
   10358                 :             :    isn't available in i386.md.  */
   10359                 :             : 
   10360                 :             : void
   10361                 :          51 : ix86_output_patchable_area (unsigned int patch_area_size,
   10362                 :             :                             bool record_p)
   10363                 :             : {
   10364                 :          51 :   default_print_patchable_function_entry (asm_out_file,
   10365                 :             :                                           patch_area_size,
   10366                 :             :                                           record_p);
   10367                 :          51 : }
   10368                 :             : 
   10369                 :             : /* Return a scratch register to use in the split stack prologue.  The
   10370                 :             :    split stack prologue is used for -fsplit-stack.  It is the first
   10371                 :             :    instructions in the function, even before the regular prologue.
   10372                 :             :    The scratch register can be any caller-saved register which is not
   10373                 :             :    used for parameters or for the static chain.  */
   10374                 :             : 
   10375                 :             : static unsigned int
   10376                 :       24634 : split_stack_prologue_scratch_regno (void)
   10377                 :             : {
   10378                 :       24634 :   if (TARGET_64BIT)
   10379                 :             :     return R11_REG;
   10380                 :             :   else
   10381                 :             :     {
   10382                 :        6966 :       bool is_fastcall, is_thiscall;
   10383                 :        6966 :       int regparm;
   10384                 :             : 
   10385                 :        6966 :       is_fastcall = (lookup_attribute ("fastcall",
   10386                 :        6966 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10387                 :             :                      != NULL);
   10388                 :        6966 :       is_thiscall = (lookup_attribute ("thiscall",
   10389                 :        6966 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10390                 :             :                      != NULL);
   10391                 :        6966 :       regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
   10392                 :             : 
   10393                 :        6966 :       if (is_fastcall)
   10394                 :             :         {
   10395                 :           0 :           if (DECL_STATIC_CHAIN (cfun->decl))
   10396                 :             :             {
   10397                 :           0 :               sorry ("%<-fsplit-stack%> does not support fastcall with "
   10398                 :             :                      "nested function");
   10399                 :           0 :               return INVALID_REGNUM;
   10400                 :             :             }
   10401                 :             :           return AX_REG;
   10402                 :             :         }
   10403                 :        6966 :       else if (is_thiscall)
   10404                 :             :         {
   10405                 :           0 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10406                 :             :             return DX_REG;
   10407                 :           0 :           return AX_REG;
   10408                 :             :         }
   10409                 :        6966 :       else if (regparm < 3)
   10410                 :             :         {
   10411                 :        6966 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10412                 :             :             return CX_REG;
   10413                 :             :           else
   10414                 :             :             {
   10415                 :         448 :               if (regparm >= 2)
   10416                 :             :                 {
   10417                 :           0 :                   sorry ("%<-fsplit-stack%> does not support 2 register "
   10418                 :             :                          "parameters for a nested function");
   10419                 :           0 :                   return INVALID_REGNUM;
   10420                 :             :                 }
   10421                 :             :               return DX_REG;
   10422                 :             :             }
   10423                 :             :         }
   10424                 :             :       else
   10425                 :             :         {
   10426                 :             :           /* FIXME: We could make this work by pushing a register
   10427                 :             :              around the addition and comparison.  */
   10428                 :           0 :           sorry ("%<-fsplit-stack%> does not support 3 register parameters");
   10429                 :           0 :           return INVALID_REGNUM;
   10430                 :             :         }
   10431                 :             :     }
   10432                 :             : }
   10433                 :             : 
   10434                 :             : /* A SYMBOL_REF for the function which allocates new stackspace for
   10435                 :             :    -fsplit-stack.  */
   10436                 :             : 
   10437                 :             : static GTY(()) rtx split_stack_fn;
   10438                 :             : 
   10439                 :             : /* A SYMBOL_REF for the more stack function when using the large
   10440                 :             :    model.  */
   10441                 :             : 
   10442                 :             : static GTY(()) rtx split_stack_fn_large;
   10443                 :             : 
   10444                 :             : /* Return location of the stack guard value in the TLS block.  */
   10445                 :             : 
   10446                 :             : rtx
   10447                 :      259805 : ix86_split_stack_guard (void)
   10448                 :             : {
   10449                 :      259805 :   int offset;
   10450                 :      259805 :   addr_space_t as = DEFAULT_TLS_SEG_REG;
   10451                 :      259805 :   rtx r;
   10452                 :             : 
   10453                 :      259805 :   gcc_assert (flag_split_stack);
   10454                 :             : 
   10455                 :             : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
   10456                 :      259805 :   offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
   10457                 :             : #else
   10458                 :             :   gcc_unreachable ();
   10459                 :             : #endif
   10460                 :             : 
   10461                 :      259805 :   r = GEN_INT (offset);
   10462                 :      259805 :   r = gen_const_mem (Pmode, r);
   10463                 :      259805 :   set_mem_addr_space (r, as);
   10464                 :             : 
   10465                 :      259805 :   return r;
   10466                 :             : }
   10467                 :             : 
   10468                 :             : /* Handle -fsplit-stack.  These are the first instructions in the
   10469                 :             :    function, even before the regular prologue.  */
   10470                 :             : 
   10471                 :             : void
   10472                 :      259796 : ix86_expand_split_stack_prologue (void)
   10473                 :             : {
   10474                 :      259796 :   HOST_WIDE_INT allocate;
   10475                 :      259796 :   unsigned HOST_WIDE_INT args_size;
   10476                 :      259796 :   rtx_code_label *label;
   10477                 :      259796 :   rtx limit, current, allocate_rtx, call_fusage;
   10478                 :      259796 :   rtx_insn *call_insn;
   10479                 :      259796 :   unsigned int scratch_regno = INVALID_REGNUM;
   10480                 :      259796 :   rtx scratch_reg = NULL_RTX;
   10481                 :      259796 :   rtx_code_label *varargs_label = NULL;
   10482                 :      259796 :   rtx fn;
   10483                 :             : 
   10484                 :      259796 :   gcc_assert (flag_split_stack && reload_completed);
   10485                 :             : 
   10486                 :      259796 :   ix86_finalize_stack_frame_flags ();
   10487                 :      259796 :   struct ix86_frame &frame = cfun->machine->frame;
   10488                 :      259796 :   allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
   10489                 :             : 
   10490                 :             :   /* This is the label we will branch to if we have enough stack
   10491                 :             :      space.  We expect the basic block reordering pass to reverse this
   10492                 :             :      branch if optimizing, so that we branch in the unlikely case.  */
   10493                 :      259796 :   label = gen_label_rtx ();
   10494                 :             : 
   10495                 :             :   /* We need to compare the stack pointer minus the frame size with
   10496                 :             :      the stack boundary in the TCB.  The stack boundary always gives
   10497                 :             :      us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
   10498                 :             :      can compare directly.  Otherwise we need to do an addition.  */
   10499                 :             : 
   10500                 :      259796 :   limit = ix86_split_stack_guard ();
   10501                 :             : 
   10502                 :      259796 :   if (allocate >= SPLIT_STACK_AVAILABLE
   10503                 :      235325 :       || flag_force_indirect_call)
   10504                 :             :     {
   10505                 :       24486 :       scratch_regno = split_stack_prologue_scratch_regno ();
   10506                 :       24486 :       if (scratch_regno == INVALID_REGNUM)
   10507                 :           0 :         return;
   10508                 :             :     }
   10509                 :             : 
   10510                 :      259796 :   if (allocate >= SPLIT_STACK_AVAILABLE)
   10511                 :             :     {
   10512                 :       24471 :       rtx offset;
   10513                 :             : 
   10514                 :             :       /* We need a scratch register to hold the stack pointer minus
   10515                 :             :          the required frame size.  Since this is the very start of the
   10516                 :             :          function, the scratch register can be any caller-saved
   10517                 :             :          register which is not used for parameters.  */
   10518                 :       24471 :       offset = GEN_INT (- allocate);
   10519                 :             : 
   10520                 :       24471 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10521                 :       24471 :       if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
   10522                 :             :         {
   10523                 :             :           /* We don't use gen_add in this case because it will
   10524                 :             :              want to split to lea, but when not optimizing the insn
   10525                 :             :              will not be split after this point.  */
   10526                 :       24471 :           emit_insn (gen_rtx_SET (scratch_reg,
   10527                 :             :                                   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   10528                 :             :                                                 offset)));
   10529                 :             :         }
   10530                 :             :       else
   10531                 :             :         {
   10532                 :           0 :           emit_move_insn (scratch_reg, offset);
   10533                 :           0 :           emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
   10534                 :             :         }
   10535                 :             :       current = scratch_reg;
   10536                 :             :     }
   10537                 :             :   else
   10538                 :      235325 :     current = stack_pointer_rtx;
   10539                 :             : 
   10540                 :      259796 :   ix86_expand_branch (GEU, current, limit, label);
   10541                 :      259796 :   rtx_insn *jump_insn = get_last_insn ();
   10542                 :      259796 :   JUMP_LABEL (jump_insn) = label;
   10543                 :             : 
   10544                 :             :   /* Mark the jump as very likely to be taken.  */
   10545                 :      259796 :   add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
   10546                 :             : 
   10547                 :      259796 :   if (split_stack_fn == NULL_RTX)
   10548                 :             :     {
   10549                 :        4349 :       split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
   10550                 :        4349 :       SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
   10551                 :             :     }
   10552                 :      259796 :   fn = split_stack_fn;
   10553                 :             : 
   10554                 :             :   /* Get more stack space.  We pass in the desired stack space and the
   10555                 :             :      size of the arguments to copy to the new stack.  In 32-bit mode
   10556                 :             :      we push the parameters; __morestack will return on a new stack
   10557                 :             :      anyhow.  In 64-bit mode we pass the parameters in r10 and
   10558                 :             :      r11.  */
   10559                 :      259796 :   allocate_rtx = GEN_INT (allocate);
   10560                 :      259796 :   args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
   10561                 :      259796 :   call_fusage = NULL_RTX;
   10562                 :      259796 :   rtx pop = NULL_RTX;
   10563                 :      259796 :   if (TARGET_64BIT)
   10564                 :             :     {
   10565                 :      161889 :       rtx reg10, reg11;
   10566                 :             : 
   10567                 :      161889 :       reg10 = gen_rtx_REG (DImode, R10_REG);
   10568                 :      161889 :       reg11 = gen_rtx_REG (DImode, R11_REG);
   10569                 :             : 
   10570                 :             :       /* If this function uses a static chain, it will be in %r10.
   10571                 :             :          Preserve it across the call to __morestack.  */
   10572                 :      161889 :       if (DECL_STATIC_CHAIN (cfun->decl))
   10573                 :             :         {
   10574                 :        7505 :           rtx rax;
   10575                 :             : 
   10576                 :        7505 :           rax = gen_rtx_REG (word_mode, AX_REG);
   10577                 :        7505 :           emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
   10578                 :        7505 :           use_reg (&call_fusage, rax);
   10579                 :             :         }
   10580                 :             : 
   10581                 :      161889 :       if (flag_force_indirect_call
   10582                 :      161874 :           || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
   10583                 :             :         {
   10584                 :          16 :           HOST_WIDE_INT argval;
   10585                 :             : 
   10586                 :          16 :           if (split_stack_fn_large == NULL_RTX)
   10587                 :             :             {
   10588                 :           7 :               split_stack_fn_large
   10589                 :           7 :                 = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
   10590                 :           7 :               SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
   10591                 :             :             }
   10592                 :             : 
   10593                 :          16 :           fn = split_stack_fn_large;
   10594                 :             : 
   10595                 :          16 :           if (ix86_cmodel == CM_LARGE_PIC)
   10596                 :             :             {
   10597                 :           3 :               rtx_code_label *label;
   10598                 :           3 :               rtx x;
   10599                 :             : 
   10600                 :           3 :               gcc_assert (Pmode == DImode);
   10601                 :             : 
   10602                 :           3 :               label = gen_label_rtx ();
   10603                 :           3 :               emit_label (label);
   10604                 :           3 :               LABEL_PRESERVE_P (label) = 1;
   10605                 :           3 :               emit_insn (gen_set_rip_rex64 (reg10, label));
   10606                 :           3 :               emit_insn (gen_set_got_offset_rex64 (reg11, label));
   10607                 :           3 :               emit_insn (gen_add2_insn (reg10, reg11));
   10608                 :           3 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
   10609                 :           3 :               x = gen_rtx_CONST (Pmode, x);
   10610                 :           3 :               emit_move_insn (reg11, x);
   10611                 :           3 :               x = gen_rtx_PLUS (Pmode, reg10, reg11);
   10612                 :           3 :               x = gen_const_mem (Pmode, x);
   10613                 :           3 :               fn = copy_to_suggested_reg (x, reg11, Pmode);
   10614                 :             :             }
   10615                 :          13 :           else if (ix86_cmodel == CM_LARGE)
   10616                 :           1 :             fn = copy_to_suggested_reg (fn, reg11, Pmode);
   10617                 :             : 
   10618                 :             :           /* When using the large model we need to load the address
   10619                 :             :              into a register, and we've run out of registers.  So we
   10620                 :             :              switch to a different calling convention, and we call a
   10621                 :             :              different function: __morestack_large.  We pass the
   10622                 :             :              argument size in the upper 32 bits of r10 and pass the
   10623                 :             :              frame size in the lower 32 bits.  */
   10624                 :          16 :           gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
   10625                 :          16 :           gcc_assert ((args_size & 0xffffffff) == args_size);
   10626                 :             : 
   10627                 :          16 :           argval = ((args_size << 16) << 16) + allocate;
   10628                 :          16 :           emit_move_insn (reg10, GEN_INT (argval));
   10629                 :          16 :         }
   10630                 :             :       else
   10631                 :             :         {
   10632                 :      161873 :           emit_move_insn (reg10, allocate_rtx);
   10633                 :      161873 :           emit_move_insn (reg11, GEN_INT (args_size));
   10634                 :      161873 :           use_reg (&call_fusage, reg11);
   10635                 :             :         }
   10636                 :             : 
   10637                 :      161889 :       use_reg (&call_fusage, reg10);
   10638                 :             :     }
   10639                 :             :   else
   10640                 :             :     {
   10641                 :       97907 :       if (flag_force_indirect_call && flag_pic)
   10642                 :             :         {
   10643                 :           0 :           rtx x;
   10644                 :             : 
   10645                 :           0 :           gcc_assert (Pmode == SImode);
   10646                 :             : 
   10647                 :           0 :           scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10648                 :             : 
   10649                 :           0 :           emit_insn (gen_set_got (scratch_reg));
   10650                 :           0 :           x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
   10651                 :             :                               UNSPEC_GOT);
   10652                 :           0 :           x = gen_rtx_CONST (Pmode, x);
   10653                 :           0 :           x = gen_rtx_PLUS (Pmode, scratch_reg, x);
   10654                 :           0 :           x = gen_const_mem (Pmode, x);
   10655                 :           0 :           fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
   10656                 :             :         }
   10657                 :             : 
   10658                 :       97907 :       rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
   10659                 :      195814 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
   10660                 :       97907 :       insn = emit_insn (gen_push (allocate_rtx));
   10661                 :      195814 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
   10662                 :      195814 :       pop = GEN_INT (2 * UNITS_PER_WORD);
   10663                 :             :     }
   10664                 :             : 
   10665                 :      259796 :   if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
   10666                 :             :     {
   10667                 :          12 :       scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
   10668                 :             : 
   10669                 :          12 :       if (GET_MODE (fn) != word_mode)
   10670                 :           0 :         fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
   10671                 :             : 
   10672                 :          12 :       fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
   10673                 :             :     }
   10674                 :             : 
   10675                 :      259796 :   call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
   10676                 :      259796 :                                 GEN_INT (UNITS_PER_WORD), constm1_rtx,
   10677                 :             :                                 pop, false);
   10678                 :      259796 :   add_function_usage_to (call_insn, call_fusage);
   10679                 :      259796 :   if (!TARGET_64BIT)
   10680                 :       97907 :     add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
   10681                 :             :   /* Indicate that this function can't jump to non-local gotos.  */
   10682                 :      259796 :   make_reg_eh_region_note_nothrow_nononlocal (call_insn);
   10683                 :             : 
   10684                 :             :   /* In order to make call/return prediction work right, we now need
   10685                 :             :      to execute a return instruction.  See
   10686                 :             :      libgcc/config/i386/morestack.S for the details on how this works.
   10687                 :             : 
   10688                 :             :      For flow purposes gcc must not see this as a return
   10689                 :             :      instruction--we need control flow to continue at the subsequent
   10690                 :             :      label.  Therefore, we use an unspec.  */
   10691                 :      259796 :   gcc_assert (crtl->args.pops_args < 65536);
   10692                 :      259796 :   rtx_insn *ret_insn
   10693                 :      259796 :     = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
   10694                 :             : 
   10695                 :      259796 :   if ((flag_cf_protection & CF_BRANCH))
   10696                 :             :     {
   10697                 :             :       /* Insert ENDBR since __morestack will jump back here via indirect
   10698                 :             :          call.  */
   10699                 :          21 :       rtx cet_eb = gen_nop_endbr ();
   10700                 :          21 :       emit_insn_after (cet_eb, ret_insn);
   10701                 :             :     }
   10702                 :             : 
   10703                 :             :   /* If we are in 64-bit mode and this function uses a static chain,
   10704                 :             :      we saved %r10 in %rax before calling _morestack.  */
   10705                 :      259796 :   if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
   10706                 :        7505 :     emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
   10707                 :             :                     gen_rtx_REG (word_mode, AX_REG));
   10708                 :             : 
   10709                 :             :   /* If this function calls va_start, we need to store a pointer to
   10710                 :             :      the arguments on the old stack, because they may not have been
   10711                 :             :      all copied to the new stack.  At this point the old stack can be
   10712                 :             :      found at the frame pointer value used by __morestack, because
   10713                 :             :      __morestack has set that up before calling back to us.  Here we
   10714                 :             :      store that pointer in a scratch register, and in
   10715                 :             :      ix86_expand_prologue we store the scratch register in a stack
   10716                 :             :      slot.  */
   10717                 :      259796 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10718                 :             :     {
   10719                 :          12 :       rtx frame_reg;
   10720                 :          12 :       int words;
   10721                 :             : 
   10722                 :          12 :       scratch_regno = split_stack_prologue_scratch_regno ();
   10723                 :          12 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10724                 :          12 :       frame_reg = gen_rtx_REG (Pmode, BP_REG);
   10725                 :             : 
   10726                 :             :       /* 64-bit:
   10727                 :             :          fp -> old fp value
   10728                 :             :                return address within this function
   10729                 :             :                return address of caller of this function
   10730                 :             :                stack arguments
   10731                 :             :          So we add three words to get to the stack arguments.
   10732                 :             : 
   10733                 :             :          32-bit:
   10734                 :             :          fp -> old fp value
   10735                 :             :                return address within this function
   10736                 :             :                first argument to __morestack
   10737                 :             :                second argument to __morestack
   10738                 :             :                return address of caller of this function
   10739                 :             :                stack arguments
   10740                 :             :          So we add five words to get to the stack arguments.
   10741                 :             :       */
   10742                 :          12 :       words = TARGET_64BIT ? 3 : 5;
   10743                 :          16 :       emit_insn (gen_rtx_SET (scratch_reg,
   10744                 :             :                               plus_constant (Pmode, frame_reg,
   10745                 :             :                                              words * UNITS_PER_WORD)));
   10746                 :             : 
   10747                 :          12 :       varargs_label = gen_label_rtx ();
   10748                 :          12 :       emit_jump_insn (gen_jump (varargs_label));
   10749                 :          12 :       JUMP_LABEL (get_last_insn ()) = varargs_label;
   10750                 :             : 
   10751                 :          12 :       emit_barrier ();
   10752                 :             :     }
   10753                 :             : 
   10754                 :      259796 :   emit_label (label);
   10755                 :      259796 :   LABEL_NUSES (label) = 1;
   10756                 :             : 
   10757                 :             :   /* If this function calls va_start, we now have to set the scratch
   10758                 :             :      register for the case where we do not call __morestack.  In this
   10759                 :             :      case we need to set it based on the stack pointer.  */
   10760                 :      259796 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10761                 :             :     {
   10762                 :          16 :       emit_insn (gen_rtx_SET (scratch_reg,
   10763                 :             :                               plus_constant (Pmode, stack_pointer_rtx,
   10764                 :             :                                              UNITS_PER_WORD)));
   10765                 :             : 
   10766                 :          12 :       emit_label (varargs_label);
   10767                 :          12 :       LABEL_NUSES (varargs_label) = 1;
   10768                 :             :     }
   10769                 :             : }
   10770                 :             : 
   10771                 :             : /* We may have to tell the dataflow pass that the split stack prologue
   10772                 :             :    is initializing a scratch register.  */
   10773                 :             : 
   10774                 :             : static void
   10775                 :    14623315 : ix86_live_on_entry (bitmap regs)
   10776                 :             : {
   10777                 :    14623315 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10778                 :             :     {
   10779                 :         124 :       gcc_assert (flag_split_stack);
   10780                 :         124 :       bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
   10781                 :             :     }
   10782                 :    14623315 : }
   10783                 :             : 
   10784                 :             : /* Extract the parts of an RTL expression that is a valid memory address
   10785                 :             :    for an instruction.  Return false if the structure of the address is
   10786                 :             :    grossly off.  */
   10787                 :             : 
   10788                 :             : bool
   10789                 :  4089075096 : ix86_decompose_address (rtx addr, struct ix86_address *out)
   10790                 :             : {
   10791                 :  4089075096 :   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
   10792                 :  4089075096 :   rtx base_reg, index_reg;
   10793                 :  4089075096 :   HOST_WIDE_INT scale = 1;
   10794                 :  4089075096 :   rtx scale_rtx = NULL_RTX;
   10795                 :  4089075096 :   rtx tmp;
   10796                 :  4089075096 :   addr_space_t seg = ADDR_SPACE_GENERIC;
   10797                 :             : 
   10798                 :             :   /* Allow zero-extended SImode addresses,
   10799                 :             :      they will be emitted with addr32 prefix.  */
   10800                 :  4089075096 :   if (TARGET_64BIT && GET_MODE (addr) == DImode)
   10801                 :             :     {
   10802                 :  2074681072 :       if (GET_CODE (addr) == ZERO_EXTEND
   10803                 :     1736759 :           && GET_MODE (XEXP (addr, 0)) == SImode)
   10804                 :             :         {
   10805                 :     1634573 :           addr = XEXP (addr, 0);
   10806                 :     1634573 :           if (CONST_INT_P (addr))
   10807                 :             :             return false;
   10808                 :             :         }
   10809                 :  2073046499 :       else if (GET_CODE (addr) == AND)
   10810                 :             :         {
   10811                 :     2670680 :           rtx mask = XEXP (addr, 1);
   10812                 :     2670680 :           rtx shift_val;
   10813                 :             : 
   10814                 :     2670680 :           if (const_32bit_mask (mask, DImode)
   10815                 :             :               /* For ASHIFT inside AND, combine will not generate
   10816                 :             :                  canonical zero-extend. Merge mask for AND and shift_count
   10817                 :             :                  to check if it is canonical zero-extend.  */
   10818                 :     2670680 :               || (CONST_INT_P (mask)
   10819                 :     1806550 :                   && GET_CODE (XEXP (addr, 0)) == ASHIFT
   10820                 :      136609 :                   && CONST_INT_P (shift_val = XEXP (XEXP (addr, 0), 1))
   10821                 :      130644 :                   && ((UINTVAL (mask)
   10822                 :      130644 :                        | ((HOST_WIDE_INT_1U << INTVAL (shift_val)) - 1))
   10823                 :             :                       == HOST_WIDE_INT_UC (0xffffffff))))
   10824                 :             :             {
   10825                 :       60615 :               addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
   10826                 :       60615 :               if (addr == NULL_RTX)
   10827                 :             :                 return false;
   10828                 :             : 
   10829                 :       60615 :               if (CONST_INT_P (addr))
   10830                 :             :                 return false;
   10831                 :             :             }
   10832                 :             :         }
   10833                 :             :     }
   10834                 :             : 
   10835                 :             :   /* Allow SImode subregs of DImode addresses,
   10836                 :             :      they will be emitted with addr32 prefix.  */
   10837                 :  4089075096 :   if (TARGET_64BIT && GET_MODE (addr) == SImode)
   10838                 :             :     {
   10839                 :    16198496 :       if (SUBREG_P (addr)
   10840                 :      196583 :           && GET_MODE (SUBREG_REG (addr)) == DImode)
   10841                 :             :         {
   10842                 :      176631 :           addr = SUBREG_REG (addr);
   10843                 :      176631 :           if (CONST_INT_P (addr))
   10844                 :             :             return false;
   10845                 :             :         }
   10846                 :             :     }
   10847                 :             : 
   10848                 :  4089075096 :   if (REG_P (addr))
   10849                 :             :     base = addr;
   10850                 :             :   else if (SUBREG_P (addr))
   10851                 :             :     {
   10852                 :      435028 :       if (REG_P (SUBREG_REG (addr)))
   10853                 :             :         base = addr;
   10854                 :             :       else
   10855                 :             :         return false;
   10856                 :             :     }
   10857                 :             :   else if (GET_CODE (addr) == PLUS)
   10858                 :             :     {
   10859                 :             :       rtx addends[4], op;
   10860                 :             :       int n = 0, i;
   10861                 :             : 
   10862                 :             :       op = addr;
   10863                 :  2985389477 :       do
   10864                 :             :         {
   10865                 :  2985389477 :           if (n >= 4)
   10866                 :   632485271 :             return false;
   10867                 :  2985384820 :           addends[n++] = XEXP (op, 1);
   10868                 :  2985384820 :           op = XEXP (op, 0);
   10869                 :             :         }
   10870                 :  2985384820 :       while (GET_CODE (op) == PLUS);
   10871                 :  2938673916 :       if (n >= 4)
   10872                 :             :         return false;
   10873                 :  2938667653 :       addends[n] = op;
   10874                 :             : 
   10875                 :  7601045418 :       for (i = n; i >= 0; --i)
   10876                 :             :         {
   10877                 :  5294852116 :           op = addends[i];
   10878                 :  5294852116 :           switch (GET_CODE (op))
   10879                 :             :             {
   10880                 :    56886395 :             case MULT:
   10881                 :    56886395 :               if (index)
   10882                 :             :                 return false;
   10883                 :    56846289 :               index = XEXP (op, 0);
   10884                 :    56846289 :               scale_rtx = XEXP (op, 1);
   10885                 :    56846289 :               break;
   10886                 :             : 
   10887                 :    11687603 :             case ASHIFT:
   10888                 :    11687603 :               if (index)
   10889                 :             :                 return false;
   10890                 :    11615587 :               index = XEXP (op, 0);
   10891                 :    11615587 :               tmp = XEXP (op, 1);
   10892                 :    11615587 :               if (!CONST_INT_P (tmp))
   10893                 :             :                 return false;
   10894                 :    11601506 :               scale = INTVAL (tmp);
   10895                 :    11601506 :               if ((unsigned HOST_WIDE_INT) scale > 3)
   10896                 :             :                 return false;
   10897                 :    11212644 :               scale = 1 << scale;
   10898                 :    11212644 :               break;
   10899                 :             : 
   10900                 :      729499 :             case ZERO_EXTEND:
   10901                 :      729499 :               op = XEXP (op, 0);
   10902                 :      729499 :               if (GET_CODE (op) != UNSPEC)
   10903                 :             :                 return false;
   10904                 :             :               /* FALLTHRU */
   10905                 :             : 
   10906                 :      614515 :             case UNSPEC:
   10907                 :      614515 :               if (XINT (op, 1) == UNSPEC_TP
   10908                 :      607223 :                   && TARGET_TLS_DIRECT_SEG_REFS
   10909                 :      607223 :                   && seg == ADDR_SPACE_GENERIC)
   10910                 :      607223 :                 seg = DEFAULT_TLS_SEG_REG;
   10911                 :             :               else
   10912                 :             :                 return false;
   10913                 :             :               break;
   10914                 :             : 
   10915                 :      512632 :             case SUBREG:
   10916                 :      512632 :               if (!REG_P (SUBREG_REG (op)))
   10917                 :             :                 return false;
   10918                 :             :               /* FALLTHRU */
   10919                 :             : 
   10920                 :  2356611648 :             case REG:
   10921                 :  2356611648 :               if (!base)
   10922                 :             :                 base = op;
   10923                 :    61751578 :               else if (!index)
   10924                 :             :                 index = op;
   10925                 :             :               else
   10926                 :             :                 return false;
   10927                 :             :               break;
   10928                 :             : 
   10929                 :  2237851843 :             case CONST:
   10930                 :  2237851843 :             case CONST_INT:
   10931                 :  2237851843 :             case SYMBOL_REF:
   10932                 :  2237851843 :             case LABEL_REF:
   10933                 :  2237851843 :               if (disp)
   10934                 :             :                 return false;
   10935                 :             :               disp = op;
   10936                 :             :               break;
   10937                 :             : 
   10938                 :             :             default:
   10939                 :             :               return false;
   10940                 :             :             }
   10941                 :             :         }
   10942                 :             :     }
   10943                 :             :   else if (GET_CODE (addr) == MULT)
   10944                 :             :     {
   10945                 :     3251024 :       index = XEXP (addr, 0);           /* index*scale */
   10946                 :     3251024 :       scale_rtx = XEXP (addr, 1);
   10947                 :             :     }
   10948                 :             :   else if (GET_CODE (addr) == ASHIFT)
   10949                 :             :     {
   10950                 :             :       /* We're called for lea too, which implements ashift on occasion.  */
   10951                 :     2884784 :       index = XEXP (addr, 0);
   10952                 :     2884784 :       tmp = XEXP (addr, 1);
   10953                 :     2884784 :       if (!CONST_INT_P (tmp))
   10954                 :             :         return false;
   10955                 :     2513425 :       scale = INTVAL (tmp);
   10956                 :     2513425 :       if ((unsigned HOST_WIDE_INT) scale > 3)
   10957                 :             :         return false;
   10958                 :     1799642 :       scale = 1 << scale;
   10959                 :             :     }
   10960                 :             :   else
   10961                 :             :     disp = addr;                        /* displacement */
   10962                 :             : 
   10963                 :  2311243968 :   if (index)
   10964                 :             :     {
   10965                 :   126331140 :       if (REG_P (index))
   10966                 :             :         ;
   10967                 :     3714041 :       else if (SUBREG_P (index)
   10968                 :      293054 :                && REG_P (SUBREG_REG (index)))
   10969                 :             :         ;
   10970                 :             :       else
   10971                 :             :         return false;
   10972                 :             :     }
   10973                 :             : 
   10974                 :             :   /* Extract the integral value of scale.  */
   10975                 :  3452013710 :   if (scale_rtx)
   10976                 :             :     {
   10977                 :    52523566 :       if (!CONST_INT_P (scale_rtx))
   10978                 :             :         return false;
   10979                 :    51972019 :       scale = INTVAL (scale_rtx);
   10980                 :             :     }
   10981                 :             : 
   10982                 :  3451462163 :   base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
   10983                 :  3451462163 :   index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
   10984                 :             : 
   10985                 :             :   /* Avoid useless 0 displacement.  */
   10986                 :  3451462163 :   if (disp == const0_rtx && (base || index))
   10987                 :  3451462163 :     disp = NULL_RTX;
   10988                 :             : 
   10989                 :             :   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   10990                 :  2516123953 :   if (base_reg && index_reg && scale == 1
   10991                 :  3511820928 :       && (REGNO (index_reg) == ARG_POINTER_REGNUM
   10992                 :             :           || REGNO (index_reg) == FRAME_POINTER_REGNUM
   10993                 :             :           || REGNO (index_reg) == SP_REG))
   10994                 :             :     {
   10995                 :             :       std::swap (base, index);
   10996                 :             :       std::swap (base_reg, index_reg);
   10997                 :             :     }
   10998                 :             : 
   10999                 :             :   /* Special case: %ebp cannot be encoded as a base without a displacement.
   11000                 :             :      Similarly %r13.  */
   11001                 :   295277417 :   if (!disp && base_reg
   11002                 :  3743139991 :       && (REGNO (base_reg) == ARG_POINTER_REGNUM
   11003                 :             :           || REGNO (base_reg) == FRAME_POINTER_REGNUM
   11004                 :             :           || REGNO (base_reg) == BP_REG
   11005                 :             :           || REGNO (base_reg) == R13_REG))
   11006                 :             :     disp = const0_rtx;
   11007                 :             : 
   11008                 :             :   /* Special case: on K6, [%esi] makes the instruction vector decoded.
   11009                 :             :      Avoid this by transforming to [%esi+0].
   11010                 :             :      Reload calls address legitimization without cfun defined, so we need
   11011                 :             :      to test cfun for being non-NULL. */
   11012                 :           0 :   if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
   11013                 :           0 :       && base_reg && !index_reg && !disp
   11014                 :  3451462163 :       && REGNO (base_reg) == SI_REG)
   11015                 :           0 :     disp = const0_rtx;
   11016                 :             : 
   11017                 :             :   /* Special case: encode reg+reg instead of reg*2.  */
   11018                 :  3451462163 :   if (!base && index && scale == 2)
   11019                 :   935338210 :     base = index, base_reg = index_reg, scale = 1;
   11020                 :             : 
   11021                 :             :   /* Special case: scaling cannot be encoded without base or displacement.  */
   11022                 :   935338210 :   if (!base && !disp && index && scale != 1)
   11023                 :     2838549 :     disp = const0_rtx;
   11024                 :             : 
   11025                 :  3451462163 :   out->base = base;
   11026                 :  3451462163 :   out->index = index;
   11027                 :  3451462163 :   out->disp = disp;
   11028                 :  3451462163 :   out->scale = scale;
   11029                 :  3451462163 :   out->seg = seg;
   11030                 :             : 
   11031                 :  3451462163 :   return true;
   11032                 :             : }
   11033                 :             : 
   11034                 :             : /* Return cost of the memory address x.
   11035                 :             :    For i386, it is better to use a complex address than let gcc copy
   11036                 :             :    the address into a reg and make a new pseudo.  But not if the address
   11037                 :             :    requires to two regs - that would mean more pseudos with longer
   11038                 :             :    lifetimes.  */
   11039                 :             : static int
   11040                 :     9449820 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
   11041                 :             : {
   11042                 :     9449820 :   struct ix86_address parts;
   11043                 :     9449820 :   int cost = 1;
   11044                 :     9449820 :   int ok = ix86_decompose_address (x, &parts);
   11045                 :             : 
   11046                 :     9449820 :   gcc_assert (ok);
   11047                 :             : 
   11048                 :     9449820 :   if (parts.base && SUBREG_P (parts.base))
   11049                 :         270 :     parts.base = SUBREG_REG (parts.base);
   11050                 :     9449820 :   if (parts.index && SUBREG_P (parts.index))
   11051                 :          20 :     parts.index = SUBREG_REG (parts.index);
   11052                 :             : 
   11053                 :             :   /* Attempt to minimize number of registers in the address by increasing
   11054                 :             :      address cost for each used register.  We don't increase address cost
   11055                 :             :      for "pic_offset_table_rtx".  When a memopt with "pic_offset_table_rtx"
   11056                 :             :      is not invariant itself it most likely means that base or index is not
   11057                 :             :      invariant.  Therefore only "pic_offset_table_rtx" could be hoisted out,
   11058                 :             :      which is not profitable for x86.  */
   11059                 :     9449820 :   if (parts.base
   11060                 :     8191864 :       && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
   11061                 :    17381041 :       && (current_pass->type == GIMPLE_PASS
   11062                 :     2208615 :           || !pic_offset_table_rtx
   11063                 :      113534 :           || !REG_P (parts.base)
   11064                 :      113534 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
   11065                 :             :     cost++;
   11066                 :             : 
   11067                 :     9449820 :   if (parts.index
   11068                 :     4632367 :       && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
   11069                 :    14068704 :       && (current_pass->type == GIMPLE_PASS
   11070                 :      510126 :           || !pic_offset_table_rtx
   11071                 :       43319 :           || !REG_P (parts.index)
   11072                 :       43319 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
   11073                 :     4617654 :     cost++;
   11074                 :             : 
   11075                 :             :   /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
   11076                 :             :      since it's predecode logic can't detect the length of instructions
   11077                 :             :      and it degenerates to vector decoded.  Increase cost of such
   11078                 :             :      addresses here.  The penalty is minimally 2 cycles.  It may be worthwhile
   11079                 :             :      to split such addresses or even refuse such addresses at all.
   11080                 :             : 
   11081                 :             :      Following addressing modes are affected:
   11082                 :             :       [base+scale*index]
   11083                 :             :       [scale*index+disp]
   11084                 :             :       [base+index]
   11085                 :             : 
   11086                 :             :      The first and last case  may be avoidable by explicitly coding the zero in
   11087                 :             :      memory address, but I don't have AMD-K6 machine handy to check this
   11088                 :             :      theory.  */
   11089                 :             : 
   11090                 :     9449820 :   if (TARGET_CPU_P (K6)
   11091                 :           0 :       && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
   11092                 :           0 :           || (parts.disp && !parts.base && parts.index && parts.scale != 1)
   11093                 :           0 :           || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
   11094                 :           0 :     cost += 10;
   11095                 :             : 
   11096                 :     9449820 :   return cost;
   11097                 :             : }
   11098                 :             : 
   11099                 :             : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
   11100                 :             :    this is used for to form addresses to local data when -fPIC is in
   11101                 :             :    use.  */
   11102                 :             : 
   11103                 :             : static bool
   11104                 :           0 : darwin_local_data_pic (rtx disp)
   11105                 :             : {
   11106                 :           0 :   return (GET_CODE (disp) == UNSPEC
   11107                 :           0 :           && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
   11108                 :             : }
   11109                 :             : 
   11110                 :             : /* True if the function symbol operand X should be loaded from GOT.
   11111                 :             :    If CALL_P is true, X is a call operand.
   11112                 :             : 
   11113                 :             :    NB: -mno-direct-extern-access doesn't force load from GOT for
   11114                 :             :    call.
   11115                 :             : 
   11116                 :             :    NB: In 32-bit mode, only non-PIC is allowed in inline assembly
   11117                 :             :    statements, since a PIC register could not be available at the
   11118                 :             :    call site.  */
   11119                 :             : 
   11120                 :             : bool
   11121                 :  1722571053 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
   11122                 :             : {
   11123                 :    93649680 :   return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
   11124                 :             :           && !TARGET_PECOFF && !TARGET_MACHO
   11125                 :  1719719999 :           && (!flag_pic || this_is_asm_operands)
   11126                 :  1701687908 :           && ix86_cmodel != CM_LARGE
   11127                 :  1701682085 :           && ix86_cmodel != CM_LARGE_PIC
   11128                 :  1701682084 :           && GET_CODE (x) == SYMBOL_REF
   11129                 :  1701682082 :           && ((!call_p
   11130                 :  1696455406 :                && (!ix86_direct_extern_access
   11131                 :  1696454069 :                    || (SYMBOL_REF_DECL (x)
   11132                 :  1515546515 :                        && lookup_attribute ("nodirect_extern_access",
   11133                 :  1515546515 :                                             DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
   11134                 :  1701680310 :               || (SYMBOL_REF_FUNCTION_P (x)
   11135                 :   636927260 :                   && (!flag_plt
   11136                 :   636923065 :                       || (SYMBOL_REF_DECL (x)
   11137                 :   636923065 :                           && lookup_attribute ("noplt",
   11138                 :   636923065 :                                                DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
   11139                 :  1722577401 :           && !SYMBOL_REF_LOCAL_P (x));
   11140                 :             : }
   11141                 :             : 
   11142                 :             : /* Determine if a given RTX is a valid constant.  We already know this
   11143                 :             :    satisfies CONSTANT_P.  */
   11144                 :             : 
   11145                 :             : static bool
   11146                 :  1464659164 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
   11147                 :             : {
   11148                 :  1464659164 :   switch (GET_CODE (x))
   11149                 :             :     {
   11150                 :   124329894 :     case CONST:
   11151                 :   124329894 :       x = XEXP (x, 0);
   11152                 :             : 
   11153                 :   124329894 :       if (GET_CODE (x) == PLUS)
   11154                 :             :         {
   11155                 :   124217191 :           if (!CONST_INT_P (XEXP (x, 1)))
   11156                 :             :             return false;
   11157                 :   124217191 :           x = XEXP (x, 0);
   11158                 :             :         }
   11159                 :             : 
   11160                 :   124329894 :       if (TARGET_MACHO && darwin_local_data_pic (x))
   11161                 :             :         return true;
   11162                 :             : 
   11163                 :             :       /* Only some unspecs are valid as "constants".  */
   11164                 :   124329894 :       if (GET_CODE (x) == UNSPEC)
   11165                 :      473955 :         switch (XINT (x, 1))
   11166                 :             :           {
   11167                 :       20630 :           case UNSPEC_GOT:
   11168                 :       20630 :           case UNSPEC_GOTOFF:
   11169                 :       20630 :           case UNSPEC_PLTOFF:
   11170                 :       20630 :             return TARGET_64BIT;
   11171                 :      452491 :           case UNSPEC_TPOFF:
   11172                 :      452491 :           case UNSPEC_NTPOFF:
   11173                 :      452491 :             x = XVECEXP (x, 0, 0);
   11174                 :      452491 :             return (GET_CODE (x) == SYMBOL_REF
   11175                 :      452491 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11176                 :         748 :           case UNSPEC_DTPOFF:
   11177                 :         748 :             x = XVECEXP (x, 0, 0);
   11178                 :         748 :             return (GET_CODE (x) == SYMBOL_REF
   11179                 :         748 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
   11180                 :             :           default:
   11181                 :             :             return false;
   11182                 :             :           }
   11183                 :             : 
   11184                 :             :       /* We must have drilled down to a symbol.  */
   11185                 :   123855939 :       if (GET_CODE (x) == LABEL_REF)
   11186                 :             :         return true;
   11187                 :   123852142 :       if (GET_CODE (x) != SYMBOL_REF)
   11188                 :             :         return false;
   11189                 :             :       /* FALLTHRU */
   11190                 :             : 
   11191                 :   865372972 :     case SYMBOL_REF:
   11192                 :             :       /* TLS symbols are never valid.  */
   11193                 :   865372972 :       if (SYMBOL_REF_TLS_MODEL (x))
   11194                 :             :         return false;
   11195                 :             : 
   11196                 :             :       /* DLLIMPORT symbols are never valid.  */
   11197                 :   865280505 :       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
   11198                 :             :           && SYMBOL_REF_DLLIMPORT_P (x))
   11199                 :             :         return false;
   11200                 :             : 
   11201                 :             : #if TARGET_MACHO
   11202                 :             :       /* mdynamic-no-pic */
   11203                 :             :       if (MACHO_DYNAMIC_NO_PIC_P)
   11204                 :             :         return machopic_symbol_defined_p (x);
   11205                 :             : #endif
   11206                 :             : 
   11207                 :             :       /* External function address should be loaded
   11208                 :             :          via the GOT slot to avoid PLT.  */
   11209                 :   865280505 :       if (ix86_force_load_from_GOT_p (x))
   11210                 :             :         return false;
   11211                 :             : 
   11212                 :             :       break;
   11213                 :             : 
   11214                 :   579160279 :     CASE_CONST_SCALAR_INT:
   11215                 :   579160279 :       if (ix86_endbr_immediate_operand (x, VOIDmode))
   11216                 :             :         return false;
   11217                 :             : 
   11218                 :   579160076 :       switch (mode)
   11219                 :             :         {
   11220                 :     1464699 :         case E_TImode:
   11221                 :     1464699 :           if (TARGET_64BIT)
   11222                 :             :             return true;
   11223                 :             :           /* FALLTHRU */
   11224                 :       21619 :         case E_OImode:
   11225                 :       21619 :         case E_XImode:
   11226                 :       21619 :           if (!standard_sse_constant_p (x, mode)
   11227                 :       34258 :               && GET_MODE_SIZE (TARGET_AVX512F && TARGET_EVEX512
   11228                 :             :                                 ? XImode
   11229                 :             :                                 : (TARGET_AVX
   11230                 :             :                                    ? OImode
   11231                 :             :                                    : (TARGET_SSE2
   11232                 :       12639 :                                       ? TImode : DImode))) < GET_MODE_SIZE (mode))
   11233                 :             :             return false;
   11234                 :             :         default:
   11235                 :             :           break;
   11236                 :             :         }
   11237                 :             :       break;
   11238                 :             : 
   11239                 :     7765189 :     case CONST_VECTOR:
   11240                 :     7765189 :       if (!standard_sse_constant_p (x, mode))
   11241                 :             :         return false;
   11242                 :             :       break;
   11243                 :             : 
   11244                 :     7573000 :     case CONST_DOUBLE:
   11245                 :     7573000 :       if (mode == E_BFmode)
   11246                 :             :         return false;
   11247                 :             : 
   11248                 :             :     default:
   11249                 :             :       break;
   11250                 :             :     }
   11251                 :             : 
   11252                 :             :   /* Otherwise we handle everything else in the move patterns.  */
   11253                 :             :   return true;
   11254                 :             : }
   11255                 :             : 
   11256                 :             : /* Determine if it's legal to put X into the constant pool.  This
   11257                 :             :    is not possible for the address of thread-local symbols, which
   11258                 :             :    is checked above.  */
   11259                 :             : 
   11260                 :             : static bool
   11261                 :    60314439 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   11262                 :             : {
   11263                 :             :   /* We can put any immediate constant in memory.  */
   11264                 :    60314439 :   switch (GET_CODE (x))
   11265                 :             :     {
   11266                 :             :     CASE_CONST_ANY:
   11267                 :             :       return false;
   11268                 :             : 
   11269                 :     1767329 :     default:
   11270                 :     1767329 :       break;
   11271                 :             :     }
   11272                 :             : 
   11273                 :     1767329 :   return !ix86_legitimate_constant_p (mode, x);
   11274                 :             : }
   11275                 :             : 
   11276                 :             : /* Return a unique alias set for the GOT.  */
   11277                 :             : 
   11278                 :             : alias_set_type
   11279                 :      183773 : ix86_GOT_alias_set (void)
   11280                 :             : {
   11281                 :      183773 :   static alias_set_type set = -1;
   11282                 :      183773 :   if (set == -1)
   11283                 :        2837 :     set = new_alias_set ();
   11284                 :      183773 :   return set;
   11285                 :             : }
   11286                 :             : 
   11287                 :             : /* Nonzero if the constant value X is a legitimate general operand
   11288                 :             :    when generating PIC code.  It is given that flag_pic is on and
   11289                 :             :    that X satisfies CONSTANT_P.  */
   11290                 :             : 
   11291                 :             : bool
   11292                 :   122194306 : legitimate_pic_operand_p (rtx x)
   11293                 :             : {
   11294                 :   122194306 :   rtx inner;
   11295                 :             : 
   11296                 :   122194306 :   switch (GET_CODE (x))
   11297                 :             :     {
   11298                 :     2456061 :     case CONST:
   11299                 :     2456061 :       inner = XEXP (x, 0);
   11300                 :     2456061 :       if (GET_CODE (inner) == PLUS
   11301                 :      344455 :           && CONST_INT_P (XEXP (inner, 1)))
   11302                 :      344455 :         inner = XEXP (inner, 0);
   11303                 :             : 
   11304                 :             :       /* Only some unspecs are valid as "constants".  */
   11305                 :     2456061 :       if (GET_CODE (inner) == UNSPEC)
   11306                 :     2215015 :         switch (XINT (inner, 1))
   11307                 :             :           {
   11308                 :     2155086 :           case UNSPEC_GOT:
   11309                 :     2155086 :           case UNSPEC_GOTOFF:
   11310                 :     2155086 :           case UNSPEC_PLTOFF:
   11311                 :     2155086 :             return TARGET_64BIT;
   11312                 :           0 :           case UNSPEC_TPOFF:
   11313                 :           0 :             x = XVECEXP (inner, 0, 0);
   11314                 :           0 :             return (GET_CODE (x) == SYMBOL_REF
   11315                 :           0 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11316                 :           0 :           case UNSPEC_MACHOPIC_OFFSET:
   11317                 :           0 :             return legitimate_pic_address_disp_p (x);
   11318                 :             :           default:
   11319                 :             :             return false;
   11320                 :             :           }
   11321                 :             :       /* FALLTHRU */
   11322                 :             : 
   11323                 :     6690331 :     case SYMBOL_REF:
   11324                 :     6690331 :     case LABEL_REF:
   11325                 :     6690331 :       return legitimate_pic_address_disp_p (x);
   11326                 :             : 
   11327                 :             :     default:
   11328                 :             :       return true;
   11329                 :             :     }
   11330                 :             : }
   11331                 :             : 
   11332                 :             : /* Determine if a given CONST RTX is a valid memory displacement
   11333                 :             :    in PIC mode.  */
   11334                 :             : 
   11335                 :             : bool
   11336                 :    61560080 : legitimate_pic_address_disp_p (rtx disp)
   11337                 :             : {
   11338                 :    61560080 :   bool saw_plus;
   11339                 :             : 
   11340                 :             :   /* In 64bit mode we can allow direct addresses of symbols and labels
   11341                 :             :      when they are not dynamic symbols.  */
   11342                 :    61560080 :   if (TARGET_64BIT)
   11343                 :             :     {
   11344                 :    37637737 :       rtx op0 = disp, op1;
   11345                 :             : 
   11346                 :    37637737 :       switch (GET_CODE (disp))
   11347                 :             :         {
   11348                 :             :         case LABEL_REF:
   11349                 :             :           return true;
   11350                 :             : 
   11351                 :    10404934 :         case CONST:
   11352                 :    10404934 :           if (GET_CODE (XEXP (disp, 0)) != PLUS)
   11353                 :             :             break;
   11354                 :     1077514 :           op0 = XEXP (XEXP (disp, 0), 0);
   11355                 :     1077514 :           op1 = XEXP (XEXP (disp, 0), 1);
   11356                 :     1077514 :           if (!CONST_INT_P (op1))
   11357                 :             :             break;
   11358                 :     1077514 :           if (GET_CODE (op0) == UNSPEC
   11359                 :         293 :               && (XINT (op0, 1) == UNSPEC_DTPOFF
   11360                 :         293 :                   || XINT (op0, 1) == UNSPEC_NTPOFF)
   11361                 :     1077807 :               && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
   11362                 :             :             return true;
   11363                 :     1077221 :           if (INTVAL (op1) >= 16*1024*1024
   11364                 :     1077221 :               || INTVAL (op1) < -16*1024*1024)
   11365                 :             :             break;
   11366                 :     1077133 :           if (GET_CODE (op0) == LABEL_REF)
   11367                 :             :             return true;
   11368                 :     1077133 :           if (GET_CODE (op0) == CONST
   11369                 :           0 :               && GET_CODE (XEXP (op0, 0)) == UNSPEC
   11370                 :           0 :               && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
   11371                 :             :             return true;
   11372                 :     1077133 :           if (GET_CODE (op0) == UNSPEC
   11373                 :           0 :               && XINT (op0, 1) == UNSPEC_PCREL)
   11374                 :             :             return true;
   11375                 :     1077133 :           if (GET_CODE (op0) != SYMBOL_REF)
   11376                 :             :             break;
   11377                 :             :           /* FALLTHRU */
   11378                 :             : 
   11379                 :    28096755 :         case SYMBOL_REF:
   11380                 :             :           /* TLS references should always be enclosed in UNSPEC.
   11381                 :             :              The dllimported symbol needs always to be resolved.  */
   11382                 :    28096755 :           if (SYMBOL_REF_TLS_MODEL (op0)
   11383                 :             :               || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
   11384                 :             :             return false;
   11385                 :             : 
   11386                 :    27948270 :           if (TARGET_PECOFF)
   11387                 :             :             {
   11388                 :             : #if TARGET_PECOFF
   11389                 :             :               if (is_imported_p (op0))
   11390                 :             :                 return true;
   11391                 :             : #endif
   11392                 :             : 
   11393                 :             :               if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
   11394                 :             :                 break;
   11395                 :             : 
   11396                 :             :               /* Non-external-weak function symbols need to be resolved only
   11397                 :             :                  for the large model.  Non-external symbols don't need to be
   11398                 :             :                  resolved for large and medium models.  For the small model,
   11399                 :             :                  we don't need to resolve anything here.  */
   11400                 :             :               if ((ix86_cmodel != CM_LARGE_PIC
   11401                 :             :                    && SYMBOL_REF_FUNCTION_P (op0)
   11402                 :             :                    && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
   11403                 :             :                   || !SYMBOL_REF_EXTERNAL_P (op0)
   11404                 :             :                   || ix86_cmodel == CM_SMALL_PIC)
   11405                 :             :                 return true;
   11406                 :             :             }
   11407                 :    27948270 :           else if (!SYMBOL_REF_FAR_ADDR_P (op0)
   11408                 :    27948266 :                    && (SYMBOL_REF_LOCAL_P (op0)
   11409                 :    16914965 :                        || ((ix86_direct_extern_access
   11410                 :    33620347 :                             && !(SYMBOL_REF_DECL (op0)
   11411                 :    16705539 :                                  && lookup_attribute ("nodirect_extern_access",
   11412                 :    16705539 :                                                       DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
   11413                 :             :                            && HAVE_LD_PIE_COPYRELOC
   11414                 :    16914651 :                            && flag_pie
   11415                 :       36379 :                            && !SYMBOL_REF_WEAK (op0)
   11416                 :       35991 :                            && !SYMBOL_REF_FUNCTION_P (op0)))
   11417                 :    38989237 :                    && ix86_cmodel != CM_LARGE_PIC)
   11418                 :             :             return true;
   11419                 :             :           break;
   11420                 :             : 
   11421                 :             :         default:
   11422                 :             :           break;
   11423                 :             :         }
   11424                 :             :     }
   11425                 :    50160869 :   if (GET_CODE (disp) != CONST)
   11426                 :             :     return false;
   11427                 :    14488186 :   disp = XEXP (disp, 0);
   11428                 :             : 
   11429                 :    14488186 :   if (TARGET_64BIT)
   11430                 :             :     {
   11431                 :             :       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
   11432                 :             :          of GOT tables.  We should not need these anyway.  */
   11433                 :     9375099 :       if (GET_CODE (disp) != UNSPEC
   11434                 :     9327420 :           || (XINT (disp, 1) != UNSPEC_GOTPCREL
   11435                 :     9327420 :               && XINT (disp, 1) != UNSPEC_GOTOFF
   11436                 :             :               && XINT (disp, 1) != UNSPEC_PCREL
   11437                 :             :               && XINT (disp, 1) != UNSPEC_PLTOFF))
   11438                 :             :         return false;
   11439                 :             : 
   11440                 :     9327420 :       if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
   11441                 :     9327420 :           && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
   11442                 :             :         return false;
   11443                 :             :       return true;
   11444                 :             :     }
   11445                 :             : 
   11446                 :     5113087 :   saw_plus = false;
   11447                 :     5113087 :   if (GET_CODE (disp) == PLUS)
   11448                 :             :     {
   11449                 :      568142 :       if (!CONST_INT_P (XEXP (disp, 1)))
   11450                 :             :         return false;
   11451                 :      568142 :       disp = XEXP (disp, 0);
   11452                 :      568142 :       saw_plus = true;
   11453                 :             :     }
   11454                 :             : 
   11455                 :     5113087 :   if (TARGET_MACHO && darwin_local_data_pic (disp))
   11456                 :             :     return true;
   11457                 :             : 
   11458                 :     5113087 :   if (GET_CODE (disp) != UNSPEC)
   11459                 :             :     return false;
   11460                 :             : 
   11461                 :     4954342 :   switch (XINT (disp, 1))
   11462                 :             :     {
   11463                 :     2265575 :     case UNSPEC_GOT:
   11464                 :     2265575 :       if (saw_plus)
   11465                 :             :         return false;
   11466                 :             :       /* We need to check for both symbols and labels because VxWorks loads
   11467                 :             :          text labels with @GOT rather than @GOTOFF.  See gotoff_operand for
   11468                 :             :          details.  */
   11469                 :     2265575 :       return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
   11470                 :     2265575 :               || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF);
   11471                 :     2688767 :     case UNSPEC_GOTOFF:
   11472                 :             :       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
   11473                 :             :          While ABI specify also 32bit relocation but we don't produce it in
   11474                 :             :          small PIC model at all.  */
   11475                 :     2688767 :       if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
   11476                 :     2688767 :            || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
   11477                 :             :           && !TARGET_64BIT)
   11478                 :     2688767 :         return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
   11479                 :             :       return false;
   11480                 :           0 :     case UNSPEC_GOTTPOFF:
   11481                 :           0 :     case UNSPEC_GOTNTPOFF:
   11482                 :           0 :     case UNSPEC_INDNTPOFF:
   11483                 :           0 :       if (saw_plus)
   11484                 :             :         return false;
   11485                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11486                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11487                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
   11488                 :           0 :     case UNSPEC_NTPOFF:
   11489                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11490                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11491                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
   11492                 :           0 :     case UNSPEC_DTPOFF:
   11493                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11494                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11495                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
   11496                 :             :     }
   11497                 :             : 
   11498                 :             :   return false;
   11499                 :             : }
   11500                 :             : 
   11501                 :             : /* Determine if op is suitable RTX for an address register.
   11502                 :             :    Return naked register if a register or a register subreg is
   11503                 :             :    found, otherwise return NULL_RTX.  */
   11504                 :             : 
   11505                 :             : static rtx
   11506                 :  1254333079 : ix86_validate_address_register (rtx op)
   11507                 :             : {
   11508                 :  1254333079 :   machine_mode mode = GET_MODE (op);
   11509                 :             : 
   11510                 :             :   /* Only SImode or DImode registers can form the address.  */
   11511                 :  1254333079 :   if (mode != SImode && mode != DImode)
   11512                 :             :     return NULL_RTX;
   11513                 :             : 
   11514                 :  1254325863 :   if (REG_P (op))
   11515                 :             :     return op;
   11516                 :      685341 :   else if (SUBREG_P (op))
   11517                 :             :     {
   11518                 :      685341 :       rtx reg = SUBREG_REG (op);
   11519                 :             : 
   11520                 :      685341 :       if (!REG_P (reg))
   11521                 :             :         return NULL_RTX;
   11522                 :             : 
   11523                 :      685341 :       mode = GET_MODE (reg);
   11524                 :             : 
   11525                 :             :       /* Don't allow SUBREGs that span more than a word.  It can
   11526                 :             :          lead to spill failures when the register is one word out
   11527                 :             :          of a two word structure.  */
   11528                 :     1415390 :       if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   11529                 :             :         return NULL_RTX;
   11530                 :             : 
   11531                 :             :       /* Allow only SUBREGs of non-eliminable hard registers.  */
   11532                 :      227501 :       if (register_no_elim_operand (reg, mode))
   11533                 :             :         return reg;
   11534                 :             :     }
   11535                 :             : 
   11536                 :             :   /* Op is not a register.  */
   11537                 :             :   return NULL_RTX;
   11538                 :             : }
   11539                 :             : 
   11540                 :             : /* Determine which memory address register set insn can use.  */
   11541                 :             : 
   11542                 :             : static enum attr_addr
   11543                 :   238310328 : ix86_memory_address_reg_class (rtx_insn* insn)
   11544                 :             : {
   11545                 :             :   /* LRA can do some initialization with NULL insn,
   11546                 :             :      return maximum register class in this case.  */
   11547                 :   238310328 :   enum attr_addr addr_rclass = ADDR_GPR32;
   11548                 :             : 
   11549                 :   238310328 :   if (!insn)
   11550                 :             :     return addr_rclass;
   11551                 :             : 
   11552                 :    68562949 :   if (asm_noperands (PATTERN (insn)) >= 0
   11553                 :    68562949 :       || GET_CODE (PATTERN (insn)) == ASM_INPUT)
   11554                 :       60516 :     return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
   11555                 :             : 
   11556                 :             :   /* Return maximum register class for unrecognized instructions.  */
   11557                 :    68532691 :   if (INSN_CODE (insn) < 0)
   11558                 :             :     return addr_rclass;
   11559                 :             : 
   11560                 :             :   /* Try to recognize the insn before calling get_attr_addr.
   11561                 :             :      Save current recog_data and current alternative.  */
   11562                 :    68532691 :   struct recog_data_d saved_recog_data = recog_data;
   11563                 :    68532691 :   int saved_alternative = which_alternative;
   11564                 :             : 
   11565                 :             :   /* Update recog_data for processing of alternatives.  */
   11566                 :    68532691 :   extract_insn_cached (insn);
   11567                 :             : 
   11568                 :             :   /* If current alternative is not set, loop throught enabled
   11569                 :             :      alternatives and get the most limited register class.  */
   11570                 :    68532691 :   if (saved_alternative == -1)
   11571                 :             :     {
   11572                 :    68532691 :       alternative_mask enabled = get_enabled_alternatives (insn);
   11573                 :             : 
   11574                 :  1187650396 :       for (int i = 0; i < recog_data.n_alternatives; i++)
   11575                 :             :         {
   11576                 :  1119117705 :           if (!TEST_BIT (enabled, i))
   11577                 :   330838392 :             continue;
   11578                 :             : 
   11579                 :   788279313 :           which_alternative = i;
   11580                 :   788279313 :           addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
   11581                 :             :         }
   11582                 :             :     }
   11583                 :             :   else
   11584                 :             :     {
   11585                 :           0 :       which_alternative = saved_alternative;
   11586                 :           0 :       addr_rclass = get_attr_addr (insn);
   11587                 :             :     }
   11588                 :             : 
   11589                 :    68532691 :   recog_data = saved_recog_data;
   11590                 :    68532691 :   which_alternative = saved_alternative;
   11591                 :             : 
   11592                 :    68532691 :   return addr_rclass;
   11593                 :             : }
   11594                 :             : 
   11595                 :             : /* Return memory address register class insn can use.  */
   11596                 :             : 
   11597                 :             : enum reg_class
   11598                 :   200086839 : ix86_insn_base_reg_class (rtx_insn* insn)
   11599                 :             : {
   11600                 :   200086839 :   switch (ix86_memory_address_reg_class (insn))
   11601                 :             :     {
   11602                 :             :     case ADDR_GPR8:
   11603                 :             :       return LEGACY_GENERAL_REGS;
   11604                 :             :     case ADDR_GPR16:
   11605                 :             :       return GENERAL_GPR16;
   11606                 :             :     case ADDR_GPR32:
   11607                 :             :       break;
   11608                 :           0 :     default:
   11609                 :           0 :       gcc_unreachable ();
   11610                 :             :     }
   11611                 :             : 
   11612                 :             :   return BASE_REG_CLASS;
   11613                 :             : }
   11614                 :             : 
   11615                 :             : bool
   11616                 :      959149 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
   11617                 :             : {
   11618                 :      959149 :   switch (ix86_memory_address_reg_class (insn))
   11619                 :             :     {
   11620                 :           0 :     case ADDR_GPR8:
   11621                 :           0 :       return LEGACY_INT_REGNO_P (regno);
   11622                 :           0 :     case ADDR_GPR16:
   11623                 :           0 :       return GENERAL_GPR16_REGNO_P (regno);
   11624                 :      959149 :     case ADDR_GPR32:
   11625                 :      959149 :       break;
   11626                 :           0 :     default:
   11627                 :           0 :       gcc_unreachable ();
   11628                 :             :     }
   11629                 :             : 
   11630                 :      959149 :   return GENERAL_REGNO_P (regno);
   11631                 :             : }
   11632                 :             : 
   11633                 :             : enum reg_class
   11634                 :    37264340 : ix86_insn_index_reg_class (rtx_insn* insn)
   11635                 :             : {
   11636                 :    37264340 :   switch (ix86_memory_address_reg_class (insn))
   11637                 :             :     {
   11638                 :             :     case ADDR_GPR8:
   11639                 :             :       return LEGACY_INDEX_REGS;
   11640                 :             :     case ADDR_GPR16:
   11641                 :             :       return INDEX_GPR16;
   11642                 :             :     case ADDR_GPR32:
   11643                 :             :       break;
   11644                 :           0 :     default:
   11645                 :           0 :       gcc_unreachable ();
   11646                 :             :     }
   11647                 :             : 
   11648                 :             :   return INDEX_REG_CLASS;
   11649                 :             : }
   11650                 :             : 
   11651                 :             : /* Recognizes RTL expressions that are valid memory addresses for an
   11652                 :             :    instruction.  The MODE argument is the machine mode for the MEM
   11653                 :             :    expression that wants to use this address.
   11654                 :             : 
   11655                 :             :    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
   11656                 :             :    convert common non-canonical forms to canonical form so that they will
   11657                 :             :    be recognized.  */
   11658                 :             : 
   11659                 :             : static bool
   11660                 :  2081517022 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
   11661                 :             :                            code_helper = ERROR_MARK)
   11662                 :             : {
   11663                 :  2081517022 :   struct ix86_address parts;
   11664                 :  2081517022 :   rtx base, index, disp;
   11665                 :  2081517022 :   HOST_WIDE_INT scale;
   11666                 :  2081517022 :   addr_space_t seg;
   11667                 :             : 
   11668                 :  2081517022 :   if (ix86_decompose_address (addr, &parts) == 0)
   11669                 :             :     /* Decomposition failed.  */
   11670                 :             :     return false;
   11671                 :             : 
   11672                 :  2070701878 :   base = parts.base;
   11673                 :  2070701878 :   index = parts.index;
   11674                 :  2070701878 :   disp = parts.disp;
   11675                 :  2070701878 :   scale = parts.scale;
   11676                 :  2070701878 :   seg = parts.seg;
   11677                 :             : 
   11678                 :             :   /* Validate base register.  */
   11679                 :  2070701878 :   if (base)
   11680                 :             :     {
   11681                 :  1180623945 :       rtx reg = ix86_validate_address_register (base);
   11682                 :             : 
   11683                 :  1180623945 :       if (reg == NULL_RTX)
   11684                 :             :         return false;
   11685                 :             : 
   11686                 :  1180208049 :       unsigned int regno = REGNO (reg);
   11687                 :  1180208049 :       if ((strict && !REGNO_OK_FOR_BASE_P (regno))
   11688                 :  1175899367 :           || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
   11689                 :             :         /* Base is not valid.  */
   11690                 :             :         return false;
   11691                 :             :     }
   11692                 :             : 
   11693                 :             :   /* Validate index register.  */
   11694                 :  2068969886 :   if (index)
   11695                 :             :     {
   11696                 :    73709134 :       rtx reg = ix86_validate_address_register (index);
   11697                 :             : 
   11698                 :    73709134 :       if (reg == NULL_RTX)
   11699                 :             :         return false;
   11700                 :             : 
   11701                 :    73659800 :       unsigned int regno = REGNO (reg);
   11702                 :    73659800 :       if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
   11703                 :    73653024 :           || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
   11704                 :             :         /* Index is not valid.  */
   11705                 :             :         return false;
   11706                 :             :     }
   11707                 :             : 
   11708                 :             :   /* Index and base should have the same mode.  */
   11709                 :  2068919642 :   if (base && index
   11710                 :    64608382 :       && GET_MODE (base) != GET_MODE (index))
   11711                 :             :     return false;
   11712                 :             : 
   11713                 :             :   /* Address override works only on the (%reg) part of %fs:(%reg).  */
   11714                 :  2068822472 :   if (seg != ADDR_SPACE_GENERIC
   11715                 :  2068822472 :       && ((base && GET_MODE (base) != word_mode)
   11716                 :      300692 :           || (index && GET_MODE (index) != word_mode)))
   11717                 :             :     return false;
   11718                 :             : 
   11719                 :             :   /* Validate scale factor.  */
   11720                 :  2068822469 :   if (scale != 1)
   11721                 :             :     {
   11722                 :    37252736 :       if (!index)
   11723                 :             :         /* Scale without index.  */
   11724                 :             :         return false;
   11725                 :             : 
   11726                 :    37252736 :       if (scale != 2 && scale != 4 && scale != 8)
   11727                 :             :         /* Scale is not a valid multiplier.  */
   11728                 :             :         return false;
   11729                 :             :     }
   11730                 :             : 
   11731                 :             :   /* Validate displacement.  */
   11732                 :  2065961401 :   if (disp)
   11733                 :             :     {
   11734                 :  1857144338 :       if (ix86_endbr_immediate_operand (disp, VOIDmode))
   11735                 :             :         return false;
   11736                 :             : 
   11737                 :  1857144295 :       if (GET_CODE (disp) == CONST
   11738                 :   134400642 :           && GET_CODE (XEXP (disp, 0)) == UNSPEC
   11739                 :    14786395 :           && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
   11740                 :    14786395 :         switch (XINT (XEXP (disp, 0), 1))
   11741                 :             :           {
   11742                 :             :           /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
   11743                 :             :              when used.  While ABI specify also 32bit relocations, we
   11744                 :             :              don't produce them at all and use IP relative instead.
   11745                 :             :              Allow GOT in 32bit mode for both PIC and non-PIC if symbol
   11746                 :             :              should be loaded via GOT.  */
   11747                 :     2265626 :           case UNSPEC_GOT:
   11748                 :     2265626 :             if (!TARGET_64BIT
   11749                 :     2265626 :                 && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   11750                 :           0 :               goto is_legitimate_pic;
   11751                 :             :             /* FALLTHRU */
   11752                 :     4545047 :           case UNSPEC_GOTOFF:
   11753                 :     4545047 :             gcc_assert (flag_pic);
   11754                 :     4545047 :             if (!TARGET_64BIT)
   11755                 :     4544945 :               goto is_legitimate_pic;
   11756                 :             : 
   11757                 :             :             /* 64bit address unspec.  */
   11758                 :             :             return false;
   11759                 :             : 
   11760                 :     9327392 :           case UNSPEC_GOTPCREL:
   11761                 :     9327392 :             if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   11762                 :        2464 :               goto is_legitimate_pic;
   11763                 :             :             /* FALLTHRU */
   11764                 :     9324928 :           case UNSPEC_PCREL:
   11765                 :     9324928 :             gcc_assert (flag_pic);
   11766                 :     9324928 :             goto is_legitimate_pic;
   11767                 :             : 
   11768                 :             :           case UNSPEC_GOTTPOFF:
   11769                 :             :           case UNSPEC_GOTNTPOFF:
   11770                 :             :           case UNSPEC_INDNTPOFF:
   11771                 :             :           case UNSPEC_NTPOFF:
   11772                 :             :           case UNSPEC_DTPOFF:
   11773                 :             :             break;
   11774                 :             : 
   11775                 :             :           default:
   11776                 :             :             /* Invalid address unspec.  */
   11777                 :             :             return false;
   11778                 :             :           }
   11779                 :             : 
   11780                 :  1160581306 :       else if (SYMBOLIC_CONST (disp)
   11781                 :  1961972147 :                && (flag_pic
   11782                 :             : #if TARGET_MACHO
   11783                 :             :                    || (MACHOPIC_INDIRECT
   11784                 :             :                        && !machopic_operand_p (disp))
   11785                 :             : #endif
   11786                 :             :                   ))
   11787                 :             :         {
   11788                 :             : 
   11789                 :    54711682 :         is_legitimate_pic:
   11790                 :    54711682 :           if (TARGET_64BIT && (index || base))
   11791                 :             :             {
   11792                 :             :               /* foo@dtpoff(%rX) is ok.  */
   11793                 :       35992 :               if (GET_CODE (disp) != CONST
   11794                 :        6739 :                   || GET_CODE (XEXP (disp, 0)) != PLUS
   11795                 :        6739 :                   || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
   11796                 :        4439 :                   || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
   11797                 :        4439 :                   || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
   11798                 :        4439 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
   11799                 :             :                 /* Non-constant pic memory reference.  */
   11800                 :             :                 return false;
   11801                 :             :             }
   11802                 :    54675690 :           else if ((!TARGET_MACHO || flag_pic)
   11803                 :    54675690 :                     && ! legitimate_pic_address_disp_p (disp))
   11804                 :             :             /* Displacement is an invalid pic construct.  */
   11805                 :             :             return false;
   11806                 :             : #if TARGET_MACHO
   11807                 :             :           else if (MACHO_DYNAMIC_NO_PIC_P
   11808                 :             :                    && !ix86_legitimate_constant_p (Pmode, disp))
   11809                 :             :             /* displacment must be referenced via non_lazy_pointer */
   11810                 :             :             return false;
   11811                 :             : #endif
   11812                 :             : 
   11813                 :             :           /* This code used to verify that a symbolic pic displacement
   11814                 :             :              includes the pic_offset_table_rtx register.
   11815                 :             : 
   11816                 :             :              While this is good idea, unfortunately these constructs may
   11817                 :             :              be created by "adds using lea" optimization for incorrect
   11818                 :             :              code like:
   11819                 :             : 
   11820                 :             :              int a;
   11821                 :             :              int foo(int i)
   11822                 :             :                {
   11823                 :             :                  return *(&a+i);
   11824                 :             :                }
   11825                 :             : 
   11826                 :             :              This code is nonsensical, but results in addressing
   11827                 :             :              GOT table with pic_offset_table_rtx base.  We can't
   11828                 :             :              just refuse it easily, since it gets matched by
   11829                 :             :              "addsi3" pattern, that later gets split to lea in the
   11830                 :             :              case output register differs from input.  While this
   11831                 :             :              can be handled by separate addsi pattern for this case
   11832                 :             :              that never results in lea, this seems to be easier and
   11833                 :             :              correct fix for crash to disable this test.  */
   11834                 :             :         }
   11835                 :  1801518555 :       else if (GET_CODE (disp) != LABEL_REF
   11836                 :  1801354465 :                && !CONST_INT_P (disp)
   11837                 :   816167611 :                && (GET_CODE (disp) != CONST
   11838                 :   118210781 :                    || !ix86_legitimate_constant_p (Pmode, disp))
   11839                 :  2499485196 :                && (GET_CODE (disp) != SYMBOL_REF
   11840                 :   642176625 :                    || !ix86_legitimate_constant_p (Pmode, disp)))
   11841                 :             :         /* Displacement is not constant.  */
   11842                 :    55847999 :         return false;
   11843                 :  1745670556 :       else if (TARGET_64BIT
   11844                 :  1745670556 :                && !x86_64_immediate_operand (disp, VOIDmode))
   11845                 :             :         /* Displacement is out of range.  */
   11846                 :             :         return false;
   11847                 :             :       /* In x32 mode, constant addresses are sign extended to 64bit, so
   11848                 :             :          we have to prevent addresses from 0x80000000 to 0xffffffff.  */
   11849                 :       29695 :       else if (TARGET_X32 && !(index || base)
   11850                 :       15366 :                && CONST_INT_P (disp)
   11851                 :  1745212829 :                && val_signbit_known_set_p (SImode, INTVAL (disp)))
   11852                 :             :         return false;
   11853                 :             :     }
   11854                 :             : 
   11855                 :             :   /* Everything looks valid.  */
   11856                 :             :   return true;
   11857                 :             : }
   11858                 :             : 
   11859                 :             : /* Determine if a given RTX is a valid constant address.  */
   11860                 :             : 
   11861                 :             : bool
   11862                 :  2503188175 : constant_address_p (rtx x)
   11863                 :             : {
   11864                 :  2503188175 :   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
   11865                 :             : }
   11866                 :             : 
   11867                 :             : 
   11868                 :             : /* Return a legitimate reference for ORIG (an address) using the
   11869                 :             :    register REG.  If REG is 0, a new pseudo is generated.
   11870                 :             : 
   11871                 :             :    There are two types of references that must be handled:
   11872                 :             : 
   11873                 :             :    1. Global data references must load the address from the GOT, via
   11874                 :             :       the PIC reg.  An insn is emitted to do this load, and the reg is
   11875                 :             :       returned.
   11876                 :             : 
   11877                 :             :    2. Static data references, constant pool addresses, and code labels
   11878                 :             :       compute the address as an offset from the GOT, whose base is in
   11879                 :             :       the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
   11880                 :             :       differentiate them from global data objects.  The returned
   11881                 :             :       address is the PIC reg + an unspec constant.
   11882                 :             : 
   11883                 :             :    TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
   11884                 :             :    reg also appears in the address.  */
   11885                 :             : 
   11886                 :             : rtx
   11887                 :      392218 : legitimize_pic_address (rtx orig, rtx reg)
   11888                 :             : {
   11889                 :      392218 :   rtx addr = orig;
   11890                 :      392218 :   rtx new_rtx = orig;
   11891                 :             : 
   11892                 :             : #if TARGET_MACHO
   11893                 :             :   if (TARGET_MACHO && !TARGET_64BIT)
   11894                 :             :     {
   11895                 :             :       if (reg == 0)
   11896                 :             :         reg = gen_reg_rtx (Pmode);
   11897                 :             :       /* Use the generic Mach-O PIC machinery.  */
   11898                 :             :       return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
   11899                 :             :     }
   11900                 :             : #endif
   11901                 :             : 
   11902                 :      392218 :   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   11903                 :             :     {
   11904                 :             : #if TARGET_PECOFF
   11905                 :             :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   11906                 :             :       if (tmp)
   11907                 :             :         return tmp;
   11908                 :             : #endif
   11909                 :             :     }
   11910                 :             : 
   11911                 :      392218 :   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
   11912                 :             :     new_rtx = addr;
   11913                 :      297723 :   else if ((!TARGET_64BIT
   11914                 :       99564 :             || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
   11915                 :             :            && !TARGET_PECOFF
   11916                 :      297802 :            && gotoff_operand (addr, Pmode))
   11917                 :             :     {
   11918                 :             :       /* This symbol may be referenced via a displacement
   11919                 :             :          from the PIC base address (@GOTOFF).  */
   11920                 :       96449 :       if (GET_CODE (addr) == CONST)
   11921                 :        2939 :         addr = XEXP (addr, 0);
   11922                 :             : 
   11923                 :       96449 :       if (GET_CODE (addr) == PLUS)
   11924                 :             :           {
   11925                 :        2939 :             new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
   11926                 :             :                                       UNSPEC_GOTOFF);
   11927                 :        2939 :             new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
   11928                 :             :           }
   11929                 :             :         else
   11930                 :       93510 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
   11931                 :             : 
   11932                 :       96449 :       new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11933                 :             : 
   11934                 :       96449 :       if (TARGET_64BIT)
   11935                 :          12 :         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11936                 :             : 
   11937                 :       96449 :       if (reg != 0)
   11938                 :             :         {
   11939                 :           3 :           gcc_assert (REG_P (reg));
   11940                 :           3 :           new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   11941                 :             :                                          new_rtx, reg, 1, OPTAB_DIRECT);
   11942                 :             :         }
   11943                 :             :       else
   11944                 :       96446 :         new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   11945                 :             :     }
   11946                 :      375590 :   else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
   11947                 :             :            /* We can't always use @GOTOFF for text labels
   11948                 :             :               on VxWorks, see gotoff_operand.  */
   11949                 :      201274 :            || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
   11950                 :             :     {
   11951                 :             : #if TARGET_PECOFF
   11952                 :             :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   11953                 :             :       if (tmp)
   11954                 :             :         return tmp;
   11955                 :             : #endif
   11956                 :             : 
   11957                 :             :       /* For x64 PE-COFF there is no GOT table,
   11958                 :             :          so we use address directly.  */
   11959                 :      174313 :       if (TARGET_64BIT && TARGET_PECOFF)
   11960                 :             :         {
   11961                 :             :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
   11962                 :             :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11963                 :             :         }
   11964                 :      174313 :       else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
   11965                 :             :         {
   11966                 :       92391 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
   11967                 :             :                                     UNSPEC_GOTPCREL);
   11968                 :       92391 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11969                 :       92391 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   11970                 :       92391 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   11971                 :             :         }
   11972                 :             :       else
   11973                 :             :         {
   11974                 :             :           /* This symbol must be referenced via a load
   11975                 :             :              from the Global Offset Table (@GOT).  */
   11976                 :       81922 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
   11977                 :       81922 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11978                 :             : 
   11979                 :       81922 :           if (TARGET_64BIT)
   11980                 :          22 :             new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11981                 :             : 
   11982                 :       81922 :           if (reg != 0)
   11983                 :             :             {
   11984                 :           0 :               gcc_assert (REG_P (reg));
   11985                 :           0 :               new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   11986                 :             :                                              new_rtx, reg, 1, OPTAB_DIRECT);
   11987                 :             :             }
   11988                 :             :           else
   11989                 :       81922 :             new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   11990                 :             : 
   11991                 :       81922 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   11992                 :       81922 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   11993                 :             :         }
   11994                 :             : 
   11995                 :      174313 :       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11996                 :             :     }
   11997                 :             :   else
   11998                 :             :     {
   11999                 :       26961 :       if (CONST_INT_P (addr)
   12000                 :       26961 :           && !x86_64_immediate_operand (addr, VOIDmode))
   12001                 :           8 :         new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
   12002                 :       26953 :       else if (GET_CODE (addr) == CONST)
   12003                 :             :         {
   12004                 :       16620 :           addr = XEXP (addr, 0);
   12005                 :             : 
   12006                 :             :           /* We must match stuff we generate before.  Assume the only
   12007                 :             :              unspecs that can get here are ours.  Not that we could do
   12008                 :             :              anything with them anyway....  */
   12009                 :       16620 :           if (GET_CODE (addr) == UNSPEC
   12010                 :        8852 :               || (GET_CODE (addr) == PLUS
   12011                 :        8852 :                   && GET_CODE (XEXP (addr, 0)) == UNSPEC))
   12012                 :             :             return orig;
   12013                 :        6760 :           gcc_assert (GET_CODE (addr) == PLUS);
   12014                 :             :         }
   12015                 :             : 
   12016                 :       17101 :       if (GET_CODE (addr) == PLUS)
   12017                 :             :         {
   12018                 :        8551 :           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
   12019                 :             : 
   12020                 :             :           /* Check first to see if this is a constant
   12021                 :             :              offset from a @GOTOFF symbol reference.  */
   12022                 :        8551 :           if (!TARGET_PECOFF
   12023                 :        8551 :               && gotoff_operand (op0, Pmode)
   12024                 :        8551 :               && CONST_INT_P (op1))
   12025                 :             :             {
   12026                 :           4 :               if (!TARGET_64BIT)
   12027                 :             :                 {
   12028                 :           0 :                   new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
   12029                 :             :                                             UNSPEC_GOTOFF);
   12030                 :           0 :                   new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
   12031                 :           0 :                   new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12032                 :             : 
   12033                 :           0 :                   if (reg != 0)
   12034                 :             :                     {
   12035                 :           0 :                       gcc_assert (REG_P (reg));
   12036                 :           0 :                       new_rtx = expand_simple_binop (Pmode, PLUS,
   12037                 :             :                                                      pic_offset_table_rtx,
   12038                 :             :                                                      new_rtx, reg, 1,
   12039                 :             :                                                      OPTAB_DIRECT);
   12040                 :             :                     }
   12041                 :             :                   else
   12042                 :           0 :                     new_rtx
   12043                 :           0 :                       = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12044                 :             :                 }
   12045                 :             :               else
   12046                 :             :                 {
   12047                 :           4 :                   if (INTVAL (op1) < -16*1024*1024
   12048                 :           4 :                       || INTVAL (op1) >= 16*1024*1024)
   12049                 :             :                     {
   12050                 :           4 :                       if (!x86_64_immediate_operand (op1, Pmode))
   12051                 :           4 :                         op1 = force_reg (Pmode, op1);
   12052                 :             : 
   12053                 :           4 :                       new_rtx
   12054                 :           4 :                         = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
   12055                 :             :                     }
   12056                 :             :                 }
   12057                 :             :             }
   12058                 :             :           else
   12059                 :             :             {
   12060                 :        8547 :               rtx base = legitimize_pic_address (op0, reg);
   12061                 :        8547 :               machine_mode mode = GET_MODE (base);
   12062                 :        8547 :               new_rtx
   12063                 :        8547 :                 = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
   12064                 :             : 
   12065                 :        8547 :               if (CONST_INT_P (new_rtx))
   12066                 :             :                 {
   12067                 :        6748 :                   if (INTVAL (new_rtx) < -16*1024*1024
   12068                 :        6748 :                       || INTVAL (new_rtx) >= 16*1024*1024)
   12069                 :             :                     {
   12070                 :           0 :                       if (!x86_64_immediate_operand (new_rtx, mode))
   12071                 :           0 :                         new_rtx = force_reg (mode, new_rtx);
   12072                 :             : 
   12073                 :           0 :                       new_rtx
   12074                 :           0 :                         = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
   12075                 :             :                     }
   12076                 :             :                   else
   12077                 :        6748 :                     new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
   12078                 :             :                 }
   12079                 :             :               else
   12080                 :             :                 {
   12081                 :             :                   /* For %rip addressing, we have to use
   12082                 :             :                      just disp32, not base nor index.  */
   12083                 :        1799 :                   if (TARGET_64BIT
   12084                 :          99 :                       && (GET_CODE (base) == SYMBOL_REF
   12085                 :          99 :                           || GET_CODE (base) == LABEL_REF))
   12086                 :           7 :                     base = force_reg (mode, base);
   12087                 :        1799 :                   if (GET_CODE (new_rtx) == PLUS
   12088                 :        1678 :                       && CONSTANT_P (XEXP (new_rtx, 1)))
   12089                 :             :                     {
   12090                 :        1674 :                       base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
   12091                 :        1674 :                       new_rtx = XEXP (new_rtx, 1);
   12092                 :             :                     }
   12093                 :        1799 :                   new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
   12094                 :             :                 }
   12095                 :             :             }
   12096                 :             :         }
   12097                 :             :     }
   12098                 :             :   return new_rtx;
   12099                 :             : }
   12100                 :             : 
   12101                 :             : /* Load the thread pointer.  If TO_REG is true, force it into a register.  */
   12102                 :             : 
   12103                 :             : static rtx
   12104                 :       22198 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
   12105                 :             : {
   12106                 :       22198 :   rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
   12107                 :             : 
   12108                 :       22198 :   if (GET_MODE (tp) != tp_mode)
   12109                 :             :     {
   12110                 :          11 :       gcc_assert (GET_MODE (tp) == SImode);
   12111                 :          11 :       gcc_assert (tp_mode == DImode);
   12112                 :             : 
   12113                 :          11 :       tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
   12114                 :             :     }
   12115                 :             : 
   12116                 :       22198 :   if (to_reg)
   12117                 :        7720 :     tp = copy_to_mode_reg (tp_mode, tp);
   12118                 :             : 
   12119                 :       22198 :   return tp;
   12120                 :             : }
   12121                 :             : 
   12122                 :             : /* Construct the SYMBOL_REF for the tls_get_addr function.  */
   12123                 :             : 
   12124                 :             : static GTY(()) rtx ix86_tls_symbol;
   12125                 :             : 
   12126                 :             : static rtx
   12127                 :        6717 : ix86_tls_get_addr (void)
   12128                 :             : {
   12129                 :        6717 :   if (!ix86_tls_symbol)
   12130                 :             :     {
   12131                 :         750 :       const char *sym
   12132                 :         375 :         = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
   12133                 :         375 :            ? "___tls_get_addr" : "__tls_get_addr");
   12134                 :             : 
   12135                 :         375 :       ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
   12136                 :             :     }
   12137                 :             : 
   12138                 :        6717 :   if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
   12139                 :             :     {
   12140                 :           0 :       rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
   12141                 :             :                                    UNSPEC_PLTOFF);
   12142                 :           0 :       return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
   12143                 :             :                            gen_rtx_CONST (Pmode, unspec));
   12144                 :             :     }
   12145                 :             : 
   12146                 :        6717 :   return ix86_tls_symbol;
   12147                 :             : }
   12148                 :             : 
   12149                 :             : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
   12150                 :             : 
   12151                 :             : static GTY(()) rtx ix86_tls_module_base_symbol;
   12152                 :             : 
   12153                 :             : rtx
   12154                 :          18 : ix86_tls_module_base (void)
   12155                 :             : {
   12156                 :          18 :   if (!ix86_tls_module_base_symbol)
   12157                 :             :     {
   12158                 :           3 :       ix86_tls_module_base_symbol
   12159                 :           3 :         = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
   12160                 :             : 
   12161                 :           3 :       SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
   12162                 :           3 :         |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
   12163                 :             :     }
   12164                 :             : 
   12165                 :          18 :   return ix86_tls_module_base_symbol;
   12166                 :             : }
   12167                 :             : 
   12168                 :             : /* A subroutine of ix86_legitimize_address and ix86_expand_move.  FOR_MOV is
   12169                 :             :    false if we expect this to be used for a memory address and true if
   12170                 :             :    we expect to load the address into a register.  */
   12171                 :             : 
   12172                 :             : rtx
   12173                 :       28915 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
   12174                 :             : {
   12175                 :       28915 :   rtx dest, base, off;
   12176                 :       28915 :   rtx pic = NULL_RTX, tp = NULL_RTX;
   12177                 :       28915 :   machine_mode tp_mode = Pmode;
   12178                 :       28915 :   int type;
   12179                 :             : 
   12180                 :             :   /* Fall back to global dynamic model if tool chain cannot support local
   12181                 :             :      dynamic.  */
   12182                 :       28915 :   if (TARGET_SUN_TLS && !TARGET_64BIT
   12183                 :             :       && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
   12184                 :             :       && model == TLS_MODEL_LOCAL_DYNAMIC)
   12185                 :             :     model = TLS_MODEL_GLOBAL_DYNAMIC;
   12186                 :             : 
   12187                 :       28915 :   switch (model)
   12188                 :             :     {
   12189                 :        6299 :     case TLS_MODEL_GLOBAL_DYNAMIC:
   12190                 :        6299 :       if (!TARGET_64BIT)
   12191                 :             :         {
   12192                 :        1976 :           if (flag_pic && !TARGET_PECOFF)
   12193                 :        1976 :             pic = pic_offset_table_rtx;
   12194                 :             :           else
   12195                 :             :             {
   12196                 :           0 :               pic = gen_reg_rtx (Pmode);
   12197                 :           0 :               emit_insn (gen_set_got (pic));
   12198                 :             :             }
   12199                 :             :         }
   12200                 :             : 
   12201                 :        6299 :       if (TARGET_GNU2_TLS)
   12202                 :             :         {
   12203                 :          14 :           dest = gen_reg_rtx (ptr_mode);
   12204                 :          14 :           if (TARGET_64BIT)
   12205                 :          14 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
   12206                 :             :           else
   12207                 :           0 :             emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
   12208                 :             : 
   12209                 :          14 :           tp = get_thread_pointer (ptr_mode, true);
   12210                 :          14 :           dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12211                 :          14 :           if (GET_MODE (dest) != Pmode)
   12212                 :           6 :              dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12213                 :          14 :           dest = force_reg (Pmode, dest);
   12214                 :             : 
   12215                 :          14 :           if (GET_MODE (x) != Pmode)
   12216                 :           3 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12217                 :             : 
   12218                 :          14 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12219                 :             :         }
   12220                 :             :       else
   12221                 :             :         {
   12222                 :        6285 :           rtx caddr = ix86_tls_get_addr ();
   12223                 :             : 
   12224                 :        6285 :           dest = gen_reg_rtx (Pmode);
   12225                 :        6285 :           if (TARGET_64BIT)
   12226                 :             :             {
   12227                 :        4309 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12228                 :        4309 :               rtx_insn *insns;
   12229                 :             : 
   12230                 :        4309 :               start_sequence ();
   12231                 :        4309 :               emit_call_insn
   12232                 :        4309 :                 (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr));
   12233                 :        4309 :               insns = get_insns ();
   12234                 :        4309 :               end_sequence ();
   12235                 :             : 
   12236                 :        4309 :               if (GET_MODE (x) != Pmode)
   12237                 :           1 :                 x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12238                 :             : 
   12239                 :        4309 :               RTL_CONST_CALL_P (insns) = 1;
   12240                 :        4309 :               emit_libcall_block (insns, dest, rax, x);
   12241                 :             :             }
   12242                 :             :           else
   12243                 :        1976 :             emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
   12244                 :             :         }
   12245                 :             :       break;
   12246                 :             : 
   12247                 :         440 :     case TLS_MODEL_LOCAL_DYNAMIC:
   12248                 :         440 :       if (!TARGET_64BIT)
   12249                 :             :         {
   12250                 :         110 :           if (flag_pic)
   12251                 :         110 :             pic = pic_offset_table_rtx;
   12252                 :             :           else
   12253                 :             :             {
   12254                 :           0 :               pic = gen_reg_rtx (Pmode);
   12255                 :           0 :               emit_insn (gen_set_got (pic));
   12256                 :             :             }
   12257                 :             :         }
   12258                 :             : 
   12259                 :         440 :       if (TARGET_GNU2_TLS)
   12260                 :             :         {
   12261                 :           8 :           rtx tmp = ix86_tls_module_base ();
   12262                 :             : 
   12263                 :           8 :           base = gen_reg_rtx (ptr_mode);
   12264                 :           8 :           if (TARGET_64BIT)
   12265                 :           8 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
   12266                 :             :           else
   12267                 :           0 :             emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
   12268                 :             : 
   12269                 :           8 :           tp = get_thread_pointer (ptr_mode, true);
   12270                 :           8 :           if (GET_MODE (base) != Pmode)
   12271                 :           2 :             base = gen_rtx_ZERO_EXTEND (Pmode, base);
   12272                 :           8 :           base = force_reg (Pmode, base);
   12273                 :             :         }
   12274                 :             :       else
   12275                 :             :         {
   12276                 :         432 :           rtx caddr = ix86_tls_get_addr ();
   12277                 :             : 
   12278                 :         432 :           base = gen_reg_rtx (Pmode);
   12279                 :         432 :           if (TARGET_64BIT)
   12280                 :             :             {
   12281                 :         322 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12282                 :         322 :               rtx_insn *insns;
   12283                 :         322 :               rtx eqv;
   12284                 :             : 
   12285                 :         322 :               start_sequence ();
   12286                 :         322 :               emit_call_insn
   12287                 :         322 :                 (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr));
   12288                 :         322 :               insns = get_insns ();
   12289                 :         322 :               end_sequence ();
   12290                 :             : 
   12291                 :             :               /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
   12292                 :             :                  share the LD_BASE result with other LD model accesses.  */
   12293                 :         322 :               eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   12294                 :             :                                     UNSPEC_TLS_LD_BASE);
   12295                 :             : 
   12296                 :         322 :               RTL_CONST_CALL_P (insns) = 1;
   12297                 :         322 :               emit_libcall_block (insns, base, rax, eqv);
   12298                 :             :             }
   12299                 :             :           else
   12300                 :         110 :             emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
   12301                 :             :         }
   12302                 :             : 
   12303                 :         440 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
   12304                 :         440 :       off = gen_rtx_CONST (Pmode, off);
   12305                 :             : 
   12306                 :         440 :       dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
   12307                 :             : 
   12308                 :         440 :       if (TARGET_GNU2_TLS)
   12309                 :             :         {
   12310                 :           8 :           if (GET_MODE (tp) != Pmode)
   12311                 :             :             {
   12312                 :           2 :               dest = lowpart_subreg (ptr_mode, dest, Pmode);
   12313                 :           2 :               dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12314                 :           2 :               dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12315                 :             :             }
   12316                 :             :           else
   12317                 :           6 :             dest = gen_rtx_PLUS (Pmode, tp, dest);
   12318                 :           8 :           dest = force_reg (Pmode, dest);
   12319                 :             : 
   12320                 :           8 :           if (GET_MODE (x) != Pmode)
   12321                 :           1 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12322                 :             : 
   12323                 :           8 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12324                 :             :         }
   12325                 :             :       break;
   12326                 :             : 
   12327                 :        9440 :     case TLS_MODEL_INITIAL_EXEC:
   12328                 :        9440 :       if (TARGET_64BIT)
   12329                 :             :         {
   12330                 :             :           /* Generate DImode references to avoid %fs:(%reg32)
   12331                 :             :              problems and linker IE->LE relaxation bug.  */
   12332                 :             :           tp_mode = DImode;
   12333                 :             :           pic = NULL;
   12334                 :             :           type = UNSPEC_GOTNTPOFF;
   12335                 :             :         }
   12336                 :         731 :       else if (flag_pic)
   12337                 :             :         {
   12338                 :         730 :           pic = pic_offset_table_rtx;
   12339                 :         730 :           type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
   12340                 :             :         }
   12341                 :           1 :       else if (!TARGET_ANY_GNU_TLS)
   12342                 :             :         {
   12343                 :           0 :           pic = gen_reg_rtx (Pmode);
   12344                 :           0 :           emit_insn (gen_set_got (pic));
   12345                 :           0 :           type = UNSPEC_GOTTPOFF;
   12346                 :             :         }
   12347                 :             :       else
   12348                 :             :         {
   12349                 :             :           pic = NULL;
   12350                 :             :           type = UNSPEC_INDNTPOFF;
   12351                 :             :         }
   12352                 :             : 
   12353                 :        9440 :       off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
   12354                 :        9440 :       off = gen_rtx_CONST (tp_mode, off);
   12355                 :        9440 :       if (pic)
   12356                 :         730 :         off = gen_rtx_PLUS (tp_mode, pic, off);
   12357                 :        9440 :       off = gen_const_mem (tp_mode, off);
   12358                 :        9440 :       set_mem_alias_set (off, GOT_ALIAS_SET);
   12359                 :             : 
   12360                 :        9440 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12361                 :             :         {
   12362                 :        9440 :           base = get_thread_pointer (tp_mode,
   12363                 :        9440 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12364                 :        9440 :           off = force_reg (tp_mode, off);
   12365                 :        9440 :           dest = gen_rtx_PLUS (tp_mode, base, off);
   12366                 :        9440 :           if (tp_mode != Pmode)
   12367                 :           4 :             dest = convert_to_mode (Pmode, dest, 1);
   12368                 :             :         }
   12369                 :             :       else
   12370                 :             :         {
   12371                 :           0 :           base = get_thread_pointer (Pmode, true);
   12372                 :           0 :           dest = gen_reg_rtx (Pmode);
   12373                 :           0 :           emit_insn (gen_sub3_insn (dest, base, off));
   12374                 :             :         }
   12375                 :             :       break;
   12376                 :             : 
   12377                 :       12736 :     case TLS_MODEL_LOCAL_EXEC:
   12378                 :       25472 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   12379                 :             :                             (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12380                 :             :                             ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
   12381                 :       12736 :       off = gen_rtx_CONST (Pmode, off);
   12382                 :             : 
   12383                 :       12736 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12384                 :             :         {
   12385                 :       12736 :           base = get_thread_pointer (Pmode,
   12386                 :       12736 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12387                 :       12736 :           return gen_rtx_PLUS (Pmode, base, off);
   12388                 :             :         }
   12389                 :             :       else
   12390                 :             :         {
   12391                 :           0 :           base = get_thread_pointer (Pmode, true);
   12392                 :           0 :           dest = gen_reg_rtx (Pmode);
   12393                 :           0 :           emit_insn (gen_sub3_insn (dest, base, off));
   12394                 :             :         }
   12395                 :           0 :       break;
   12396                 :             : 
   12397                 :           0 :     default:
   12398                 :           0 :       gcc_unreachable ();
   12399                 :             :     }
   12400                 :             : 
   12401                 :             :   return dest;
   12402                 :             : }
   12403                 :             : 
   12404                 :             : /* Return true if the TLS address requires insn using integer registers.
   12405                 :             :    It's used to prevent KMOV/VMOV in TLS code sequences which require integer
   12406                 :             :    MOV instructions, refer to PR103275.  */
   12407                 :             : bool
   12408                 :    15205017 : ix86_gpr_tls_address_pattern_p (rtx mem)
   12409                 :             : {
   12410                 :    15205017 :   gcc_assert (MEM_P (mem));
   12411                 :             : 
   12412                 :    15205017 :   rtx addr = XEXP (mem, 0);
   12413                 :    15205017 :   subrtx_var_iterator::array_type array;
   12414                 :    52975496 :   FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
   12415                 :             :     {
   12416                 :    37777190 :       rtx op = *iter;
   12417                 :    37777190 :       if (GET_CODE (op) == UNSPEC)
   12418                 :      202970 :         switch (XINT (op, 1))
   12419                 :             :           {
   12420                 :             :           case UNSPEC_GOTNTPOFF:
   12421                 :        6711 :             return true;
   12422                 :           0 :           case UNSPEC_TPOFF:
   12423                 :           0 :             if (!TARGET_64BIT)
   12424                 :             :               return true;
   12425                 :             :             break;
   12426                 :             :           default:
   12427                 :             :             break;
   12428                 :             :           }
   12429                 :             :     }
   12430                 :             : 
   12431                 :    15198306 :   return false;
   12432                 :    15205017 : }
   12433                 :             : 
   12434                 :             : /* Return true if OP refers to a TLS address.  */
   12435                 :             : bool
   12436                 :   221833867 : ix86_tls_address_pattern_p (rtx op)
   12437                 :             : {
   12438                 :   221833867 :   subrtx_var_iterator::array_type array;
   12439                 :  1316836342 :   FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
   12440                 :             :     {
   12441                 :  1095018493 :       rtx op = *iter;
   12442                 :  1095018493 :       if (MEM_P (op))
   12443                 :             :         {
   12444                 :    99410953 :           rtx *x = &XEXP (op, 0);
   12445                 :   156128479 :           while (GET_CODE (*x) == PLUS)
   12446                 :             :             {
   12447                 :             :               int i;
   12448                 :   170168619 :               for (i = 0; i < 2; i++)
   12449                 :             :                 {
   12450                 :   113451093 :                   rtx u = XEXP (*x, i);
   12451                 :   113451093 :                   if (GET_CODE (u) == ZERO_EXTEND)
   12452                 :      100424 :                     u = XEXP (u, 0);
   12453                 :   113451093 :                   if (GET_CODE (u) == UNSPEC
   12454                 :       16040 :                       && XINT (u, 1) == UNSPEC_TP)
   12455                 :       16018 :                     return true;
   12456                 :             :                 }
   12457                 :    56717526 :               x = &XEXP (*x, 0);
   12458                 :             :             }
   12459                 :             : 
   12460                 :    99394935 :           iter.skip_subrtxes ();
   12461                 :             :         }
   12462                 :             :     }
   12463                 :             : 
   12464                 :   221817849 :   return false;
   12465                 :   221833867 : }
   12466                 :             : 
   12467                 :             : /* Rewrite *LOC so that it refers to a default TLS address space.  */
   12468                 :             : static void
   12469                 :       16018 : ix86_rewrite_tls_address_1 (rtx *loc)
   12470                 :             : {
   12471                 :       16018 :   subrtx_ptr_iterator::array_type array;
   12472                 :       48225 :   FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
   12473                 :             :     {
   12474                 :       48225 :       rtx *loc = *iter;
   12475                 :       48225 :       if (MEM_P (*loc))
   12476                 :             :         {
   12477                 :       16205 :           rtx addr = XEXP (*loc, 0);
   12478                 :       16205 :           rtx *x = &addr;
   12479                 :       20869 :           while (GET_CODE (*x) == PLUS)
   12480                 :             :             {
   12481                 :             :               int i;
   12482                 :       30033 :               for (i = 0; i < 2; i++)
   12483                 :             :                 {
   12484                 :       25369 :                   rtx u = XEXP (*x, i);
   12485                 :       25369 :                   if (GET_CODE (u) == ZERO_EXTEND)
   12486                 :          19 :                     u = XEXP (u, 0);
   12487                 :       25369 :                   if (GET_CODE (u) == UNSPEC
   12488                 :       16018 :                       && XINT (u, 1) == UNSPEC_TP)
   12489                 :             :                     {
   12490                 :             :                       /* NB: Since address override only applies to the
   12491                 :             :                          (reg32) part in fs:(reg32), return if address
   12492                 :             :                          override is used.  */
   12493                 :       16018 :                       if (Pmode != word_mode
   12494                 :       16018 :                           && REG_P (XEXP (*x, 1 - i)))
   12495                 :       16018 :                         return;
   12496                 :             : 
   12497                 :       16018 :                       addr_space_t as = DEFAULT_TLS_SEG_REG;
   12498                 :             : 
   12499                 :       16018 :                       *x = XEXP (*x, 1 - i);
   12500                 :             : 
   12501                 :       16018 :                       *loc = replace_equiv_address_nv (*loc, addr, true);
   12502                 :       16018 :                       set_mem_addr_space (*loc, as);
   12503                 :       16018 :                       return;
   12504                 :             :                     }
   12505                 :             :                 }
   12506                 :        4664 :               x = &XEXP (*x, 0);
   12507                 :             :             }
   12508                 :             : 
   12509                 :         187 :           iter.skip_subrtxes ();
   12510                 :             :         }
   12511                 :             :     }
   12512                 :       16018 : }
   12513                 :             : 
   12514                 :             : /* Rewrite instruction pattern involvning TLS address
   12515                 :             :    so that it refers to a default TLS address space.  */
   12516                 :             : rtx
   12517                 :       16018 : ix86_rewrite_tls_address (rtx pattern)
   12518                 :             : {
   12519                 :       16018 :   pattern = copy_insn (pattern);
   12520                 :       16018 :   ix86_rewrite_tls_address_1 (&pattern);
   12521                 :       16018 :   return pattern;
   12522                 :             : }
   12523                 :             : 
   12524                 :             : /* Try machine-dependent ways of modifying an illegitimate address
   12525                 :             :    to be legitimate.  If we find one, return the new, valid address.
   12526                 :             :    This macro is used in only one place: `memory_address' in explow.cc.
   12527                 :             : 
   12528                 :             :    OLDX is the address as it was before break_out_memory_refs was called.
   12529                 :             :    In some cases it is useful to look at this to decide what needs to be done.
   12530                 :             : 
   12531                 :             :    It is always safe for this macro to do nothing.  It exists to recognize
   12532                 :             :    opportunities to optimize the output.
   12533                 :             : 
   12534                 :             :    For the 80386, we handle X+REG by loading X into a register R and
   12535                 :             :    using R+REG.  R will go in a general reg and indexing will be used.
   12536                 :             :    However, if REG is a broken-out memory address or multiplication,
   12537                 :             :    nothing needs to be done because REG can certainly go in a general reg.
   12538                 :             : 
   12539                 :             :    When -fpic is used, special handling is needed for symbolic references.
   12540                 :             :    See comments by legitimize_pic_address in i386.cc for details.  */
   12541                 :             : 
   12542                 :             : static rtx
   12543                 :      594064 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
   12544                 :             : {
   12545                 :      594064 :   bool changed = false;
   12546                 :      594064 :   unsigned log;
   12547                 :             : 
   12548                 :      594064 :   log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0;
   12549                 :      149887 :   if (log)
   12550                 :       19138 :     return legitimize_tls_address (x, (enum tls_model) log, false);
   12551                 :      574926 :   if (GET_CODE (x) == CONST
   12552                 :         493 :       && GET_CODE (XEXP (x, 0)) == PLUS
   12553                 :         493 :       && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
   12554                 :      575419 :       && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
   12555                 :             :     {
   12556                 :           4 :       rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
   12557                 :             :                                       (enum tls_model) log, false);
   12558                 :           4 :       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
   12559                 :             :     }
   12560                 :             : 
   12561                 :      574922 :   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   12562                 :             :     {
   12563                 :             : #if TARGET_PECOFF
   12564                 :             :       rtx tmp = legitimize_pe_coff_symbol (x, true);
   12565                 :             :       if (tmp)
   12566                 :             :         return tmp;
   12567                 :             : #endif
   12568                 :             :     }
   12569                 :             : 
   12570                 :      574922 :   if (flag_pic && SYMBOLIC_CONST (x))
   12571                 :      131111 :     return legitimize_pic_address (x, 0);
   12572                 :             : 
   12573                 :             : #if TARGET_MACHO
   12574                 :             :   if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
   12575                 :             :     return machopic_indirect_data_reference (x, 0);
   12576                 :             : #endif
   12577                 :             : 
   12578                 :             :   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   12579                 :      443811 :   if (GET_CODE (x) == ASHIFT
   12580                 :           0 :       && CONST_INT_P (XEXP (x, 1))
   12581                 :           0 :       && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
   12582                 :             :     {
   12583                 :           0 :       changed = true;
   12584                 :           0 :       log = INTVAL (XEXP (x, 1));
   12585                 :           0 :       x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
   12586                 :             :                         GEN_INT (1 << log));
   12587                 :             :     }
   12588                 :             : 
   12589                 :      443811 :   if (GET_CODE (x) == PLUS)
   12590                 :             :     {
   12591                 :             :       /* Canonicalize shifts by 0, 1, 2, 3 into multiply.  */
   12592                 :             : 
   12593                 :      120096 :       if (GET_CODE (XEXP (x, 0)) == ASHIFT
   12594                 :         544 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   12595                 :         544 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
   12596                 :             :         {
   12597                 :         544 :           changed = true;
   12598                 :         544 :           log = INTVAL (XEXP (XEXP (x, 0), 1));
   12599                 :         544 :           XEXP (x, 0) = gen_rtx_MULT (Pmode,
   12600                 :             :                                       force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
   12601                 :             :                                       GEN_INT (1 << log));
   12602                 :             :         }
   12603                 :             : 
   12604                 :      120096 :       if (GET_CODE (XEXP (x, 1)) == ASHIFT
   12605                 :           0 :           && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   12606                 :           0 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
   12607                 :             :         {
   12608                 :           0 :           changed = true;
   12609                 :           0 :           log = INTVAL (XEXP (XEXP (x, 1), 1));
   12610                 :           0 :           XEXP (x, 1) = gen_rtx_MULT (Pmode,
   12611                 :             :                                       force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
   12612                 :             :                                       GEN_INT (1 << log));
   12613                 :             :         }
   12614                 :             : 
   12615                 :             :       /* Put multiply first if it isn't already.  */
   12616                 :      120096 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   12617                 :             :         {
   12618                 :           0 :           std::swap (XEXP (x, 0), XEXP (x, 1));
   12619                 :           0 :           changed = true;
   12620                 :             :         }
   12621                 :             : 
   12622                 :             :       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
   12623                 :             :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
   12624                 :             :          created by virtual register instantiation, register elimination, and
   12625                 :             :          similar optimizations.  */
   12626                 :      120096 :       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
   12627                 :             :         {
   12628                 :        9042 :           changed = true;
   12629                 :        9042 :           x = gen_rtx_PLUS (Pmode,
   12630                 :             :                             gen_rtx_PLUS (Pmode, XEXP (x, 0),
   12631                 :             :                                           XEXP (XEXP (x, 1), 0)),
   12632                 :             :                             XEXP (XEXP (x, 1), 1));
   12633                 :             :         }
   12634                 :             : 
   12635                 :             :       /* Canonicalize
   12636                 :             :          (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
   12637                 :             :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
   12638                 :      111054 :       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
   12639                 :       74690 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   12640                 :       47901 :                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
   12641                 :           0 :                && CONSTANT_P (XEXP (x, 1)))
   12642                 :             :         {
   12643                 :           0 :           rtx constant;
   12644                 :           0 :           rtx other = NULL_RTX;
   12645                 :             : 
   12646                 :           0 :           if (CONST_INT_P (XEXP (x, 1)))
   12647                 :             :             {
   12648                 :           0 :               constant = XEXP (x, 1);
   12649                 :           0 :               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
   12650                 :             :             }
   12651                 :           0 :           else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
   12652                 :             :             {
   12653                 :             :               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
   12654                 :             :               other = XEXP (x, 1);
   12655                 :             :             }
   12656                 :             :           else
   12657                 :             :             constant = 0;
   12658                 :             : 
   12659                 :           0 :           if (constant)
   12660                 :             :             {
   12661                 :           0 :               changed = true;
   12662                 :           0 :               x = gen_rtx_PLUS (Pmode,
   12663                 :             :                                 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
   12664                 :             :                                               XEXP (XEXP (XEXP (x, 0), 1), 0)),
   12665                 :             :                                 plus_constant (Pmode, other,
   12666                 :             :                                                INTVAL (constant)));
   12667                 :             :             }
   12668                 :             :         }
   12669                 :             : 
   12670                 :      120096 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   12671                 :        9077 :         return x;
   12672                 :             : 
   12673                 :      111019 :       if (GET_CODE (XEXP (x, 0)) == MULT)
   12674                 :             :         {
   12675                 :       18279 :           changed = true;
   12676                 :       18279 :           XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
   12677                 :             :         }
   12678                 :             : 
   12679                 :      111019 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   12680                 :             :         {
   12681                 :           0 :           changed = true;
   12682                 :           0 :           XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
   12683                 :             :         }
   12684                 :             : 
   12685                 :      111019 :       if (changed
   12686                 :       18288 :           && REG_P (XEXP (x, 1))
   12687                 :       14806 :           && REG_P (XEXP (x, 0)))
   12688                 :             :         return x;
   12689                 :             : 
   12690                 :       96214 :       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
   12691                 :             :         {
   12692                 :        1791 :           changed = true;
   12693                 :        1791 :           x = legitimize_pic_address (x, 0);
   12694                 :             :         }
   12695                 :             : 
   12696                 :       96214 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   12697                 :        3751 :         return x;
   12698                 :             : 
   12699                 :       92463 :       if (REG_P (XEXP (x, 0)))
   12700                 :             :         {
   12701                 :       17314 :           rtx temp = gen_reg_rtx (Pmode);
   12702                 :       17314 :           rtx val  = force_operand (XEXP (x, 1), temp);
   12703                 :       17314 :           if (val != temp)
   12704                 :             :             {
   12705                 :        9626 :               val = convert_to_mode (Pmode, val, 1);
   12706                 :        9626 :               emit_move_insn (temp, val);
   12707                 :             :             }
   12708                 :             : 
   12709                 :       17314 :           XEXP (x, 1) = temp;
   12710                 :       17314 :           return x;
   12711                 :             :         }
   12712                 :             : 
   12713                 :       75149 :       else if (REG_P (XEXP (x, 1)))
   12714                 :             :         {
   12715                 :        2716 :           rtx temp = gen_reg_rtx (Pmode);
   12716                 :        2716 :           rtx val  = force_operand (XEXP (x, 0), temp);
   12717                 :        2716 :           if (val != temp)
   12718                 :             :             {
   12719                 :           0 :               val = convert_to_mode (Pmode, val, 1);
   12720                 :           0 :               emit_move_insn (temp, val);
   12721                 :             :             }
   12722                 :             : 
   12723                 :        2716 :           XEXP (x, 0) = temp;
   12724                 :        2716 :           return x;
   12725                 :             :         }
   12726                 :             :     }
   12727                 :             : 
   12728                 :             :   return x;
   12729                 :             : }
   12730                 :             : 
   12731                 :             : /* Print an integer constant expression in assembler syntax.  Addition
   12732                 :             :    and subtraction are the only arithmetic that may appear in these
   12733                 :             :    expressions.  FILE is the stdio stream to write to, X is the rtx, and
   12734                 :             :    CODE is the operand print code from the output string.  */
   12735                 :             : 
   12736                 :             : static void
   12737                 :     3482465 : output_pic_addr_const (FILE *file, rtx x, int code)
   12738                 :             : {
   12739                 :     3708770 :   char buf[256];
   12740                 :             : 
   12741                 :     3708770 :   switch (GET_CODE (x))
   12742                 :             :     {
   12743                 :           0 :     case PC:
   12744                 :           0 :       gcc_assert (flag_pic);
   12745                 :           0 :       putc ('.', file);
   12746                 :           0 :       break;
   12747                 :             : 
   12748                 :      846080 :     case SYMBOL_REF:
   12749                 :      846080 :       if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
   12750                 :      846080 :         output_addr_const (file, x);
   12751                 :             :       else
   12752                 :             :         {
   12753                 :             :           const char *name = XSTR (x, 0);
   12754                 :             : 
   12755                 :             :           /* Mark the decl as referenced so that cgraph will
   12756                 :             :              output the function.  */
   12757                 :             :           if (SYMBOL_REF_DECL (x))
   12758                 :             :             mark_decl_referenced (SYMBOL_REF_DECL (x));
   12759                 :             : 
   12760                 :             : #if TARGET_MACHO
   12761                 :             :           if (MACHOPIC_INDIRECT
   12762                 :             :               && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
   12763                 :             :             name = machopic_indirection_name (x, /*stub_p=*/true);
   12764                 :             : #endif
   12765                 :             :           assemble_name (file, name);
   12766                 :             :         }
   12767                 :      846080 :       if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
   12768                 :      846080 :           && code == 'P' && ix86_call_use_plt_p (x))
   12769                 :      384189 :         fputs ("@PLT", file);
   12770                 :             :       break;
   12771                 :             : 
   12772                 :        2545 :     case LABEL_REF:
   12773                 :        2545 :       x = XEXP (x, 0);
   12774                 :             :       /* FALLTHRU */
   12775                 :        2545 :     case CODE_LABEL:
   12776                 :        2545 :       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   12777                 :        2545 :       assemble_name (asm_out_file, buf);
   12778                 :        2545 :       break;
   12779                 :             : 
   12780                 :     2435071 :     CASE_CONST_SCALAR_INT:
   12781                 :     2435071 :       output_addr_const (file, x);
   12782                 :     2435071 :       break;
   12783                 :             : 
   12784                 :      207935 :     case CONST:
   12785                 :             :       /* This used to output parentheses around the expression,
   12786                 :             :          but that does not work on the 386 (either ATT or BSD assembler).  */
   12787                 :      207935 :       output_pic_addr_const (file, XEXP (x, 0), code);
   12788                 :      207935 :       break;
   12789                 :             : 
   12790                 :           0 :     case CONST_DOUBLE:
   12791                 :             :       /* We can't handle floating point constants;
   12792                 :             :          TARGET_PRINT_OPERAND must handle them.  */
   12793                 :           0 :       output_operand_lossage ("floating constant misused");
   12794                 :           0 :       break;
   12795                 :             : 
   12796                 :       18370 :     case PLUS:
   12797                 :             :       /* Some assemblers need integer constants to appear first.  */
   12798                 :       18370 :       if (CONST_INT_P (XEXP (x, 0)))
   12799                 :             :         {
   12800                 :           0 :           output_pic_addr_const (file, XEXP (x, 0), code);
   12801                 :           0 :           putc ('+', file);
   12802                 :           0 :           output_pic_addr_const (file, XEXP (x, 1), code);
   12803                 :             :         }
   12804                 :             :       else
   12805                 :             :         {
   12806                 :       18370 :           gcc_assert (CONST_INT_P (XEXP (x, 1)));
   12807                 :       18370 :           output_pic_addr_const (file, XEXP (x, 1), code);
   12808                 :       18370 :           putc ('+', file);
   12809                 :       18370 :           output_pic_addr_const (file, XEXP (x, 0), code);
   12810                 :             :         }
   12811                 :             :       break;
   12812                 :             : 
   12813                 :           0 :     case MINUS:
   12814                 :           0 :       if (!TARGET_MACHO)
   12815                 :           0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
   12816                 :           0 :       output_pic_addr_const (file, XEXP (x, 0), code);
   12817                 :           0 :       putc ('-', file);
   12818                 :           0 :       output_pic_addr_const (file, XEXP (x, 1), code);
   12819                 :           0 :       if (!TARGET_MACHO)
   12820                 :           0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
   12821                 :           0 :       break;
   12822                 :             : 
   12823                 :      198769 :     case UNSPEC:
   12824                 :      198769 :       gcc_assert (XVECLEN (x, 0) == 1);
   12825                 :      198769 :       output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
   12826                 :      198769 :       switch (XINT (x, 1))
   12827                 :             :         {
   12828                 :       43087 :         case UNSPEC_GOT:
   12829                 :       43087 :           fputs ("@GOT", file);
   12830                 :       43087 :           break;
   12831                 :       77751 :         case UNSPEC_GOTOFF:
   12832                 :       77751 :           fputs ("@GOTOFF", file);
   12833                 :       77751 :           break;
   12834                 :          31 :         case UNSPEC_PLTOFF:
   12835                 :          31 :           fputs ("@PLTOFF", file);
   12836                 :          31 :           break;
   12837                 :           0 :         case UNSPEC_PCREL:
   12838                 :           0 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12839                 :             :                  "(%rip)" : "[rip]", file);
   12840                 :           0 :           break;
   12841                 :       73950 :         case UNSPEC_GOTPCREL:
   12842                 :       73950 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12843                 :             :                  "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
   12844                 :       73950 :           break;
   12845                 :           0 :         case UNSPEC_GOTTPOFF:
   12846                 :             :           /* FIXME: This might be @TPOFF in Sun ld too.  */
   12847                 :           0 :           fputs ("@gottpoff", file);
   12848                 :           0 :           break;
   12849                 :           0 :         case UNSPEC_TPOFF:
   12850                 :           0 :           fputs ("@tpoff", file);
   12851                 :           0 :           break;
   12852                 :        1353 :         case UNSPEC_NTPOFF:
   12853                 :        1353 :           if (TARGET_64BIT)
   12854                 :        1353 :             fputs ("@tpoff", file);
   12855                 :             :           else
   12856                 :           0 :             fputs ("@ntpoff", file);
   12857                 :             :           break;
   12858                 :         330 :         case UNSPEC_DTPOFF:
   12859                 :         330 :           fputs ("@dtpoff", file);
   12860                 :         330 :           break;
   12861                 :        2267 :         case UNSPEC_GOTNTPOFF:
   12862                 :        2267 :           if (TARGET_64BIT)
   12863                 :        2019 :             fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12864                 :             :                    "@gottpoff(%rip)": "@gottpoff[rip]", file);
   12865                 :             :           else
   12866                 :         248 :             fputs ("@gotntpoff", file);
   12867                 :             :           break;
   12868                 :           0 :         case UNSPEC_INDNTPOFF:
   12869                 :           0 :           fputs ("@indntpoff", file);
   12870                 :           0 :           break;
   12871                 :             : #if TARGET_MACHO
   12872                 :             :         case UNSPEC_MACHOPIC_OFFSET:
   12873                 :             :           putc ('-', file);
   12874                 :             :           machopic_output_function_base_name (file);
   12875                 :             :           break;
   12876                 :             : #endif
   12877                 :           0 :         default:
   12878                 :           0 :           output_operand_lossage ("invalid UNSPEC as operand");
   12879                 :           0 :           break;
   12880                 :             :         }
   12881                 :             :        break;
   12882                 :             : 
   12883                 :           0 :     default:
   12884                 :           0 :       output_operand_lossage ("invalid expression as operand");
   12885                 :             :     }
   12886                 :     3482465 : }
   12887                 :             : 
   12888                 :             : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
   12889                 :             :    We need to emit DTP-relative relocations.  */
   12890                 :             : 
   12891                 :             : static void ATTRIBUTE_UNUSED
   12892                 :         694 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
   12893                 :             : {
   12894                 :         694 :   fputs (ASM_LONG, file);
   12895                 :         694 :   output_addr_const (file, x);
   12896                 :         694 :   fputs ("@dtpoff", file);
   12897                 :         694 :   switch (size)
   12898                 :             :     {
   12899                 :             :     case 4:
   12900                 :             :       break;
   12901                 :         534 :     case 8:
   12902                 :         534 :       fputs (", 0", file);
   12903                 :         534 :       break;
   12904                 :           0 :     default:
   12905                 :           0 :       gcc_unreachable ();
   12906                 :             :    }
   12907                 :         694 : }
   12908                 :             : 
   12909                 :             : /* Return true if X is a representation of the PIC register.  This copes
   12910                 :             :    with calls from ix86_find_base_term, where the register might have
   12911                 :             :    been replaced by a cselib value.  */
   12912                 :             : 
   12913                 :             : static bool
   12914                 :    25571380 : ix86_pic_register_p (rtx x)
   12915                 :             : {
   12916                 :    25571380 :   if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
   12917                 :      767851 :     return (pic_offset_table_rtx
   12918                 :      767851 :             && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
   12919                 :    24803529 :   else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
   12920                 :             :     return true;
   12921                 :    24802185 :   else if (!REG_P (x))
   12922                 :             :     return false;
   12923                 :    24178489 :   else if (pic_offset_table_rtx)
   12924                 :             :     {
   12925                 :    24165881 :       if (REGNO (x) == REGNO (pic_offset_table_rtx))
   12926                 :             :         return true;
   12927                 :      384488 :       if (HARD_REGISTER_P (x)
   12928                 :      363551 :           && !HARD_REGISTER_P (pic_offset_table_rtx)
   12929                 :      748039 :           && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
   12930                 :             :         return true;
   12931                 :             :       return false;
   12932                 :             :     }
   12933                 :             :   else
   12934                 :       12608 :     return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
   12935                 :             : }
   12936                 :             : 
   12937                 :             : /* Helper function for ix86_delegitimize_address.
   12938                 :             :    Attempt to delegitimize TLS local-exec accesses.  */
   12939                 :             : 
   12940                 :             : static rtx
   12941                 :  3444256173 : ix86_delegitimize_tls_address (rtx orig_x)
   12942                 :             : {
   12943                 :  3444256173 :   rtx x = orig_x, unspec;
   12944                 :  3444256173 :   struct ix86_address addr;
   12945                 :             : 
   12946                 :  3444256173 :   if (!TARGET_TLS_DIRECT_SEG_REFS)
   12947                 :             :     return orig_x;
   12948                 :  3444256173 :   if (MEM_P (x))
   12949                 :    41198354 :     x = XEXP (x, 0);
   12950                 :  3444256173 :   if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
   12951                 :             :     return orig_x;
   12952                 :  1654517084 :   if (ix86_decompose_address (x, &addr) == 0
   12953                 :  1920556180 :       || addr.seg != DEFAULT_TLS_SEG_REG
   12954                 :      242864 :       || addr.disp == NULL_RTX
   12955                 :  1654714278 :       || GET_CODE (addr.disp) != CONST)
   12956                 :             :     return orig_x;
   12957                 :      107291 :   unspec = XEXP (addr.disp, 0);
   12958                 :      107291 :   if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
   12959                 :       65476 :     unspec = XEXP (unspec, 0);
   12960                 :      107291 :   if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
   12961                 :             :     return orig_x;
   12962                 :      107283 :   x = XVECEXP (unspec, 0, 0);
   12963                 :      107283 :   gcc_assert (GET_CODE (x) == SYMBOL_REF);
   12964                 :      107283 :   if (unspec != XEXP (addr.disp, 0))
   12965                 :       65476 :     x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
   12966                 :      107283 :   if (addr.index)
   12967                 :             :     {
   12968                 :         187 :       rtx idx = addr.index;
   12969                 :         187 :       if (addr.scale != 1)
   12970                 :         187 :         idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
   12971                 :         187 :       x = gen_rtx_PLUS (Pmode, idx, x);
   12972                 :             :     }
   12973                 :      107283 :   if (addr.base)
   12974                 :           2 :     x = gen_rtx_PLUS (Pmode, addr.base, x);
   12975                 :      107283 :   if (MEM_P (orig_x))
   12976                 :         132 :     x = replace_equiv_address_nv (orig_x, x);
   12977                 :             :   return x;
   12978                 :             : }
   12979                 :             : 
   12980                 :             : /* In the name of slightly smaller debug output, and to cater to
   12981                 :             :    general assembler lossage, recognize PIC+GOTOFF and turn it back
   12982                 :             :    into a direct symbol reference.
   12983                 :             : 
   12984                 :             :    On Darwin, this is necessary to avoid a crash, because Darwin
   12985                 :             :    has a different PIC label for each routine but the DWARF debugging
   12986                 :             :    information is not associated with any particular routine, so it's
   12987                 :             :    necessary to remove references to the PIC label from RTL stored by
   12988                 :             :    the DWARF output code.
   12989                 :             : 
   12990                 :             :    This helper is used in the normal ix86_delegitimize_address
   12991                 :             :    entrypoint (e.g. used in the target delegitimization hook) and
   12992                 :             :    in ix86_find_base_term.  As compile time memory optimization, we
   12993                 :             :    avoid allocating rtxes that will not change anything on the outcome
   12994                 :             :    of the callers (find_base_value and find_base_term).  */
   12995                 :             : 
   12996                 :             : static inline rtx
   12997                 :  3467780775 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
   12998                 :             : {
   12999                 :  3467780775 :   rtx orig_x = delegitimize_mem_from_attrs (x);
   13000                 :             :   /* addend is NULL or some rtx if x is something+GOTOFF where
   13001                 :             :      something doesn't include the PIC register.  */
   13002                 :  3467780775 :   rtx addend = NULL_RTX;
   13003                 :             :   /* reg_addend is NULL or a multiple of some register.  */
   13004                 :  3467780775 :   rtx reg_addend = NULL_RTX;
   13005                 :             :   /* const_addend is NULL or a const_int.  */
   13006                 :  3467780775 :   rtx const_addend = NULL_RTX;
   13007                 :             :   /* This is the result, or NULL.  */
   13008                 :  3467780775 :   rtx result = NULL_RTX;
   13009                 :             : 
   13010                 :  3467780775 :   x = orig_x;
   13011                 :             : 
   13012                 :  3467780775 :   if (MEM_P (x))
   13013                 :    59116523 :     x = XEXP (x, 0);
   13014                 :             : 
   13015                 :  3467780775 :   if (TARGET_64BIT)
   13016                 :             :     {
   13017                 :   225356789 :       if (GET_CODE (x) == CONST
   13018                 :     7934309 :           && GET_CODE (XEXP (x, 0)) == PLUS
   13019                 :     6191252 :           && GET_MODE (XEXP (x, 0)) == Pmode
   13020                 :     6191252 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13021                 :     6191252 :           && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
   13022                 :   225361310 :           && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
   13023                 :             :         {
   13024                 :             :           /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
   13025                 :             :              base.  A CONST can't be arg_pointer_rtx based.  */
   13026                 :           0 :           if (base_term_p && MEM_P (orig_x))
   13027                 :             :             return orig_x;
   13028                 :           0 :           rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
   13029                 :           0 :           x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
   13030                 :           0 :           if (MEM_P (orig_x))
   13031                 :           0 :             x = replace_equiv_address_nv (orig_x, x);
   13032                 :           0 :           return x;
   13033                 :             :         }
   13034                 :             : 
   13035                 :   225356789 :       if (GET_CODE (x) == CONST
   13036                 :     7934309 :           && GET_CODE (XEXP (x, 0)) == UNSPEC
   13037                 :     1743057 :           && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
   13038                 :      561560 :               || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
   13039                 :     1181497 :           && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
   13040                 :             :         {
   13041                 :      257024 :           x = XVECEXP (XEXP (x, 0), 0, 0);
   13042                 :      257024 :           if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
   13043                 :             :             {
   13044                 :           9 :               x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
   13045                 :           9 :               if (x == NULL_RTX)
   13046                 :             :                 return orig_x;
   13047                 :             :             }
   13048                 :      257024 :           return x;
   13049                 :             :         }
   13050                 :             : 
   13051                 :   225099765 :       if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
   13052                 :   225098635 :         return ix86_delegitimize_tls_address (orig_x);
   13053                 :             : 
   13054                 :             :       /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
   13055                 :             :          and -mcmodel=medium -fpic.  */
   13056                 :             :     }
   13057                 :             : 
   13058                 :  3242425116 :   if (GET_CODE (x) != PLUS
   13059                 :  1538887588 :       || GET_CODE (XEXP (x, 1)) != CONST)
   13060                 :  3217418373 :     return ix86_delegitimize_tls_address (orig_x);
   13061                 :             : 
   13062                 :    25006743 :   if (ix86_pic_register_p (XEXP (x, 0)))
   13063                 :             :     /* %ebx + GOT/GOTOFF */
   13064                 :             :     ;
   13065                 :     1307663 :   else if (GET_CODE (XEXP (x, 0)) == PLUS)
   13066                 :             :     {
   13067                 :             :       /* %ebx + %reg * scale + GOT/GOTOFF */
   13068                 :      489589 :       reg_addend = XEXP (x, 0);
   13069                 :      489589 :       if (ix86_pic_register_p (XEXP (reg_addend, 0)))
   13070                 :      414541 :         reg_addend = XEXP (reg_addend, 1);
   13071                 :       75048 :       else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
   13072                 :       43872 :         reg_addend = XEXP (reg_addend, 0);
   13073                 :             :       else
   13074                 :             :         {
   13075                 :       31176 :           reg_addend = NULL_RTX;
   13076                 :       31176 :           addend = XEXP (x, 0);
   13077                 :             :         }
   13078                 :             :     }
   13079                 :             :   else
   13080                 :             :     addend = XEXP (x, 0);
   13081                 :             : 
   13082                 :    25006743 :   x = XEXP (XEXP (x, 1), 0);
   13083                 :    25006743 :   if (GET_CODE (x) == PLUS
   13084                 :     1468516 :       && CONST_INT_P (XEXP (x, 1)))
   13085                 :             :     {
   13086                 :     1468516 :       const_addend = XEXP (x, 1);
   13087                 :     1468516 :       x = XEXP (x, 0);
   13088                 :             :     }
   13089                 :             : 
   13090                 :    25006743 :   if (GET_CODE (x) == UNSPEC
   13091                 :    24319055 :       && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
   13092                 :     6657910 :           || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
   13093                 :     1051477 :           || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
   13094                 :           0 :               && !MEM_P (orig_x) && !addend)))
   13095                 :    23267578 :     result = XVECEXP (x, 0, 0);
   13096                 :             : 
   13097                 :    23267578 :   if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
   13098                 :             :       && !MEM_P (orig_x))
   13099                 :             :     result = XVECEXP (x, 0, 0);
   13100                 :             : 
   13101                 :    23267578 :   if (! result)
   13102                 :     1739165 :     return ix86_delegitimize_tls_address (orig_x);
   13103                 :             : 
   13104                 :             :   /* For (PLUS something CONST_INT) both find_base_{value,term} just
   13105                 :             :      recurse on the first operand.  */
   13106                 :    23267578 :   if (const_addend && !base_term_p)
   13107                 :      113764 :     result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
   13108                 :    23267578 :   if (reg_addend)
   13109                 :      447083 :     result = gen_rtx_PLUS (Pmode, reg_addend, result);
   13110                 :    23267578 :   if (addend)
   13111                 :             :     {
   13112                 :             :       /* If the rest of original X doesn't involve the PIC register, add
   13113                 :             :          addend and subtract pic_offset_table_rtx.  This can happen e.g.
   13114                 :             :          for code like:
   13115                 :             :          leal (%ebx, %ecx, 4), %ecx
   13116                 :             :          ...
   13117                 :             :          movl foo@GOTOFF(%ecx), %edx
   13118                 :             :          in which case we return (%ecx - %ebx) + foo
   13119                 :             :          or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
   13120                 :             :          and reload has completed.  Don't do the latter for debug,
   13121                 :             :          as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly.  */
   13122                 :      134192 :       if (pic_offset_table_rtx
   13123                 :      134192 :           && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
   13124                 :         828 :         result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
   13125                 :             :                                                      pic_offset_table_rtx),
   13126                 :             :                                result);
   13127                 :      133364 :       else if (base_term_p
   13128                 :      127733 :                && pic_offset_table_rtx
   13129                 :             :                && !TARGET_MACHO
   13130                 :             :                && !TARGET_VXWORKS_RTP)
   13131                 :             :         {
   13132                 :      127733 :           rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
   13133                 :      127733 :           tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
   13134                 :      127733 :           result = gen_rtx_PLUS (Pmode, tmp, result);
   13135                 :      127733 :         }
   13136                 :             :       else
   13137                 :             :         return orig_x;
   13138                 :             :     }
   13139                 :    23261947 :   if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
   13140                 :             :     {
   13141                 :           0 :       result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
   13142                 :           0 :       if (result == NULL_RTX)
   13143                 :             :         return orig_x;
   13144                 :             :     }
   13145                 :             :   return result;
   13146                 :             : }
   13147                 :             : 
   13148                 :             : /* The normal instantiation of the above template.  */
   13149                 :             : 
   13150                 :             : static rtx
   13151                 :   294309324 : ix86_delegitimize_address (rtx x)
   13152                 :             : {
   13153                 :   294309324 :   return ix86_delegitimize_address_1 (x, false);
   13154                 :             : }
   13155                 :             : 
   13156                 :             : /* If X is a machine specific address (i.e. a symbol or label being
   13157                 :             :    referenced as a displacement from the GOT implemented using an
   13158                 :             :    UNSPEC), then return the base term.  Otherwise return X.  */
   13159                 :             : 
   13160                 :             : rtx
   13161                 :  6342242443 : ix86_find_base_term (rtx x)
   13162                 :             : {
   13163                 :  6342242443 :   rtx term;
   13164                 :             : 
   13165                 :  6342242443 :   if (TARGET_64BIT)
   13166                 :             :     {
   13167                 :  3168770992 :       if (GET_CODE (x) != CONST)
   13168                 :             :         return x;
   13169                 :    30350838 :       term = XEXP (x, 0);
   13170                 :    30350838 :       if (GET_CODE (term) == PLUS
   13171                 :    30336371 :           && CONST_INT_P (XEXP (term, 1)))
   13172                 :    30336371 :         term = XEXP (term, 0);
   13173                 :    30350838 :       if (GET_CODE (term) != UNSPEC
   13174                 :       39052 :           || (XINT (term, 1) != UNSPEC_GOTPCREL
   13175                 :       39052 :               && XINT (term, 1) != UNSPEC_PCREL))
   13176                 :             :         return x;
   13177                 :             : 
   13178                 :           0 :       return XVECEXP (term, 0, 0);
   13179                 :             :     }
   13180                 :             : 
   13181                 :  3173471451 :   return ix86_delegitimize_address_1 (x, true);
   13182                 :             : }
   13183                 :             : 
   13184                 :             : /* Return true if X shouldn't be emitted into the debug info.
   13185                 :             :    Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
   13186                 :             :    symbol easily into the .debug_info section, so we need not to
   13187                 :             :    delegitimize, but instead assemble as @gotoff.
   13188                 :             :    Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
   13189                 :             :    assembles that as _GLOBAL_OFFSET_TABLE_-. expression.  */
   13190                 :             : 
   13191                 :             : static bool
   13192                 :     1545411 : ix86_const_not_ok_for_debug_p (rtx x)
   13193                 :             : {
   13194                 :     1545411 :   if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
   13195                 :             :     return true;
   13196                 :             : 
   13197                 :     1545395 :   if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
   13198                 :           0 :     return true;
   13199                 :             : 
   13200                 :             :   return false;
   13201                 :             : }
   13202                 :             : 
   13203                 :             : static void
   13204                 :     6695870 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
   13205                 :             :                     bool fp, FILE *file)
   13206                 :             : {
   13207                 :     6695870 :   const char *suffix;
   13208                 :             : 
   13209                 :     6695870 :   if (mode == CCFPmode)
   13210                 :             :     {
   13211                 :      556828 :       code = ix86_fp_compare_code_to_integer (code);
   13212                 :      556828 :       mode = CCmode;
   13213                 :             :     }
   13214                 :     6695870 :   if (reverse)
   13215                 :      189669 :     code = reverse_condition (code);
   13216                 :             : 
   13217                 :     6695870 :   switch (code)
   13218                 :             :     {
   13219                 :     2610780 :     case EQ:
   13220                 :     2610780 :       gcc_assert (mode != CCGZmode);
   13221                 :     2610780 :       switch (mode)
   13222                 :             :         {
   13223                 :             :         case E_CCAmode:
   13224                 :             :           suffix = "a";
   13225                 :             :           break;
   13226                 :             :         case E_CCCmode:
   13227                 :       25824 :           suffix = "c";
   13228                 :             :           break;
   13229                 :             :         case E_CCOmode:
   13230                 :     6695870 :           suffix = "o";
   13231                 :             :           break;
   13232                 :             :         case E_CCPmode:
   13233                 :      232040 :           suffix = "p";
   13234                 :             :           break;
   13235                 :             :         case E_CCSmode:
   13236                 :      113151 :           suffix = "s";
   13237                 :             :           break;
   13238                 :     2591047 :         default:
   13239                 :     2591047 :           suffix = "e";
   13240                 :     2591047 :           break;
   13241                 :             :         }
   13242                 :             :       break;
   13243                 :     2173960 :     case NE:
   13244                 :     2173960 :       gcc_assert (mode != CCGZmode);
   13245                 :     2173960 :       switch (mode)
   13246                 :             :         {
   13247                 :             :         case E_CCAmode:
   13248                 :             :           suffix = "na";
   13249                 :             :           break;
   13250                 :             :         case E_CCCmode:
   13251                 :       12528 :           suffix = "nc";
   13252                 :             :           break;
   13253                 :       10799 :         case E_CCOmode:
   13254                 :       10799 :           suffix = "no";
   13255                 :       10799 :           break;
   13256                 :             :         case E_CCPmode:
   13257                 :        4285 :           suffix = "np";
   13258                 :             :           break;
   13259                 :             :         case E_CCSmode:
   13260                 :       52555 :           suffix = "ns";
   13261                 :             :           break;
   13262                 :     2162294 :         default:
   13263                 :     2162294 :           suffix = "ne";
   13264                 :     2162294 :           break;
   13265                 :             :         }
   13266                 :             :       break;
   13267                 :      250617 :     case GT:
   13268                 :      250617 :       gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
   13269                 :             :       suffix = "g";
   13270                 :             :       break;
   13271                 :      154724 :     case GTU:
   13272                 :             :       /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
   13273                 :             :          Those same assemblers have the same but opposite lossage on cmov.  */
   13274                 :      154724 :       if (mode == CCmode)
   13275                 :      154724 :         suffix = fp ? "nbe" : "a";
   13276                 :             :       else
   13277                 :           0 :         gcc_unreachable ();
   13278                 :             :       break;
   13279                 :      222718 :     case LT:
   13280                 :      222718 :       switch (mode)
   13281                 :             :         {
   13282                 :             :         case E_CCNOmode:
   13283                 :             :         case E_CCGOCmode:
   13284                 :             :           suffix = "s";
   13285                 :             :           break;
   13286                 :             : 
   13287                 :             :         case E_CCmode:
   13288                 :             :         case E_CCGCmode:
   13289                 :             :         case E_CCGZmode:
   13290                 :     6695870 :           suffix = "l";
   13291                 :             :           break;
   13292                 :             : 
   13293                 :           0 :         default:
   13294                 :           0 :           gcc_unreachable ();
   13295                 :             :         }
   13296                 :             :       break;
   13297                 :      399721 :     case LTU:
   13298                 :      399721 :       if (mode == CCmode || mode == CCGZmode)
   13299                 :             :         suffix = "b";
   13300                 :       24539 :       else if (mode == CCCmode)
   13301                 :       24539 :         suffix = fp ? "b" : "c";
   13302                 :             :       else
   13303                 :           0 :         gcc_unreachable ();
   13304                 :             :       break;
   13305                 :      140287 :     case GE:
   13306                 :      140287 :       switch (mode)
   13307                 :             :         {
   13308                 :             :         case E_CCNOmode:
   13309                 :             :         case E_CCGOCmode:
   13310                 :             :           suffix = "ns";
   13311                 :             :           break;
   13312                 :             : 
   13313                 :             :         case E_CCmode:
   13314                 :             :         case E_CCGCmode:
   13315                 :             :         case E_CCGZmode:
   13316                 :     6695870 :           suffix = "ge";
   13317                 :             :           break;
   13318                 :             : 
   13319                 :           0 :         default:
   13320                 :           0 :           gcc_unreachable ();
   13321                 :             :         }
   13322                 :             :       break;
   13323                 :      174412 :     case GEU:
   13324                 :      174412 :       if (mode == CCmode || mode == CCGZmode)
   13325                 :             :         suffix = "nb";
   13326                 :       11681 :       else if (mode == CCCmode)
   13327                 :       11681 :         suffix = fp ? "nb" : "nc";
   13328                 :             :       else
   13329                 :           0 :         gcc_unreachable ();
   13330                 :             :       break;
   13331                 :      226267 :     case LE:
   13332                 :      226267 :       gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
   13333                 :             :       suffix = "le";
   13334                 :             :       break;
   13335                 :      106059 :     case LEU:
   13336                 :      106059 :       if (mode == CCmode)
   13337                 :             :         suffix = "be";
   13338                 :             :       else
   13339                 :           0 :         gcc_unreachable ();
   13340                 :             :       break;
   13341                 :      232039 :     case UNORDERED:
   13342                 :      232039 :       suffix = fp ? "u" : "p";
   13343                 :             :       break;
   13344                 :        4286 :     case ORDERED:
   13345                 :        4286 :       suffix = fp ? "nu" : "np";
   13346                 :             :       break;
   13347                 :           0 :     default:
   13348                 :           0 :       gcc_unreachable ();
   13349                 :             :     }
   13350                 :     6695870 :   fputs (suffix, file);
   13351                 :     6695870 : }
   13352                 :             : 
   13353                 :             : /* Print the name of register X to FILE based on its machine mode and number.
   13354                 :             :    If CODE is 'w', pretend the mode is HImode.
   13355                 :             :    If CODE is 'b', pretend the mode is QImode.
   13356                 :             :    If CODE is 'k', pretend the mode is SImode.
   13357                 :             :    If CODE is 'q', pretend the mode is DImode.
   13358                 :             :    If CODE is 'x', pretend the mode is V4SFmode.
   13359                 :             :    If CODE is 't', pretend the mode is V8SFmode.
   13360                 :             :    If CODE is 'g', pretend the mode is V16SFmode.
   13361                 :             :    If CODE is 'h', pretend the reg is the 'high' byte register.
   13362                 :             :    If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   13363                 :             :    If CODE is 'd', duplicate the operand for AVX instruction.
   13364                 :             :    If CODE is 'V', print naked full integer register name without %.
   13365                 :             :  */
   13366                 :             : 
   13367                 :             : void
   13368                 :   117317173 : print_reg (rtx x, int code, FILE *file)
   13369                 :             : {
   13370                 :   117317173 :   const char *reg;
   13371                 :   117317173 :   int msize;
   13372                 :   117317173 :   unsigned int regno;
   13373                 :   117317173 :   bool duplicated;
   13374                 :             : 
   13375                 :   117317173 :   if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
   13376                 :   117315207 :     putc ('%', file);
   13377                 :             : 
   13378                 :   117317173 :   if (x == pc_rtx)
   13379                 :             :     {
   13380                 :     5559134 :       gcc_assert (TARGET_64BIT);
   13381                 :     5559134 :       fputs ("rip", file);
   13382                 :     5559134 :       return;
   13383                 :             :     }
   13384                 :             : 
   13385                 :   111758039 :   if (code == 'y' && STACK_TOP_P (x))
   13386                 :             :     {
   13387                 :      296382 :       fputs ("st(0)", file);
   13388                 :      296382 :       return;
   13389                 :             :     }
   13390                 :             : 
   13391                 :   111461657 :   if (code == 'w')
   13392                 :             :     msize = 2;
   13393                 :             :   else if (code == 'b')
   13394                 :             :     msize = 1;
   13395                 :             :   else if (code == 'k')
   13396                 :             :     msize = 4;
   13397                 :             :   else if (code == 'q')
   13398                 :             :     msize = 8;
   13399                 :             :   else if (code == 'h')
   13400                 :             :     msize = 0;
   13401                 :             :   else if (code == 'x')
   13402                 :             :     msize = 16;
   13403                 :             :   else if (code == 't')
   13404                 :             :     msize = 32;
   13405                 :             :   else if (code == 'g')
   13406                 :             :     msize = 64;
   13407                 :             :   else
   13408                 :   190569728 :     msize = GET_MODE_SIZE (GET_MODE (x));
   13409                 :             : 
   13410                 :   111461657 :   regno = REGNO (x);
   13411                 :             : 
   13412                 :   111461657 :   if (regno == ARG_POINTER_REGNUM
   13413                 :   111461657 :       || regno == FRAME_POINTER_REGNUM
   13414                 :   111461657 :       || regno == FPSR_REG)
   13415                 :             :     {
   13416                 :           0 :       output_operand_lossage
   13417                 :           0 :         ("invalid use of register '%s'", reg_names[regno]);
   13418                 :           0 :       return;
   13419                 :             :     }
   13420                 :   111461657 :   else if (regno == FLAGS_REG)
   13421                 :             :     {
   13422                 :           1 :       output_operand_lossage ("invalid use of asm flag output");
   13423                 :           1 :       return;
   13424                 :             :     }
   13425                 :             : 
   13426                 :   111461656 :   if (code == 'V')
   13427                 :             :     {
   13428                 :           1 :       if (GENERAL_REGNO_P (regno))
   13429                 :           2 :         msize = GET_MODE_SIZE (word_mode);
   13430                 :             :       else
   13431                 :           0 :         error ("%<V%> modifier on non-integer register");
   13432                 :             :     }
   13433                 :             : 
   13434                 :   111461656 :   duplicated = code == 'd' && TARGET_AVX;
   13435                 :             : 
   13436                 :   111461656 :   switch (msize)
   13437                 :             :     {
   13438                 :    72719197 :     case 16:
   13439                 :    72719197 :     case 12:
   13440                 :    72719197 :     case 8:
   13441                 :   135994760 :       if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
   13442                 :           5 :         warning (0, "unsupported size for integer register");
   13443                 :             :       /* FALLTHRU */
   13444                 :   108152912 :     case 4:
   13445                 :   108152912 :       if (LEGACY_INT_REGNO_P (regno))
   13446                 :   118345072 :         putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
   13447                 :             :       /* FALLTHRU */
   13448                 :   109013660 :     case 2:
   13449                 :    20776308 :     normal:
   13450                 :   109013660 :       reg = hi_reg_name[regno];
   13451                 :   109013660 :       break;
   13452                 :     2179568 :     case 1:
   13453                 :     2179568 :       if (regno >= ARRAY_SIZE (qi_reg_name))
   13454                 :      263057 :         goto normal;
   13455                 :     1916511 :       if (!ANY_QI_REGNO_P (regno))
   13456                 :           0 :         error ("unsupported size for integer register");
   13457                 :     1916511 :       reg = qi_reg_name[regno];
   13458                 :     1916511 :       break;
   13459                 :       26769 :     case 0:
   13460                 :       26769 :       if (regno >= ARRAY_SIZE (qi_high_reg_name))
   13461                 :           0 :         goto normal;
   13462                 :       26769 :       reg = qi_high_reg_name[regno];
   13463                 :       26769 :       break;
   13464                 :      504716 :     case 32:
   13465                 :      504716 :     case 64:
   13466                 :      504716 :       if (SSE_REGNO_P (regno))
   13467                 :             :         {
   13468                 :      504716 :           gcc_assert (!duplicated);
   13469                 :      696394 :           putc (msize == 32 ? 'y' : 'z', file);
   13470                 :      504716 :           reg = hi_reg_name[regno] + 1;
   13471                 :      504716 :           break;
   13472                 :             :         }
   13473                 :           0 :       goto normal;
   13474                 :           0 :     default:
   13475                 :           0 :       gcc_unreachable ();
   13476                 :             :     }
   13477                 :             : 
   13478                 :   111461656 :   fputs (reg, file);
   13479                 :             : 
   13480                 :             :   /* Irritatingly, AMD extended registers use
   13481                 :             :      different naming convention: "r%d[bwd]"  */
   13482                 :   111461656 :   if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   13483                 :             :     {
   13484                 :     9537928 :       gcc_assert (TARGET_64BIT);
   13485                 :     9537928 :       switch (msize)
   13486                 :             :         {
   13487                 :           0 :           case 0:
   13488                 :           0 :             error ("extended registers have no high halves");
   13489                 :           0 :             break;
   13490                 :      181235 :           case 1:
   13491                 :      181235 :             putc ('b', file);
   13492                 :      181235 :             break;
   13493                 :       26533 :           case 2:
   13494                 :       26533 :             putc ('w', file);
   13495                 :       26533 :             break;
   13496                 :     2462733 :           case 4:
   13497                 :     2462733 :             putc ('d', file);
   13498                 :     2462733 :             break;
   13499                 :             :           case 8:
   13500                 :             :             /* no suffix */
   13501                 :             :             break;
   13502                 :           0 :           default:
   13503                 :           0 :             error ("unsupported operand size for extended register");
   13504                 :           0 :             break;
   13505                 :             :         }
   13506                 :     9537928 :       return;
   13507                 :             :     }
   13508                 :             : 
   13509                 :   101923728 :   if (duplicated)
   13510                 :             :     {
   13511                 :       17842 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   13512                 :       17821 :         fprintf (file, ", %%%s", reg);
   13513                 :             :       else
   13514                 :          21 :         fprintf (file, ", %s", reg);
   13515                 :             :     }
   13516                 :             : }
   13517                 :             : 
   13518                 :             : /* Meaning of CODE:
   13519                 :             :    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
   13520                 :             :    C -- print opcode suffix for set/cmov insn.
   13521                 :             :    c -- like C, but print reversed condition
   13522                 :             :    F,f -- likewise, but for floating-point.
   13523                 :             :    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
   13524                 :             :         otherwise nothing
   13525                 :             :    R -- print embedded rounding and sae.
   13526                 :             :    r -- print only sae.
   13527                 :             :    z -- print the opcode suffix for the size of the current operand.
   13528                 :             :    Z -- likewise, with special suffixes for x87 instructions.
   13529                 :             :    * -- print a star (in certain assembler syntax)
   13530                 :             :    A -- print an absolute memory reference.
   13531                 :             :    E -- print address with DImode register names if TARGET_64BIT.
   13532                 :             :    w -- print the operand as if it's a "word" (HImode) even if it isn't.
   13533                 :             :    s -- print a shift double count, followed by the assemblers argument
   13534                 :             :         delimiter.
   13535                 :             :    b -- print the QImode name of the register for the indicated operand.
   13536                 :             :         %b0 would print %al if operands[0] is reg 0.
   13537                 :             :    w --  likewise, print the HImode name of the register.
   13538                 :             :    k --  likewise, print the SImode name of the register.
   13539                 :             :    q --  likewise, print the DImode name of the register.
   13540                 :             :    x --  likewise, print the V4SFmode name of the register.
   13541                 :             :    t --  likewise, print the V8SFmode name of the register.
   13542                 :             :    g --  likewise, print the V16SFmode name of the register.
   13543                 :             :    h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
   13544                 :             :    y -- print "st(0)" instead of "st" as a register.
   13545                 :             :    d -- print duplicated register operand for AVX instruction.
   13546                 :             :    D -- print condition for SSE cmp instruction.
   13547                 :             :    P -- if PIC, print an @PLT suffix.  For -fno-plt, load function
   13548                 :             :         address from GOT.
   13549                 :             :    p -- print raw symbol name.
   13550                 :             :    X -- don't print any sort of PIC '@' suffix for a symbol.
   13551                 :             :    & -- print some in-use local-dynamic symbol name.
   13552                 :             :    H -- print a memory address offset by 8; used for sse high-parts
   13553                 :             :    Y -- print condition for XOP pcom* instruction.
   13554                 :             :    V -- print naked full integer register name without %.
   13555                 :             :    + -- print a branch hint as 'cs' or 'ds' prefix
   13556                 :             :    ; -- print a semicolon (after prefixes due to bug in older gas).
   13557                 :             :    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
   13558                 :             :    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
   13559                 :             :    M -- print addr32 prefix for TARGET_X32 with VSIB address.
   13560                 :             :    ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
   13561                 :             :    N -- print maskz if it's constant 0 operand.
   13562                 :             :    G -- print embedded flag for ccmp/ctest.
   13563                 :             :  */
   13564                 :             : 
   13565                 :             : void
   13566                 :   168249458 : ix86_print_operand (FILE *file, rtx x, int code)
   13567                 :             : {
   13568                 :   168438050 :   if (code)
   13569                 :             :     {
   13570                 :    58898895 :       switch (code)
   13571                 :             :         {
   13572                 :      188588 :         case 'A':
   13573                 :      188588 :           switch (ASSEMBLER_DIALECT)
   13574                 :             :             {
   13575                 :      188588 :             case ASM_ATT:
   13576                 :      188588 :               putc ('*', file);
   13577                 :      188588 :               break;
   13578                 :             : 
   13579                 :           0 :             case ASM_INTEL:
   13580                 :             :               /* Intel syntax. For absolute addresses, registers should not
   13581                 :             :                  be surrounded by braces.  */
   13582                 :           0 :               if (!REG_P (x))
   13583                 :             :                 {
   13584                 :           0 :                   putc ('[', file);
   13585                 :           0 :                   ix86_print_operand (file, x, 0);
   13586                 :           0 :                   putc (']', file);
   13587                 :           0 :                   return;
   13588                 :             :                 }
   13589                 :             :               break;
   13590                 :             : 
   13591                 :           0 :             default:
   13592                 :           0 :               gcc_unreachable ();
   13593                 :             :             }
   13594                 :             : 
   13595                 :      188588 :           ix86_print_operand (file, x, 0);
   13596                 :      188588 :           return;
   13597                 :             : 
   13598                 :     3328987 :         case 'E':
   13599                 :             :           /* Wrap address in an UNSPEC to declare special handling.  */
   13600                 :     3328987 :           if (TARGET_64BIT)
   13601                 :     2849589 :             x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
   13602                 :             : 
   13603                 :     3328987 :           output_address (VOIDmode, x);
   13604                 :     3328987 :           return;
   13605                 :             : 
   13606                 :           0 :         case 'L':
   13607                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13608                 :           0 :             putc ('l', file);
   13609                 :           0 :           return;
   13610                 :             : 
   13611                 :           0 :         case 'W':
   13612                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13613                 :           0 :             putc ('w', file);
   13614                 :           0 :           return;
   13615                 :             : 
   13616                 :           0 :         case 'B':
   13617                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13618                 :           0 :             putc ('b', file);
   13619                 :           0 :           return;
   13620                 :             : 
   13621                 :           0 :         case 'Q':
   13622                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13623                 :           0 :             putc ('l', file);
   13624                 :           0 :           return;
   13625                 :             : 
   13626                 :           0 :         case 'S':
   13627                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13628                 :           0 :             putc ('s', file);
   13629                 :           0 :           return;
   13630                 :             : 
   13631                 :           0 :         case 'T':
   13632                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13633                 :           0 :             putc ('t', file);
   13634                 :           0 :           return;
   13635                 :             : 
   13636                 :             :         case 'O':
   13637                 :             : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   13638                 :             :           if (ASSEMBLER_DIALECT != ASM_ATT)
   13639                 :             :             return;
   13640                 :             : 
   13641                 :             :           switch (GET_MODE_SIZE (GET_MODE (x)))
   13642                 :             :             {
   13643                 :             :             case 2:
   13644                 :             :               putc ('w', file);
   13645                 :             :               break;
   13646                 :             : 
   13647                 :             :             case 4:
   13648                 :             :               putc ('l', file);
   13649                 :             :               break;
   13650                 :             : 
   13651                 :             :             case 8:
   13652                 :             :               putc ('q', file);
   13653                 :             :               break;
   13654                 :             : 
   13655                 :             :             default:
   13656                 :             :               output_operand_lossage ("invalid operand size for operand "
   13657                 :             :                                       "code 'O'");
   13658                 :             :               return;
   13659                 :             :             }
   13660                 :             : 
   13661                 :             :           putc ('.', file);
   13662                 :             : #endif
   13663                 :             :           return;
   13664                 :             : 
   13665                 :       37131 :         case 'z':
   13666                 :       37131 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   13667                 :             :             {
   13668                 :             :               /* Opcodes don't get size suffixes if using Intel opcodes.  */
   13669                 :       37129 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   13670                 :             :                 return;
   13671                 :             : 
   13672                 :       74258 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13673                 :             :                 {
   13674                 :           6 :                 case 1:
   13675                 :           6 :                   putc ('b', file);
   13676                 :           6 :                   return;
   13677                 :             : 
   13678                 :           6 :                 case 2:
   13679                 :           6 :                   putc ('w', file);
   13680                 :           6 :                   return;
   13681                 :             : 
   13682                 :       36673 :                 case 4:
   13683                 :       36673 :                   putc ('l', file);
   13684                 :       36673 :                   return;
   13685                 :             : 
   13686                 :         444 :                 case 8:
   13687                 :         444 :                   putc ('q', file);
   13688                 :         444 :                   return;
   13689                 :             : 
   13690                 :           0 :                 default:
   13691                 :           0 :                   output_operand_lossage ("invalid operand size for operand "
   13692                 :             :                                           "code 'z'");
   13693                 :           0 :                   return;
   13694                 :             :                 }
   13695                 :             :             }
   13696                 :             : 
   13697                 :           2 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   13698                 :             :             {
   13699                 :           1 :               if (this_is_asm_operands)
   13700                 :           1 :                 warning_for_asm (this_is_asm_operands,
   13701                 :             :                                  "non-integer operand used with operand code %<z%>");
   13702                 :             :               else
   13703                 :           0 :                 warning (0, "non-integer operand used with operand code %<z%>");
   13704                 :             :             }
   13705                 :             :           /* FALLTHRU */
   13706                 :             : 
   13707                 :      377453 :         case 'Z':
   13708                 :             :           /* 387 opcodes don't get size suffixes if using Intel opcodes.  */
   13709                 :      377453 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   13710                 :             :             return;
   13711                 :             : 
   13712                 :      377453 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   13713                 :             :             {
   13714                 :       29634 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13715                 :             :                 {
   13716                 :        3501 :                 case 2:
   13717                 :             : #ifdef HAVE_AS_IX86_FILDS
   13718                 :        3501 :                   putc ('s', file);
   13719                 :             : #endif
   13720                 :        3501 :                   return;
   13721                 :             : 
   13722                 :        3896 :                 case 4:
   13723                 :        3896 :                   putc ('l', file);
   13724                 :        3896 :                   return;
   13725                 :             : 
   13726                 :        7420 :                 case 8:
   13727                 :             : #ifdef HAVE_AS_IX86_FILDQ
   13728                 :        7420 :                   putc ('q', file);
   13729                 :             : #else
   13730                 :             :                   fputs ("ll", file);
   13731                 :             : #endif
   13732                 :        7420 :                   return;
   13733                 :             : 
   13734                 :             :                 default:
   13735                 :             :                   break;
   13736                 :             :                 }
   13737                 :             :             }
   13738                 :      362636 :           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   13739                 :             :             {
   13740                 :             :               /* 387 opcodes don't get size suffixes
   13741                 :             :                  if the operands are registers.  */
   13742                 :      362634 :               if (STACK_REG_P (x))
   13743                 :             :                 return;
   13744                 :             : 
   13745                 :      679038 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13746                 :             :                 {
   13747                 :       22608 :                 case 4:
   13748                 :       22608 :                   putc ('s', file);
   13749                 :       22608 :                   return;
   13750                 :             : 
   13751                 :       31780 :                 case 8:
   13752                 :       31780 :                   putc ('l', file);
   13753                 :       31780 :                   return;
   13754                 :             : 
   13755                 :      285129 :                 case 12:
   13756                 :      285129 :                 case 16:
   13757                 :      285129 :                   putc ('t', file);
   13758                 :      285129 :                   return;
   13759                 :             : 
   13760                 :             :                 default:
   13761                 :             :                   break;
   13762                 :             :                 }
   13763                 :             :             }
   13764                 :             :           else
   13765                 :             :             {
   13766                 :           2 :               output_operand_lossage ("invalid operand type used with "
   13767                 :             :                                       "operand code '%c'", code);
   13768                 :           2 :               return;
   13769                 :             :             }
   13770                 :             : 
   13771                 :           2 :           output_operand_lossage ("invalid operand size for operand code '%c'",
   13772                 :             :                                   code);
   13773                 :           2 :           return;
   13774                 :             : 
   13775                 :             :         case 'd':
   13776                 :             :         case 'b':
   13777                 :             :         case 'w':
   13778                 :             :         case 'k':
   13779                 :             :         case 'q':
   13780                 :             :         case 'h':
   13781                 :             :         case 't':
   13782                 :             :         case 'g':
   13783                 :             :         case 'y':
   13784                 :             :         case 'x':
   13785                 :             :         case 'X':
   13786                 :             :         case 'P':
   13787                 :             :         case 'p':
   13788                 :             :         case 'V':
   13789                 :             :           break;
   13790                 :             : 
   13791                 :           0 :         case 's':
   13792                 :           0 :           if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
   13793                 :             :             {
   13794                 :           0 :               ix86_print_operand (file, x, 0);
   13795                 :           0 :               fputs (", ", file);
   13796                 :             :             }
   13797                 :           0 :           return;
   13798                 :             : 
   13799                 :         497 :         case 'Y':
   13800                 :         497 :           switch (GET_CODE (x))
   13801                 :             :             {
   13802                 :         185 :             case NE:
   13803                 :         185 :               fputs ("neq", file);
   13804                 :         185 :               break;
   13805                 :          32 :             case EQ:
   13806                 :          32 :               fputs ("eq", file);
   13807                 :          32 :               break;
   13808                 :          64 :             case GE:
   13809                 :          64 :             case GEU:
   13810                 :          64 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
   13811                 :          64 :               break;
   13812                 :          40 :             case GT:
   13813                 :          40 :             case GTU:
   13814                 :          40 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
   13815                 :          40 :               break;
   13816                 :          64 :             case LE:
   13817                 :          64 :             case LEU:
   13818                 :          64 :               fputs ("le", file);
   13819                 :          64 :               break;
   13820                 :         112 :             case LT:
   13821                 :         112 :             case LTU:
   13822                 :         112 :               fputs ("lt", file);
   13823                 :         112 :               break;
   13824                 :           0 :             case UNORDERED:
   13825                 :           0 :               fputs ("unord", file);
   13826                 :           0 :               break;
   13827                 :           0 :             case ORDERED:
   13828                 :           0 :               fputs ("ord", file);
   13829                 :           0 :               break;
   13830                 :           0 :             case UNEQ:
   13831                 :           0 :               fputs ("ueq", file);
   13832                 :           0 :               break;
   13833                 :           0 :             case UNGE:
   13834                 :           0 :               fputs ("nlt", file);
   13835                 :           0 :               break;
   13836                 :           0 :             case UNGT:
   13837                 :           0 :               fputs ("nle", file);
   13838                 :           0 :               break;
   13839                 :           0 :             case UNLE:
   13840                 :           0 :               fputs ("ule", file);
   13841                 :           0 :               break;
   13842                 :           0 :             case UNLT:
   13843                 :           0 :               fputs ("ult", file);
   13844                 :           0 :               break;
   13845                 :           0 :             case LTGT:
   13846                 :           0 :               fputs ("une", file);
   13847                 :           0 :               break;
   13848                 :           0 :             default:
   13849                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   13850                 :             :                                       "invalid operand code 'Y'");
   13851                 :           0 :               return;
   13852                 :             :             }
   13853                 :         497 :           return;
   13854                 :             : 
   13855                 :        8947 :         case 'D':
   13856                 :             :           /* Little bit of braindamage here.  The SSE compare instructions
   13857                 :             :              does use completely different names for the comparisons that the
   13858                 :             :              fp conditional moves.  */
   13859                 :        8947 :           switch (GET_CODE (x))
   13860                 :             :             {
   13861                 :           2 :             case UNEQ:
   13862                 :           2 :               if (TARGET_AVX)
   13863                 :             :                 {
   13864                 :           2 :                   fputs ("eq_us", file);
   13865                 :           2 :                   break;
   13866                 :             :                 }
   13867                 :             :              /* FALLTHRU */
   13868                 :        4328 :             case EQ:
   13869                 :        4328 :               fputs ("eq", file);
   13870                 :        4328 :               break;
   13871                 :           0 :             case UNLT:
   13872                 :           0 :               if (TARGET_AVX)
   13873                 :             :                 {
   13874                 :           0 :                   fputs ("nge", file);
   13875                 :           0 :                   break;
   13876                 :             :                 }
   13877                 :             :              /* FALLTHRU */
   13878                 :        1613 :             case LT:
   13879                 :        1613 :               fputs ("lt", file);
   13880                 :        1613 :               break;
   13881                 :           0 :             case UNLE:
   13882                 :           0 :               if (TARGET_AVX)
   13883                 :             :                 {
   13884                 :           0 :                   fputs ("ngt", file);
   13885                 :           0 :                   break;
   13886                 :             :                 }
   13887                 :             :              /* FALLTHRU */
   13888                 :         687 :             case LE:
   13889                 :         687 :               fputs ("le", file);
   13890                 :         687 :               break;
   13891                 :          89 :             case UNORDERED:
   13892                 :          89 :               fputs ("unord", file);
   13893                 :          89 :               break;
   13894                 :          24 :             case LTGT:
   13895                 :          24 :               if (TARGET_AVX)
   13896                 :             :                 {
   13897                 :          24 :                   fputs ("neq_oq", file);
   13898                 :          24 :                   break;
   13899                 :             :                 }
   13900                 :             :              /* FALLTHRU */
   13901                 :         980 :             case NE:
   13902                 :         980 :               fputs ("neq", file);
   13903                 :         980 :               break;
   13904                 :           0 :             case GE:
   13905                 :           0 :               if (TARGET_AVX)
   13906                 :             :                 {
   13907                 :           0 :                   fputs ("ge", file);
   13908                 :           0 :                   break;
   13909                 :             :                 }
   13910                 :             :              /* FALLTHRU */
   13911                 :         398 :             case UNGE:
   13912                 :         398 :               fputs ("nlt", file);
   13913                 :         398 :               break;
   13914                 :           0 :             case GT:
   13915                 :           0 :               if (TARGET_AVX)
   13916                 :             :                 {
   13917                 :           0 :                   fputs ("gt", file);
   13918                 :           0 :                   break;
   13919                 :             :                 }
   13920                 :             :              /* FALLTHRU */
   13921                 :         745 :             case UNGT:
   13922                 :         745 :               fputs ("nle", file);
   13923                 :         745 :               break;
   13924                 :          81 :             case ORDERED:
   13925                 :          81 :               fputs ("ord", file);
   13926                 :          81 :               break;
   13927                 :           0 :             default:
   13928                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   13929                 :             :                                       "invalid operand code 'D'");
   13930                 :           0 :               return;
   13931                 :             :             }
   13932                 :        8947 :           return;
   13933                 :             : 
   13934                 :     6695870 :         case 'F':
   13935                 :     6695870 :         case 'f':
   13936                 :             : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   13937                 :             :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13938                 :             :             putc ('.', file);
   13939                 :             :           gcc_fallthrough ();
   13940                 :             : #endif
   13941                 :             : 
   13942                 :     6695870 :         case 'C':
   13943                 :     6695870 :         case 'c':
   13944                 :     6695870 :           if (!COMPARISON_P (x))
   13945                 :             :             {
   13946                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   13947                 :             :                                       "invalid operand code '%c'", code);
   13948                 :           0 :               return;
   13949                 :             :             }
   13950                 :     6695870 :           put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
   13951                 :     6695870 :                               code == 'c' || code == 'f',
   13952                 :     6695870 :                               code == 'F' || code == 'f',
   13953                 :             :                               file);
   13954                 :     6695870 :           return;
   13955                 :             : 
   13956                 :          21 :         case 'G':
   13957                 :          21 :           {
   13958                 :          21 :             int dfv = INTVAL (x);
   13959                 :          21 :             const char *dfv_suffix = ix86_ccmp_dfv_mapping[dfv];
   13960                 :          21 :             fputs (dfv_suffix, file);
   13961                 :             :           }
   13962                 :          21 :           return;
   13963                 :             : 
   13964                 :        1366 :         case 'H':
   13965                 :        1366 :           if (!offsettable_memref_p (x))
   13966                 :             :             {
   13967                 :           1 :               output_operand_lossage ("operand is not an offsettable memory "
   13968                 :             :                                       "reference, invalid operand code 'H'");
   13969                 :           1 :               return;
   13970                 :             :             }
   13971                 :             :           /* It doesn't actually matter what mode we use here, as we're
   13972                 :             :              only going to use this for printing.  */
   13973                 :        1365 :           x = adjust_address_nv (x, DImode, 8);
   13974                 :             :           /* Output 'qword ptr' for intel assembler dialect.  */
   13975                 :        1365 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   13976                 :           0 :             code = 'q';
   13977                 :             :           break;
   13978                 :             : 
   13979                 :       75432 :         case 'K':
   13980                 :       75432 :           if (!CONST_INT_P (x))
   13981                 :             :             {
   13982                 :           1 :               output_operand_lossage ("operand is not an integer, invalid "
   13983                 :             :                                       "operand code 'K'");
   13984                 :           1 :               return;
   13985                 :             :             }
   13986                 :             : 
   13987                 :       75431 :           if (INTVAL (x) & IX86_HLE_ACQUIRE)
   13988                 :             : #ifdef HAVE_AS_IX86_HLE
   13989                 :          22 :             fputs ("xacquire ", file);
   13990                 :             : #else
   13991                 :             :             fputs ("\n" ASM_BYTE "0xf2\n\t", file);
   13992                 :             : #endif
   13993                 :       75409 :           else if (INTVAL (x) & IX86_HLE_RELEASE)
   13994                 :             : #ifdef HAVE_AS_IX86_HLE
   13995                 :          24 :             fputs ("xrelease ", file);
   13996                 :             : #else
   13997                 :             :             fputs ("\n" ASM_BYTE "0xf3\n\t", file);
   13998                 :             : #endif
   13999                 :             :           /* We do not want to print value of the operand.  */
   14000                 :       75431 :           return;
   14001                 :             : 
   14002                 :       43085 :         case 'N':
   14003                 :       43085 :           if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
   14004                 :       15248 :             fputs ("{z}", file);
   14005                 :       43085 :           return;
   14006                 :             : 
   14007                 :        5603 :         case 'r':
   14008                 :        5603 :           if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
   14009                 :             :             {
   14010                 :           2 :               output_operand_lossage ("operand is not a specific integer, "
   14011                 :             :                                       "invalid operand code 'r'");
   14012                 :           2 :               return;
   14013                 :             :             }
   14014                 :             : 
   14015                 :        5601 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14016                 :           1 :             fputs (", ", file);
   14017                 :             : 
   14018                 :        5601 :           fputs ("{sae}", file);
   14019                 :             : 
   14020                 :        5601 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14021                 :        5600 :             fputs (", ", file);
   14022                 :             : 
   14023                 :        5601 :           return;
   14024                 :             : 
   14025                 :        8456 :         case 'R':
   14026                 :        8456 :           if (!CONST_INT_P (x))
   14027                 :             :             {
   14028                 :           1 :               output_operand_lossage ("operand is not an integer, invalid "
   14029                 :             :                                       "operand code 'R'");
   14030                 :           1 :               return;
   14031                 :             :             }
   14032                 :             : 
   14033                 :        8455 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14034                 :           2 :             fputs (", ", file);
   14035                 :             : 
   14036                 :        8455 :           switch (INTVAL (x))
   14037                 :             :             {
   14038                 :        7036 :             case ROUND_NEAREST_INT | ROUND_SAE:
   14039                 :        7036 :               fputs ("{rn-sae}", file);
   14040                 :        7036 :               break;
   14041                 :        1138 :             case ROUND_NEG_INF | ROUND_SAE:
   14042                 :        1138 :               fputs ("{rd-sae}", file);
   14043                 :        1138 :               break;
   14044                 :          84 :             case ROUND_POS_INF | ROUND_SAE:
   14045                 :          84 :               fputs ("{ru-sae}", file);
   14046                 :          84 :               break;
   14047                 :         196 :             case ROUND_ZERO | ROUND_SAE:
   14048                 :         196 :               fputs ("{rz-sae}", file);
   14049                 :         196 :               break;
   14050                 :           1 :             default:
   14051                 :           1 :               output_operand_lossage ("operand is not a specific integer, "
   14052                 :             :                                       "invalid operand code 'R'");
   14053                 :             :             }
   14054                 :             : 
   14055                 :        8455 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14056                 :        8453 :             fputs (", ", file);
   14057                 :             : 
   14058                 :        8455 :           return;
   14059                 :             : 
   14060                 :           0 :         case '*':
   14061                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14062                 :           0 :             putc ('*', file);
   14063                 :           0 :           return;
   14064                 :             : 
   14065                 :         269 :         case '&':
   14066                 :         269 :           {
   14067                 :         269 :             const char *name = get_some_local_dynamic_name ();
   14068                 :         269 :             if (name == NULL)
   14069                 :           1 :               output_operand_lossage ("'%%&' used without any "
   14070                 :             :                                       "local dynamic TLS references");
   14071                 :             :             else
   14072                 :         268 :               assemble_name (file, name);
   14073                 :         269 :             return;
   14074                 :             :           }
   14075                 :             : 
   14076                 :     6092722 :         case '+':
   14077                 :     6092722 :           {
   14078                 :     6092722 :             rtx x;
   14079                 :             : 
   14080                 :     6092722 :             if (!optimize
   14081                 :     4696641 :                 || optimize_function_for_size_p (cfun)
   14082                 :    10608744 :                 || (!TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN
   14083                 :     4516022 :                     && !TARGET_BRANCH_PREDICTION_HINTS_TAKEN))
   14084                 :     6092722 :               return;
   14085                 :             : 
   14086                 :           0 :             x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
   14087                 :           0 :             if (x)
   14088                 :             :               {
   14089                 :           0 :                 int pred_val = profile_probability::from_reg_br_prob_note
   14090                 :           0 :                                  (XINT (x, 0)).to_reg_br_prob_base ();
   14091                 :             : 
   14092                 :           0 :                 bool taken = pred_val > REG_BR_PROB_BASE / 2;
   14093                 :             :                 /* We use 3e (DS) prefix for taken branches and
   14094                 :             :                    2e (CS) prefix for not taken branches.  */
   14095                 :           0 :                 if (taken && TARGET_BRANCH_PREDICTION_HINTS_TAKEN)
   14096                 :           0 :                   fputs ("ds ; ", file);
   14097                 :           0 :                 else if (!taken && TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN)
   14098                 :           0 :                   fputs ("cs ; ", file);
   14099                 :             :               }
   14100                 :           0 :             return;
   14101                 :             :           }
   14102                 :             : 
   14103                 :             :         case ';':
   14104                 :             : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
   14105                 :             :           putc (';', file);
   14106                 :             : #endif
   14107                 :             :           return;
   14108                 :             : 
   14109                 :        3410 :         case '~':
   14110                 :        3410 :           putc (TARGET_AVX2 ? 'i' : 'f', file);
   14111                 :        3410 :           return;
   14112                 :             : 
   14113                 :        1697 :         case 'M':
   14114                 :        1697 :           if (TARGET_X32)
   14115                 :             :             {
   14116                 :             :               /* NB: 32-bit indices in VSIB address are sign-extended
   14117                 :             :                  to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
   14118                 :             :                  sign-extended to 0xfffffffff7fa3010 which is invalid
   14119                 :             :                  address.  Add addr32 prefix if there is no base
   14120                 :             :                  register nor symbol.  */
   14121                 :          40 :               bool ok;
   14122                 :          40 :               struct ix86_address parts;
   14123                 :          40 :               ok = ix86_decompose_address (x, &parts);
   14124                 :          40 :               gcc_assert (ok && parts.index == NULL_RTX);
   14125                 :          40 :               if (parts.base == NULL_RTX
   14126                 :          40 :                   && (parts.disp == NULL_RTX
   14127                 :          34 :                       || !symbolic_operand (parts.disp,
   14128                 :          34 :                                             GET_MODE (parts.disp))))
   14129                 :          34 :                 fputs ("addr32 ", file);
   14130                 :             :             }
   14131                 :        1697 :           return;
   14132                 :             : 
   14133                 :       52312 :         case '^':
   14134                 :       52312 :           if (TARGET_64BIT && Pmode != word_mode)
   14135                 :           0 :             fputs ("addr32 ", file);
   14136                 :       52312 :           return;
   14137                 :             : 
   14138                 :    14051034 :         case '!':
   14139                 :    14051034 :           if (ix86_notrack_prefixed_insn_p (current_output_insn))
   14140                 :        4046 :             fputs ("notrack ", file);
   14141                 :    14051034 :           return;
   14142                 :             : 
   14143                 :           1 :         default:
   14144                 :           1 :           output_operand_lossage ("invalid operand code '%c'", code);
   14145                 :             :         }
   14146                 :             :     }
   14147                 :             : 
   14148                 :   137072577 :   if (REG_P (x))
   14149                 :    82171415 :     print_reg (x, code, file);
   14150                 :             : 
   14151                 :    54901162 :   else if (MEM_P (x))
   14152                 :             :     {
   14153                 :    31143429 :       rtx addr = XEXP (x, 0);
   14154                 :             : 
   14155                 :             :       /* No `byte ptr' prefix for call instructions ... */
   14156                 :    31143429 :       if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
   14157                 :             :         {
   14158                 :         211 :           machine_mode mode = GET_MODE (x);
   14159                 :         211 :           const char *size;
   14160                 :             : 
   14161                 :             :           /* Check for explicit size override codes.  */
   14162                 :         211 :           if (code == 'b')
   14163                 :             :             size = "BYTE";
   14164                 :             :           else if (code == 'w')
   14165                 :             :             size = "WORD";
   14166                 :             :           else if (code == 'k')
   14167                 :             :             size = "DWORD";
   14168                 :             :           else if (code == 'q')
   14169                 :             :             size = "QWORD";
   14170                 :             :           else if (code == 'x')
   14171                 :             :             size = "XMMWORD";
   14172                 :             :           else if (code == 't')
   14173                 :             :             size = "YMMWORD";
   14174                 :             :           else if (code == 'g')
   14175                 :             :             size = "ZMMWORD";
   14176                 :         137 :           else if (mode == BLKmode)
   14177                 :             :             /* ... or BLKmode operands, when not overridden.  */
   14178                 :             :             size = NULL;
   14179                 :             :           else
   14180                 :         270 :             switch (GET_MODE_SIZE (mode))
   14181                 :             :               {
   14182                 :             :               case 1: size = "BYTE"; break;
   14183                 :             :               case 2: size = "WORD"; break;
   14184                 :             :               case 4: size = "DWORD"; break;
   14185                 :             :               case 8: size = "QWORD"; break;
   14186                 :             :               case 12: size = "TBYTE"; break;
   14187                 :           4 :               case 16:
   14188                 :           4 :                 if (mode == XFmode)
   14189                 :             :                   size = "TBYTE";
   14190                 :             :                 else
   14191                 :             :                   size = "XMMWORD";
   14192                 :             :                 break;
   14193                 :             :               case 32: size = "YMMWORD"; break;
   14194                 :             :               case 64: size = "ZMMWORD"; break;
   14195                 :           0 :               default:
   14196                 :           0 :                 gcc_unreachable ();
   14197                 :             :               }
   14198                 :             :           if (size)
   14199                 :             :             {
   14200                 :         209 :               fputs (size, file);
   14201                 :         209 :               fputs (" PTR ", file);
   14202                 :             :             }
   14203                 :             :         }
   14204                 :             : 
   14205                 :    31143429 :       if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14206                 :           0 :         output_operand_lossage ("invalid constraints for operand");
   14207                 :             :       else
   14208                 :    31143429 :         ix86_print_operand_address_as
   14209                 :    31444143 :           (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
   14210                 :             :     }
   14211                 :             : 
   14212                 :    23757733 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
   14213                 :             :     {
   14214                 :         796 :       long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   14215                 :         796 :                                REAL_MODE_FORMAT (HFmode));
   14216                 :         796 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14217                 :         796 :         putc ('$', file);
   14218                 :         796 :       fprintf (file, "0x%04x", (unsigned int) l);
   14219                 :             :     }
   14220                 :             : 
   14221                 :    23756937 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
   14222                 :             :     {
   14223                 :       17247 :       long l;
   14224                 :             : 
   14225                 :       17247 :       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14226                 :             : 
   14227                 :       17247 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14228                 :       17247 :         putc ('$', file);
   14229                 :             :       /* Sign extend 32bit SFmode immediate to 8 bytes.  */
   14230                 :       17247 :       if (code == 'q')
   14231                 :         387 :         fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
   14232                 :             :                  (unsigned long long) (int) l);
   14233                 :             :       else
   14234                 :       16860 :         fprintf (file, "0x%08x", (unsigned int) l);
   14235                 :             :     }
   14236                 :             : 
   14237                 :    23739690 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
   14238                 :             :     {
   14239                 :        3067 :       long l[2];
   14240                 :             : 
   14241                 :        3067 :       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14242                 :             : 
   14243                 :        3067 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14244                 :        3067 :         putc ('$', file);
   14245                 :        3067 :       fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
   14246                 :             :     }
   14247                 :             : 
   14248                 :             :   /* These float cases don't actually occur as immediate operands.  */
   14249                 :    23736623 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
   14250                 :             :     {
   14251                 :           0 :       char dstr[30];
   14252                 :             : 
   14253                 :           0 :       real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
   14254                 :           0 :       fputs (dstr, file);
   14255                 :             :     }
   14256                 :             : 
   14257                 :             :   /* Print bcst_mem_operand.  */
   14258                 :    23736623 :   else if (GET_CODE (x) == VEC_DUPLICATE)
   14259                 :             :     {
   14260                 :         312 :       machine_mode vmode = GET_MODE (x);
   14261                 :             :       /* Must be bcst_memory_operand.  */
   14262                 :         312 :       gcc_assert (bcst_mem_operand (x, vmode));
   14263                 :             : 
   14264                 :         312 :       rtx mem = XEXP (x,0);
   14265                 :         312 :       ix86_print_operand (file, mem, 0);
   14266                 :             : 
   14267                 :         312 :       switch (vmode)
   14268                 :             :         {
   14269                 :          28 :         case E_V2DImode:
   14270                 :          28 :         case E_V2DFmode:
   14271                 :          28 :           fputs ("{1to2}", file);
   14272                 :          28 :           break;
   14273                 :          74 :         case E_V4SImode:
   14274                 :          74 :         case E_V4SFmode:
   14275                 :          74 :         case E_V4DImode:
   14276                 :          74 :         case E_V4DFmode:
   14277                 :          74 :           fputs ("{1to4}", file);
   14278                 :          74 :           break;
   14279                 :          93 :         case E_V8SImode:
   14280                 :          93 :         case E_V8SFmode:
   14281                 :          93 :         case E_V8DFmode:
   14282                 :          93 :         case E_V8DImode:
   14283                 :          93 :         case E_V8HFmode:
   14284                 :          93 :           fputs ("{1to8}", file);
   14285                 :          93 :           break;
   14286                 :         109 :         case E_V16SFmode:
   14287                 :         109 :         case E_V16SImode:
   14288                 :         109 :         case E_V16HFmode:
   14289                 :         109 :           fputs ("{1to16}", file);
   14290                 :         109 :           break;
   14291                 :           8 :         case E_V32HFmode:
   14292                 :           8 :           fputs ("{1to32}", file);
   14293                 :           8 :           break;
   14294                 :           0 :         default:
   14295                 :           0 :           gcc_unreachable ();
   14296                 :             :         }
   14297                 :             :     }
   14298                 :             : 
   14299                 :             :   else
   14300                 :             :     {
   14301                 :             :       /* We have patterns that allow zero sets of memory, for instance.
   14302                 :             :          In 64-bit mode, we should probably support all 8-byte vectors,
   14303                 :             :          since we can in fact encode that into an immediate.  */
   14304                 :    23736311 :       if (GET_CODE (x) == CONST_VECTOR)
   14305                 :             :         {
   14306                 :         114 :           if (x != CONST0_RTX (GET_MODE (x)))
   14307                 :           2 :             output_operand_lossage ("invalid vector immediate");
   14308                 :         114 :           x = const0_rtx;
   14309                 :             :         }
   14310                 :             : 
   14311                 :    23736311 :       if (code == 'P')
   14312                 :             :         {
   14313                 :     5704901 :           if (ix86_force_load_from_GOT_p (x, true))
   14314                 :             :             {
   14315                 :             :               /* For inline assembly statement, load function address
   14316                 :             :                  from GOT with 'P' operand modifier to avoid PLT.  */
   14317                 :           4 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   14318                 :             :                                   (TARGET_64BIT
   14319                 :             :                                    ? UNSPEC_GOTPCREL
   14320                 :             :                                    : UNSPEC_GOT));
   14321                 :           4 :               x = gen_rtx_CONST (Pmode, x);
   14322                 :           4 :               x = gen_const_mem (Pmode, x);
   14323                 :           4 :               ix86_print_operand (file, x, 'A');
   14324                 :           4 :               return;
   14325                 :             :             }
   14326                 :             :         }
   14327                 :    18031410 :       else if (code != 'p')
   14328                 :             :         {
   14329                 :    18031301 :           if (CONST_INT_P (x))
   14330                 :             :             {
   14331                 :    14873553 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14332                 :    14873350 :                 putc ('$', file);
   14333                 :             :             }
   14334                 :     3157748 :           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
   14335                 :        9371 :                    || GET_CODE (x) == LABEL_REF)
   14336                 :             :             {
   14337                 :     3157746 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14338                 :     3157740 :                 putc ('$', file);
   14339                 :             :               else
   14340                 :           6 :                 fputs ("OFFSET FLAT:", file);
   14341                 :             :             }
   14342                 :             :         }
   14343                 :    23736307 :       if (CONST_INT_P (x))
   14344                 :    14873639 :         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
   14345                 :     8862668 :       else if (flag_pic || MACHOPIC_INDIRECT)
   14346                 :      512015 :         output_pic_addr_const (file, x, code);
   14347                 :             :       else
   14348                 :     8350653 :         output_addr_const (file, x);
   14349                 :             :     }
   14350                 :             : }
   14351                 :             : 
   14352                 :             : static bool
   14353                 :    20310522 : ix86_print_operand_punct_valid_p (unsigned char code)
   14354                 :             : {
   14355                 :    20310522 :   return (code == '*' || code == '+' || code == '&' || code == ';'
   14356                 :    14103346 :           || code == '~' || code == '^' || code == '!');
   14357                 :             : }
   14358                 :             : 
   14359                 :             : /* Print a memory operand whose address is ADDR.  */
   14360                 :             : 
   14361                 :             : static void
   14362                 :    34474603 : ix86_print_operand_address_as (FILE *file, rtx addr,
   14363                 :             :                                addr_space_t as, bool raw)
   14364                 :             : {
   14365                 :    34474603 :   struct ix86_address parts;
   14366                 :    34474603 :   rtx base, index, disp;
   14367                 :    34474603 :   int scale;
   14368                 :    34474603 :   int ok;
   14369                 :    34474603 :   bool vsib = false;
   14370                 :    34474603 :   int code = 0;
   14371                 :             : 
   14372                 :    34474603 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
   14373                 :             :     {
   14374                 :        1697 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   14375                 :        1697 :       gcc_assert (parts.index == NULL_RTX);
   14376                 :        1697 :       parts.index = XVECEXP (addr, 0, 1);
   14377                 :        1697 :       parts.scale = INTVAL (XVECEXP (addr, 0, 2));
   14378                 :        1697 :       addr = XVECEXP (addr, 0, 0);
   14379                 :        1697 :       vsib = true;
   14380                 :             :     }
   14381                 :    34472906 :   else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
   14382                 :             :     {
   14383                 :     2849589 :       gcc_assert (TARGET_64BIT);
   14384                 :     2849589 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   14385                 :     2849589 :       code = 'q';
   14386                 :             :     }
   14387                 :             :   else
   14388                 :    31623317 :     ok = ix86_decompose_address (addr, &parts);
   14389                 :             : 
   14390                 :    34474603 :   gcc_assert (ok);
   14391                 :             : 
   14392                 :    34474603 :   base = parts.base;
   14393                 :    34474603 :   index = parts.index;
   14394                 :    34474603 :   disp = parts.disp;
   14395                 :    34474603 :   scale = parts.scale;
   14396                 :             : 
   14397                 :    34474603 :   if (ADDR_SPACE_GENERIC_P (as))
   14398                 :    34195341 :     as = parts.seg;
   14399                 :             :   else
   14400                 :      279262 :     gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
   14401                 :             : 
   14402                 :    34474603 :   if (!ADDR_SPACE_GENERIC_P (as) && !raw)
   14403                 :             :     {
   14404                 :      279278 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14405                 :      279276 :         putc ('%', file);
   14406                 :             : 
   14407                 :      279278 :       switch (as)
   14408                 :             :         {
   14409                 :      179745 :         case ADDR_SPACE_SEG_FS:
   14410                 :      179745 :           fputs ("fs:", file);
   14411                 :      179745 :           break;
   14412                 :       99533 :         case ADDR_SPACE_SEG_GS:
   14413                 :       99533 :           fputs ("gs:", file);
   14414                 :       99533 :           break;
   14415                 :           0 :         default:
   14416                 :           0 :           gcc_unreachable ();
   14417                 :             :         }
   14418                 :             :     }
   14419                 :             : 
   14420                 :             :   /* Use one byte shorter RIP relative addressing for 64bit mode.  */
   14421                 :    34474603 :   if (TARGET_64BIT && !base && !index && !raw)
   14422                 :             :     {
   14423                 :     5817142 :       rtx symbol = disp;
   14424                 :             : 
   14425                 :     5817142 :       if (GET_CODE (disp) == CONST
   14426                 :     2080179 :           && GET_CODE (XEXP (disp, 0)) == PLUS
   14427                 :     1998434 :           && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   14428                 :     1998434 :         symbol = XEXP (XEXP (disp, 0), 0);
   14429                 :             : 
   14430                 :     5817142 :       if (GET_CODE (symbol) == LABEL_REF
   14431                 :     5817142 :           || (GET_CODE (symbol) == SYMBOL_REF
   14432                 :     5560081 :               && SYMBOL_REF_TLS_MODEL (symbol) == 0))
   14433                 :     5559134 :         base = pc_rtx;
   14434                 :             :     }
   14435                 :             : 
   14436                 :    34474603 :   if (!base && !index)
   14437                 :             :     {
   14438                 :             :       /* Displacement only requires special attention.  */
   14439                 :      599057 :       if (CONST_INT_P (disp))
   14440                 :             :         {
   14441                 :      268530 :           if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
   14442                 :           1 :             fputs ("ds:", file);
   14443                 :      268530 :           fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
   14444                 :             :         }
   14445                 :             :       /* Load the external function address via the GOT slot to avoid PLT.  */
   14446                 :      330527 :       else if (GET_CODE (disp) == CONST
   14447                 :      108874 :                && GET_CODE (XEXP (disp, 0)) == UNSPEC
   14448                 :       81964 :                && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
   14449                 :        8014 :                    || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
   14450                 :      404477 :                && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   14451                 :          24 :         output_pic_addr_const (file, disp, 0);
   14452                 :      330503 :       else if (flag_pic)
   14453                 :      112571 :         output_pic_addr_const (file, disp, 0);
   14454                 :             :       else
   14455                 :      217932 :         output_addr_const (file, disp);
   14456                 :             :     }
   14457                 :             :   else
   14458                 :             :     {
   14459                 :             :       /* Print SImode register names to force addr32 prefix.  */
   14460                 :    33875546 :       if (SImode_address_operand (addr, VOIDmode))
   14461                 :             :         {
   14462                 :          26 :           if (flag_checking)
   14463                 :             :             {
   14464                 :          26 :               gcc_assert (TARGET_64BIT);
   14465                 :          26 :               switch (GET_CODE (addr))
   14466                 :             :                 {
   14467                 :           0 :                 case SUBREG:
   14468                 :           0 :                   gcc_assert (GET_MODE (addr) == SImode);
   14469                 :           0 :                   gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
   14470                 :             :                   break;
   14471                 :          26 :                 case ZERO_EXTEND:
   14472                 :          26 :                 case AND:
   14473                 :          26 :                   gcc_assert (GET_MODE (addr) == DImode);
   14474                 :             :                   break;
   14475                 :           0 :                 default:
   14476                 :           0 :                   gcc_unreachable ();
   14477                 :             :                 }
   14478                 :             :             }
   14479                 :          26 :           gcc_assert (!code);
   14480                 :             :           code = 'k';
   14481                 :             :         }
   14482                 :    33875520 :       else if (code == 0
   14483                 :    31028342 :                && TARGET_X32
   14484                 :         292 :                && disp
   14485                 :         226 :                && CONST_INT_P (disp)
   14486                 :         136 :                && INTVAL (disp) < -16*1024*1024)
   14487                 :             :         {
   14488                 :             :           /* X32 runs in 64-bit mode, where displacement, DISP, in
   14489                 :             :              address DISP(%r64), is encoded as 32-bit immediate sign-
   14490                 :             :              extended from 32-bit to 64-bit.  For -0x40000300(%r64),
   14491                 :             :              address is %r64 + 0xffffffffbffffd00.  When %r64 <
   14492                 :             :              0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
   14493                 :             :              which is invalid for x32.  The correct address is %r64
   14494                 :             :              - 0x40000300 == 0xf7ffdd64.  To properly encode
   14495                 :             :              -0x40000300(%r64) for x32, we zero-extend negative
   14496                 :             :              displacement by forcing addr32 prefix which truncates
   14497                 :             :              0xfffffffff7ffdd64 to 0xf7ffdd64.  In theory, we should
   14498                 :             :              zero-extend all negative displacements, including -1(%rsp).
   14499                 :             :              However, for small negative displacements, sign-extension
   14500                 :             :              won't cause overflow.  We only zero-extend negative
   14501                 :             :              displacements if they < -16*1024*1024, which is also used
   14502                 :             :              to check legitimate address displacements for PIC.  */
   14503                 :          27 :           code = 'k';
   14504                 :             :         }
   14505                 :             : 
   14506                 :             :       /* Since the upper 32 bits of RSP are always zero for x32,
   14507                 :             :          we can encode %esp as %rsp to avoid 0x67 prefix if
   14508                 :             :          there is no index register.  */
   14509                 :         375 :       if (TARGET_X32 && Pmode == SImode
   14510                 :    33875754 :           && !index && base && REG_P (base) && REGNO (base) == SP_REG)
   14511                 :             :         code = 'q';
   14512                 :             : 
   14513                 :    33875546 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14514                 :             :         {
   14515                 :    33875286 :           if (disp)
   14516                 :             :             {
   14517                 :    30090593 :               if (flag_pic)
   14518                 :     2640716 :                 output_pic_addr_const (file, disp, 0);
   14519                 :    27449877 :               else if (GET_CODE (disp) == LABEL_REF)
   14520                 :        5493 :                 output_asm_label (disp);
   14521                 :             :               else
   14522                 :    27444384 :                 output_addr_const (file, disp);
   14523                 :             :             }
   14524                 :             : 
   14525                 :    33875286 :           putc ('(', file);
   14526                 :    33875286 :           if (base)
   14527                 :    33476058 :             print_reg (base, code, file);
   14528                 :    33875286 :           if (index)
   14529                 :             :             {
   14530                 :     1669387 :               putc (',', file);
   14531                 :     3337125 :               print_reg (index, vsib ? 0 : code, file);
   14532                 :     1669387 :               if (scale != 1 || vsib)
   14533                 :      966697 :                 fprintf (file, ",%d", scale);
   14534                 :             :             }
   14535                 :    33875286 :           putc (')', file);
   14536                 :             :         }
   14537                 :             :       else
   14538                 :             :         {
   14539                 :         260 :           rtx offset = NULL_RTX;
   14540                 :             : 
   14541                 :         260 :           if (disp)
   14542                 :             :             {
   14543                 :             :               /* Pull out the offset of a symbol; print any symbol itself.  */
   14544                 :         201 :               if (GET_CODE (disp) == CONST
   14545                 :          16 :                   && GET_CODE (XEXP (disp, 0)) == PLUS
   14546                 :          16 :                   && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   14547                 :             :                 {
   14548                 :          16 :                   offset = XEXP (XEXP (disp, 0), 1);
   14549                 :          16 :                   disp = gen_rtx_CONST (VOIDmode,
   14550                 :             :                                         XEXP (XEXP (disp, 0), 0));
   14551                 :             :                 }
   14552                 :             : 
   14553                 :         201 :               if (flag_pic)
   14554                 :           0 :                 output_pic_addr_const (file, disp, 0);
   14555                 :         201 :               else if (GET_CODE (disp) == LABEL_REF)
   14556                 :           0 :                 output_asm_label (disp);
   14557                 :         201 :               else if (CONST_INT_P (disp))
   14558                 :             :                 offset = disp;
   14559                 :             :               else
   14560                 :         101 :                 output_addr_const (file, disp);
   14561                 :             :             }
   14562                 :             : 
   14563                 :         260 :           putc ('[', file);
   14564                 :         260 :           if (base)
   14565                 :             :             {
   14566                 :         220 :               print_reg (base, code, file);
   14567                 :         220 :               if (offset)
   14568                 :             :                 {
   14569                 :         116 :                   if (INTVAL (offset) >= 0)
   14570                 :          18 :                     putc ('+', file);
   14571                 :         116 :                   fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   14572                 :             :                 }
   14573                 :             :             }
   14574                 :          40 :           else if (offset)
   14575                 :           0 :             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   14576                 :             :           else
   14577                 :          40 :             putc ('0', file);
   14578                 :             : 
   14579                 :         260 :           if (index)
   14580                 :             :             {
   14581                 :          93 :               putc ('+', file);
   14582                 :         138 :               print_reg (index, vsib ? 0 : code, file);
   14583                 :          93 :               if (scale != 1 || vsib)
   14584                 :          91 :                 fprintf (file, "*%d", scale);
   14585                 :             :             }
   14586                 :         260 :           putc (']', file);
   14587                 :             :         }
   14588                 :             :     }
   14589                 :    34474603 : }
   14590                 :             : 
   14591                 :             : static void
   14592                 :     3331175 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   14593                 :             : {
   14594                 :     3331175 :   if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14595                 :           1 :     output_operand_lossage ("invalid constraints for operand");
   14596                 :             :   else
   14597                 :     3331174 :     ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
   14598                 :     3331175 : }
   14599                 :             : 
   14600                 :             : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA.  */
   14601                 :             : 
   14602                 :             : static bool
   14603                 :       13787 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
   14604                 :             : {
   14605                 :       13787 :   rtx op;
   14606                 :             : 
   14607                 :       13787 :   if (GET_CODE (x) != UNSPEC)
   14608                 :             :     return false;
   14609                 :             : 
   14610                 :       13787 :   op = XVECEXP (x, 0, 0);
   14611                 :       13787 :   switch (XINT (x, 1))
   14612                 :             :     {
   14613                 :        1488 :     case UNSPEC_GOTOFF:
   14614                 :        1488 :       output_addr_const (file, op);
   14615                 :        1488 :       fputs ("@gotoff", file);
   14616                 :        1488 :       break;
   14617                 :           0 :     case UNSPEC_GOTTPOFF:
   14618                 :           0 :       output_addr_const (file, op);
   14619                 :             :       /* FIXME: This might be @TPOFF in Sun ld.  */
   14620                 :           0 :       fputs ("@gottpoff", file);
   14621                 :           0 :       break;
   14622                 :           0 :     case UNSPEC_TPOFF:
   14623                 :           0 :       output_addr_const (file, op);
   14624                 :           0 :       fputs ("@tpoff", file);
   14625                 :           0 :       break;
   14626                 :       10175 :     case UNSPEC_NTPOFF:
   14627                 :       10175 :       output_addr_const (file, op);
   14628                 :       10175 :       if (TARGET_64BIT)
   14629                 :        9455 :         fputs ("@tpoff", file);
   14630                 :             :       else
   14631                 :         720 :         fputs ("@ntpoff", file);
   14632                 :             :       break;
   14633                 :          30 :     case UNSPEC_DTPOFF:
   14634                 :          30 :       output_addr_const (file, op);
   14635                 :          30 :       fputs ("@dtpoff", file);
   14636                 :          30 :       break;
   14637                 :        2093 :     case UNSPEC_GOTNTPOFF:
   14638                 :        2093 :       output_addr_const (file, op);
   14639                 :        2093 :       if (TARGET_64BIT)
   14640                 :        2093 :         fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   14641                 :             :                "@gottpoff(%rip)" : "@gottpoff[rip]", file);
   14642                 :             :       else
   14643                 :           0 :         fputs ("@gotntpoff", file);
   14644                 :             :       break;
   14645                 :           1 :     case UNSPEC_INDNTPOFF:
   14646                 :           1 :       output_addr_const (file, op);
   14647                 :           1 :       fputs ("@indntpoff", file);
   14648                 :           1 :       break;
   14649                 :             : #if TARGET_MACHO
   14650                 :             :     case UNSPEC_MACHOPIC_OFFSET:
   14651                 :             :       output_addr_const (file, op);
   14652                 :             :       putc ('-', file);
   14653                 :             :       machopic_output_function_base_name (file);
   14654                 :             :       break;
   14655                 :             : #endif
   14656                 :             : 
   14657                 :             :     default:
   14658                 :             :       return false;
   14659                 :             :     }
   14660                 :             : 
   14661                 :             :   return true;
   14662                 :             : }
   14663                 :             : 
   14664                 :             : 
   14665                 :             : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
   14666                 :             :    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
   14667                 :             :    is the expression of the binary operation.  The output may either be
   14668                 :             :    emitted here, or returned to the caller, like all output_* functions.
   14669                 :             : 
   14670                 :             :    There is no guarantee that the operands are the same mode, as they
   14671                 :             :    might be within FLOAT or FLOAT_EXTEND expressions.  */
   14672                 :             : 
   14673                 :             : #ifndef SYSV386_COMPAT
   14674                 :             : /* Set to 1 for compatibility with brain-damaged assemblers.  No-one
   14675                 :             :    wants to fix the assemblers because that causes incompatibility
   14676                 :             :    with gcc.  No-one wants to fix gcc because that causes
   14677                 :             :    incompatibility with assemblers...  You can use the option of
   14678                 :             :    -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way.  */
   14679                 :             : #define SYSV386_COMPAT 1
   14680                 :             : #endif
   14681                 :             : 
   14682                 :             : const char *
   14683                 :      603012 : output_387_binary_op (rtx_insn *insn, rtx *operands)
   14684                 :             : {
   14685                 :      603012 :   static char buf[40];
   14686                 :      603012 :   const char *p;
   14687                 :      603012 :   bool is_sse
   14688                 :      603012 :     = (SSE_REG_P (operands[0])
   14689                 :      658318 :        || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
   14690                 :             : 
   14691                 :       55306 :   if (is_sse)
   14692                 :             :     p = "%v";
   14693                 :       55306 :   else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
   14694                 :       55299 :            || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
   14695                 :             :     p = "fi";
   14696                 :             :   else
   14697                 :      603012 :     p = "f";
   14698                 :             : 
   14699                 :      603012 :   strcpy (buf, p);
   14700                 :             : 
   14701                 :      603012 :   switch (GET_CODE (operands[3]))
   14702                 :             :     {
   14703                 :             :     case PLUS:
   14704                 :             :       p = "add"; break;
   14705                 :             :     case MINUS:
   14706                 :             :       p = "sub"; break;
   14707                 :       95027 :     case MULT:
   14708                 :       95027 :       p = "mul"; break;
   14709                 :       25982 :     case DIV:
   14710                 :       25982 :       p = "div"; break;
   14711                 :           0 :     default:
   14712                 :           0 :       gcc_unreachable ();
   14713                 :             :     }
   14714                 :             : 
   14715                 :      603012 :   strcat (buf, p);
   14716                 :             : 
   14717                 :      603012 :   if (is_sse)
   14718                 :             :    {
   14719                 :      547706 :      p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
   14720                 :      547706 :      strcat (buf, p);
   14721                 :             : 
   14722                 :      547706 :      if (TARGET_AVX)
   14723                 :             :        p = "\t{%2, %1, %0|%0, %1, %2}";
   14724                 :             :      else
   14725                 :      529276 :        p = "\t{%2, %0|%0, %2}";
   14726                 :             : 
   14727                 :      547706 :      strcat (buf, p);
   14728                 :      547706 :      return buf;
   14729                 :             :    }
   14730                 :             : 
   14731                 :             :   /* Even if we do not want to check the inputs, this documents input
   14732                 :             :      constraints.  Which helps in understanding the following code.  */
   14733                 :       55306 :   if (flag_checking)
   14734                 :             :     {
   14735                 :       55305 :       if (STACK_REG_P (operands[0])
   14736                 :       55305 :           && ((REG_P (operands[1])
   14737                 :       53944 :                && REGNO (operands[0]) == REGNO (operands[1])
   14738                 :       49841 :                && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
   14739                 :        5464 :               || (REG_P (operands[2])
   14740                 :        5464 :                   && REGNO (operands[0]) == REGNO (operands[2])
   14741                 :        5464 :                   && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
   14742                 :      110610 :           && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
   14743                 :             :         ; /* ok */
   14744                 :             :       else
   14745                 :           0 :         gcc_unreachable ();
   14746                 :             :     }
   14747                 :             : 
   14748                 :       55306 :   switch (GET_CODE (operands[3]))
   14749                 :             :     {
   14750                 :       40527 :     case MULT:
   14751                 :       40527 :     case PLUS:
   14752                 :       40527 :       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
   14753                 :        1786 :         std::swap (operands[1], operands[2]);
   14754                 :             : 
   14755                 :             :       /* know operands[0] == operands[1].  */
   14756                 :             : 
   14757                 :       40527 :       if (MEM_P (operands[2]))
   14758                 :             :         {
   14759                 :             :           p = "%Z2\t%2";
   14760                 :             :           break;
   14761                 :             :         }
   14762                 :             : 
   14763                 :       36567 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   14764                 :             :         {
   14765                 :       21356 :           if (STACK_TOP_P (operands[0]))
   14766                 :             :             /* How is it that we are storing to a dead operand[2]?
   14767                 :             :                Well, presumably operands[1] is dead too.  We can't
   14768                 :             :                store the result to st(0) as st(0) gets popped on this
   14769                 :             :                instruction.  Instead store to operands[2] (which I
   14770                 :             :                think has to be st(1)).  st(1) will be popped later.
   14771                 :             :                gcc <= 2.8.1 didn't have this check and generated
   14772                 :             :                assembly code that the Unixware assembler rejected.  */
   14773                 :             :             p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
   14774                 :             :           else
   14775                 :             :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   14776                 :             :           break;
   14777                 :             :         }
   14778                 :             : 
   14779                 :       15211 :       if (STACK_TOP_P (operands[0]))
   14780                 :             :         p = "\t{%y2, %0|%0, %y2}";    /* st(0) = st(0) op st(r2) */
   14781                 :             :       else
   14782                 :             :         p = "\t{%2, %0|%0, %2}";      /* st(r1) = st(r1) op st(0) */
   14783                 :             :       break;
   14784                 :             : 
   14785                 :       14779 :     case MINUS:
   14786                 :       14779 :     case DIV:
   14787                 :       14779 :       if (MEM_P (operands[1]))
   14788                 :             :         {
   14789                 :             :           p = "r%Z1\t%1";
   14790                 :             :           break;
   14791                 :             :         }
   14792                 :             : 
   14793                 :       14396 :       if (MEM_P (operands[2]))
   14794                 :             :         {
   14795                 :             :           p = "%Z2\t%2";
   14796                 :             :           break;
   14797                 :             :         }
   14798                 :             : 
   14799                 :       12983 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   14800                 :             :         {
   14801                 :             : #if SYSV386_COMPAT
   14802                 :             :           /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
   14803                 :             :              derived assemblers, confusingly reverse the direction of
   14804                 :             :              the operation for fsub{r} and fdiv{r} when the
   14805                 :             :              destination register is not st(0).  The Intel assembler
   14806                 :             :              doesn't have this brain damage.  Read !SYSV386_COMPAT to
   14807                 :             :              figure out what the hardware really does.  */
   14808                 :        5977 :           if (STACK_TOP_P (operands[0]))
   14809                 :             :             p = "{p\t%0, %2|rp\t%2, %0}";
   14810                 :             :           else
   14811                 :             :             p = "{rp\t%2, %0|p\t%0, %2}";
   14812                 :             : #else
   14813                 :             :           if (STACK_TOP_P (operands[0]))
   14814                 :             :             /* As above for fmul/fadd, we can't store to st(0).  */
   14815                 :             :             p = "rp\t{%0, %2|%2, %0}";        /* st(1) = st(0) op st(1); pop */
   14816                 :             :           else
   14817                 :             :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   14818                 :             : #endif
   14819                 :             :           break;
   14820                 :             :         }
   14821                 :             : 
   14822                 :        7006 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   14823                 :             :         {
   14824                 :             : #if SYSV386_COMPAT
   14825                 :        3098 :           if (STACK_TOP_P (operands[0]))
   14826                 :             :             p = "{rp\t%0, %1|p\t%1, %0}";
   14827                 :             :           else
   14828                 :             :             p = "{p\t%1, %0|rp\t%0, %1}";
   14829                 :             : #else
   14830                 :             :           if (STACK_TOP_P (operands[0]))
   14831                 :             :             p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
   14832                 :             :           else
   14833                 :             :             p = "rp\t{%1, %0|%0, %1}";        /* st(r2) = st(0) op st(r2); pop */
   14834                 :             : #endif
   14835                 :             :           break;
   14836                 :             :         }
   14837                 :             : 
   14838                 :        3908 :       if (STACK_TOP_P (operands[0]))
   14839                 :             :         {
   14840                 :        3028 :           if (STACK_TOP_P (operands[1]))
   14841                 :             :             p = "\t{%y2, %0|%0, %y2}";        /* st(0) = st(0) op st(r2) */
   14842                 :             :           else
   14843                 :             :             p = "r\t{%y1, %0|%0, %y1}";       /* st(0) = st(r1) op st(0) */
   14844                 :             :           break;
   14845                 :             :         }
   14846                 :         880 :       else if (STACK_TOP_P (operands[1]))
   14847                 :             :         {
   14848                 :             : #if SYSV386_COMPAT
   14849                 :             :           p = "{\t%1, %0|r\t%0, %1}";
   14850                 :             : #else
   14851                 :             :           p = "r\t{%1, %0|%0, %1}";   /* st(r2) = st(0) op st(r2) */
   14852                 :             : #endif
   14853                 :             :         }
   14854                 :             :       else
   14855                 :             :         {
   14856                 :             : #if SYSV386_COMPAT
   14857                 :             :           p = "{r\t%2, %0|\t%0, %2}";
   14858                 :             : #else
   14859                 :             :           p = "\t{%2, %0|%0, %2}";    /* st(r1) = st(r1) op st(0) */
   14860                 :             : #endif
   14861                 :             :         }
   14862                 :             :       break;
   14863                 :             : 
   14864                 :           0 :     default:
   14865                 :           0 :       gcc_unreachable ();
   14866                 :             :     }
   14867                 :             : 
   14868                 :       55306 :   strcat (buf, p);
   14869                 :       55306 :   return buf;
   14870                 :             : }
   14871                 :             : 
   14872                 :             : /* Return needed mode for entity in optimize_mode_switching pass.  */
   14873                 :             : 
   14874                 :             : static int
   14875                 :        1637 : ix86_dirflag_mode_needed (rtx_insn *insn)
   14876                 :             : {
   14877                 :        1637 :   if (CALL_P (insn))
   14878                 :             :     {
   14879                 :         337 :       if (cfun->machine->func_type == TYPE_NORMAL)
   14880                 :             :         return X86_DIRFLAG_ANY;
   14881                 :             :       else
   14882                 :             :         /* No need to emit CLD in interrupt handler for TARGET_CLD.  */
   14883                 :         337 :         return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
   14884                 :             :     }
   14885                 :             : 
   14886                 :        1300 :   if (recog_memoized (insn) < 0)
   14887                 :             :     return X86_DIRFLAG_ANY;
   14888                 :             : 
   14889                 :        1298 :   if (get_attr_type (insn) == TYPE_STR)
   14890                 :             :     {
   14891                 :             :       /* Emit cld instruction if stringops are used in the function.  */
   14892                 :           1 :       if (cfun->machine->func_type == TYPE_NORMAL)
   14893                 :           0 :         return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
   14894                 :             :       else
   14895                 :             :         return X86_DIRFLAG_RESET;
   14896                 :             :     }
   14897                 :             : 
   14898                 :             :   return X86_DIRFLAG_ANY;
   14899                 :             : }
   14900                 :             : 
   14901                 :             : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP.   */
   14902                 :             : 
   14903                 :             : static bool
   14904                 :     2128147 : ix86_check_avx_upper_register (const_rtx exp)
   14905                 :             : {
   14906                 :             :   /* construct_container may return a parallel with expr_list
   14907                 :             :      which contains the real reg and mode  */
   14908                 :     2128147 :   subrtx_iterator::array_type array;
   14909                 :     8104395 :   FOR_EACH_SUBRTX (iter, array, exp, NONCONST)
   14910                 :             :     {
   14911                 :     6135149 :       const_rtx x = *iter;
   14912                 :     2471898 :       if (SSE_REG_P (x)
   14913                 :      802733 :           && !EXT_REX_SSE_REG_P (x)
   14914                 :     7729311 :           && GET_MODE_BITSIZE (GET_MODE (x)) > 128)
   14915                 :      158901 :         return true;
   14916                 :             :     }
   14917                 :             : 
   14918                 :     1969246 :   return false;
   14919                 :     2128147 : }
   14920                 :             : 
   14921                 :             : /* Check if a 256bit or 512bit AVX register is referenced in stores.   */
   14922                 :             : 
   14923                 :             : static void
   14924                 :       46793 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
   14925                 :             : {
   14926                 :       46793 :   if (SSE_REG_P (dest)
   14927                 :       12489 :       && !EXT_REX_SSE_REG_P (dest)
   14928                 :       71771 :       && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   14929                 :             :     {
   14930                 :         724 :       bool *used = (bool *) data;
   14931                 :         724 :       *used = true;
   14932                 :             :     }
   14933                 :       46793 : }
   14934                 :             : 
   14935                 :             : /* Return needed mode for entity in optimize_mode_switching pass.  */
   14936                 :             : 
   14937                 :             : static int
   14938                 :     1993082 : ix86_avx_u128_mode_needed (rtx_insn *insn)
   14939                 :             : {
   14940                 :     1993082 :   if (DEBUG_INSN_P (insn))
   14941                 :             :     return AVX_U128_ANY;
   14942                 :             : 
   14943                 :     1993082 :   if (CALL_P (insn))
   14944                 :             :     {
   14945                 :       46263 :       rtx link;
   14946                 :             : 
   14947                 :             :       /* Needed mode is set to AVX_U128_CLEAN if there are
   14948                 :             :          no 256bit or 512bit modes used in function arguments. */
   14949                 :       46263 :       for (link = CALL_INSN_FUNCTION_USAGE (insn);
   14950                 :      116938 :            link;
   14951                 :       70675 :            link = XEXP (link, 1))
   14952                 :             :         {
   14953                 :       71712 :           if (GET_CODE (XEXP (link, 0)) == USE)
   14954                 :             :             {
   14955                 :       70775 :               rtx arg = XEXP (XEXP (link, 0), 0);
   14956                 :             : 
   14957                 :       70775 :               if (ix86_check_avx_upper_register (arg))
   14958                 :             :                 return AVX_U128_DIRTY;
   14959                 :             :             }
   14960                 :             :         }
   14961                 :             : 
   14962                 :             :       /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
   14963                 :             :          nor 512bit registers used in the function return register.  */
   14964                 :       45226 :       bool avx_upper_reg_found = false;
   14965                 :       45226 :       note_stores (insn, ix86_check_avx_upper_stores,
   14966                 :             :                    &avx_upper_reg_found);
   14967                 :       45226 :       if (avx_upper_reg_found)
   14968                 :             :         return AVX_U128_DIRTY;
   14969                 :             : 
   14970                 :             :       /* If the function is known to preserve some SSE registers,
   14971                 :             :          RA and previous passes can legitimately rely on that for
   14972                 :             :          modes wider than 256 bits.  It's only safe to issue a
   14973                 :             :          vzeroupper if all SSE registers are clobbered.  */
   14974                 :       45055 :       const function_abi &abi = insn_callee_abi (insn);
   14975                 :       45055 :       if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
   14976                 :             :           /* Should be safe to issue an vzeroupper before sibling_call_p.
   14977                 :             :              Also there not mode_exit for sibling_call, so there could be
   14978                 :             :              missing vzeroupper for that.  */
   14979                 :       45055 :           || !(SIBLING_CALL_P (insn)
   14980                 :       43851 :                || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   14981                 :       43851 :                                          abi.mode_clobbers (V4DImode))))
   14982                 :        9289 :         return AVX_U128_ANY;
   14983                 :             : 
   14984                 :       35766 :       return AVX_U128_CLEAN;
   14985                 :             :     }
   14986                 :             : 
   14987                 :     1946819 :   rtx set = single_set (insn);
   14988                 :     1946819 :   if (set)
   14989                 :             :     {
   14990                 :     1876054 :       rtx dest = SET_DEST (set);
   14991                 :     1876054 :       rtx src = SET_SRC (set);
   14992                 :     1418425 :       if (SSE_REG_P (dest)
   14993                 :      536606 :           && !EXT_REX_SSE_REG_P (dest)
   14994                 :     2938302 :           && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   14995                 :             :         {
   14996                 :             :           /* This is an YMM/ZMM load.  Return AVX_U128_DIRTY if the
   14997                 :             :              source isn't zero.  */
   14998                 :      166540 :           if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
   14999                 :             :             return AVX_U128_DIRTY;
   15000                 :             :           else
   15001                 :             :             return AVX_U128_ANY;
   15002                 :             :         }
   15003                 :             :       else
   15004                 :             :         {
   15005                 :     1709514 :           if (ix86_check_avx_upper_register (src))
   15006                 :             :             return AVX_U128_DIRTY;
   15007                 :             :         }
   15008                 :             : 
   15009                 :             :       /* This isn't YMM/ZMM load/store.  */
   15010                 :             :       return AVX_U128_ANY;
   15011                 :             :     }
   15012                 :             : 
   15013                 :             :   /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
   15014                 :             :      Hardware changes state only when a 256bit register is written to,
   15015                 :             :      but we need to prevent the compiler from moving optimal insertion
   15016                 :             :      point above eventual read from 256bit or 512 bit register.  */
   15017                 :       70765 :   if (ix86_check_avx_upper_register (PATTERN (insn)))
   15018                 :             :     return AVX_U128_DIRTY;
   15019                 :             : 
   15020                 :             :   return AVX_U128_ANY;
   15021                 :             : }
   15022                 :             : 
   15023                 :             : /* Return mode that i387 must be switched into
   15024                 :             :    prior to the execution of insn.  */
   15025                 :             : 
   15026                 :             : static int
   15027                 :      467268 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
   15028                 :             : {
   15029                 :      467268 :   enum attr_i387_cw mode;
   15030                 :             : 
   15031                 :             :   /* The mode UNINITIALIZED is used to store control word after a
   15032                 :             :      function call or ASM pattern.  The mode ANY specify that function
   15033                 :             :      has no requirements on the control word and make no changes in the
   15034                 :             :      bits we are interested in.  */
   15035                 :             : 
   15036                 :      467268 :   if (CALL_P (insn)
   15037                 :      467268 :       || (NONJUMP_INSN_P (insn)
   15038                 :      383629 :           && (asm_noperands (PATTERN (insn)) >= 0
   15039                 :      383629 :               || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
   15040                 :       17228 :     return I387_CW_UNINITIALIZED;
   15041                 :             : 
   15042                 :      450040 :   if (recog_memoized (insn) < 0)
   15043                 :             :     return I387_CW_ANY;
   15044                 :             : 
   15045                 :      449076 :   mode = get_attr_i387_cw (insn);
   15046                 :             : 
   15047                 :      449076 :   switch (entity)
   15048                 :             :     {
   15049                 :           0 :     case I387_ROUNDEVEN:
   15050                 :           0 :       if (mode == I387_CW_ROUNDEVEN)
   15051                 :             :         return mode;
   15052                 :             :       break;
   15053                 :             : 
   15054                 :      443106 :     case I387_TRUNC:
   15055                 :      443106 :       if (mode == I387_CW_TRUNC)
   15056                 :             :         return mode;
   15057                 :             :       break;
   15058                 :             : 
   15059                 :        4560 :     case I387_FLOOR:
   15060                 :        4560 :       if (mode == I387_CW_FLOOR)
   15061                 :             :         return mode;
   15062                 :             :       break;
   15063                 :             : 
   15064                 :        1410 :     case I387_CEIL:
   15065                 :        1410 :       if (mode == I387_CW_CEIL)
   15066                 :             :         return mode;
   15067                 :             :       break;
   15068                 :             : 
   15069                 :           0 :     default:
   15070                 :           0 :       gcc_unreachable ();
   15071                 :             :     }
   15072                 :             : 
   15073                 :             :   return I387_CW_ANY;
   15074                 :             : }
   15075                 :             : 
   15076                 :             : /* Return mode that entity must be switched into
   15077                 :             :    prior to the execution of insn.  */
   15078                 :             : 
   15079                 :             : static int
   15080                 :     2461987 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
   15081                 :             : {
   15082                 :     2461987 :   switch (entity)
   15083                 :             :     {
   15084                 :        1637 :     case X86_DIRFLAG:
   15085                 :        1637 :       return ix86_dirflag_mode_needed (insn);
   15086                 :     1993082 :     case AVX_U128:
   15087                 :     1993082 :       return ix86_avx_u128_mode_needed (insn);
   15088                 :      467268 :     case I387_ROUNDEVEN:
   15089                 :      467268 :     case I387_TRUNC:
   15090                 :      467268 :     case I387_FLOOR:
   15091                 :      467268 :     case I387_CEIL:
   15092                 :      467268 :       return ix86_i387_mode_needed (entity, insn);
   15093                 :           0 :     default:
   15094                 :           0 :       gcc_unreachable ();
   15095                 :             :     }
   15096                 :             :   return 0;
   15097                 :             : }
   15098                 :             : 
   15099                 :             : /* Calculate mode of upper 128bit AVX registers after the insn.  */
   15100                 :             : 
   15101                 :             : static int
   15102                 :     1993082 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
   15103                 :             : {
   15104                 :     1993082 :   rtx pat = PATTERN (insn);
   15105                 :             : 
   15106                 :     1993082 :   if (vzeroupper_pattern (pat, VOIDmode)
   15107                 :     1993082 :       || vzeroall_pattern (pat, VOIDmode))
   15108                 :         217 :     return AVX_U128_CLEAN;
   15109                 :             : 
   15110                 :             :   /* We know that state is clean after CALL insn if there are no
   15111                 :             :      256bit or 512bit registers used in the function return register. */
   15112                 :     1992865 :   if (CALL_P (insn))
   15113                 :             :     {
   15114                 :       46217 :       bool avx_upper_reg_found = false;
   15115                 :       46217 :       note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
   15116                 :             : 
   15117                 :       46217 :       if (avx_upper_reg_found)
   15118                 :             :         return AVX_U128_DIRTY;
   15119                 :             : 
   15120                 :             :       /* If the function desn't clobber any sse registers or only clobber
   15121                 :             :          128-bit part, Then vzeroupper isn't issued before the function exit.
   15122                 :             :          the status not CLEAN but ANY after the function.  */
   15123                 :       45664 :       const function_abi &abi = insn_callee_abi (insn);
   15124                 :       45664 :       if (!(SIBLING_CALL_P (insn)
   15125                 :       44465 :             || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15126                 :       44465 :                                       abi.mode_clobbers (V4DImode))))
   15127                 :        9584 :         return AVX_U128_ANY;
   15128                 :             : 
   15129                 :       36080 :       return  AVX_U128_CLEAN;
   15130                 :             :     }
   15131                 :             : 
   15132                 :             :   /* Otherwise, return current mode.  Remember that if insn
   15133                 :             :      references AVX 256bit or 512bit registers, the mode was already
   15134                 :             :      changed to DIRTY from MODE_NEEDED.  */
   15135                 :             :   return mode;
   15136                 :             : }
   15137                 :             : 
   15138                 :             : /* Return the mode that an insn results in.  */
   15139                 :             : 
   15140                 :             : static int
   15141                 :     2461127 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
   15142                 :             : {
   15143                 :     2461127 :   switch (entity)
   15144                 :             :     {
   15145                 :             :     case X86_DIRFLAG:
   15146                 :             :       return mode;
   15147                 :     1993082 :     case AVX_U128:
   15148                 :     1993082 :       return ix86_avx_u128_mode_after (mode, insn);
   15149                 :             :     case I387_ROUNDEVEN:
   15150                 :             :     case I387_TRUNC:
   15151                 :             :     case I387_FLOOR:
   15152                 :             :     case I387_CEIL:
   15153                 :             :       return mode;
   15154                 :           0 :     default:
   15155                 :           0 :       gcc_unreachable ();
   15156                 :             :     }
   15157                 :             : }
   15158                 :             : 
   15159                 :             : static int
   15160                 :         118 : ix86_dirflag_mode_entry (void)
   15161                 :             : {
   15162                 :             :   /* For TARGET_CLD or in the interrupt handler we can't assume
   15163                 :             :      direction flag state at function entry.  */
   15164                 :         118 :   if (TARGET_CLD
   15165                 :         116 :       || cfun->machine->func_type != TYPE_NORMAL)
   15166                 :         118 :     return X86_DIRFLAG_ANY;
   15167                 :             : 
   15168                 :             :   return X86_DIRFLAG_RESET;
   15169                 :             : }
   15170                 :             : 
   15171                 :             : static int
   15172                 :      121493 : ix86_avx_u128_mode_entry (void)
   15173                 :             : {
   15174                 :      121493 :   tree arg;
   15175                 :             : 
   15176                 :             :   /* Entry mode is set to AVX_U128_DIRTY if there are
   15177                 :             :      256bit or 512bit modes used in function arguments.  */
   15178                 :      303890 :   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
   15179                 :      182397 :        arg = TREE_CHAIN (arg))
   15180                 :             :     {
   15181                 :      218255 :       rtx incoming = DECL_INCOMING_RTL (arg);
   15182                 :             : 
   15183                 :      218255 :       if (incoming && ix86_check_avx_upper_register (incoming))
   15184                 :             :         return AVX_U128_DIRTY;
   15185                 :             :     }
   15186                 :             : 
   15187                 :             :   return AVX_U128_CLEAN;
   15188                 :             : }
   15189                 :             : 
   15190                 :             : /* Return a mode that ENTITY is assumed to be
   15191                 :             :    switched to at function entry.  */
   15192                 :             : 
   15193                 :             : static int
   15194                 :       75874 : ix86_mode_entry (int entity)
   15195                 :             : {
   15196                 :       75874 :   switch (entity)
   15197                 :             :     {
   15198                 :         118 :     case X86_DIRFLAG:
   15199                 :         118 :       return ix86_dirflag_mode_entry ();
   15200                 :       74600 :     case AVX_U128:
   15201                 :       74600 :       return ix86_avx_u128_mode_entry ();
   15202                 :             :     case I387_ROUNDEVEN:
   15203                 :             :     case I387_TRUNC:
   15204                 :             :     case I387_FLOOR:
   15205                 :             :     case I387_CEIL:
   15206                 :             :       return I387_CW_ANY;
   15207                 :           0 :     default:
   15208                 :           0 :       gcc_unreachable ();
   15209                 :             :     }
   15210                 :             : }
   15211                 :             : 
   15212                 :             : static int
   15213                 :       73414 : ix86_avx_u128_mode_exit (void)
   15214                 :             : {
   15215                 :       73414 :   rtx reg = crtl->return_rtx;
   15216                 :             : 
   15217                 :             :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
   15218                 :             :      or 512 bit modes used in the function return register. */
   15219                 :       73414 :   if (reg && ix86_check_avx_upper_register (reg))
   15220                 :             :     return AVX_U128_DIRTY;
   15221                 :             : 
   15222                 :             :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
   15223                 :             :      modes used in function arguments, otherwise return AVX_U128_CLEAN.
   15224                 :             :    */
   15225                 :       46893 :   return ix86_avx_u128_mode_entry ();
   15226                 :             : }
   15227                 :             : 
   15228                 :             : /* Return a mode that ENTITY is assumed to be
   15229                 :             :    switched to at function exit.  */
   15230                 :             : 
   15231                 :             : static int
   15232                 :       74547 : ix86_mode_exit (int entity)
   15233                 :             : {
   15234                 :       74547 :   switch (entity)
   15235                 :             :     {
   15236                 :             :     case X86_DIRFLAG:
   15237                 :             :       return X86_DIRFLAG_ANY;
   15238                 :       73414 :     case AVX_U128:
   15239                 :       73414 :       return ix86_avx_u128_mode_exit ();
   15240                 :        1101 :     case I387_ROUNDEVEN:
   15241                 :        1101 :     case I387_TRUNC:
   15242                 :        1101 :     case I387_FLOOR:
   15243                 :        1101 :     case I387_CEIL:
   15244                 :        1101 :       return I387_CW_ANY;
   15245                 :           0 :     default:
   15246                 :           0 :       gcc_unreachable ();
   15247                 :             :     }
   15248                 :             : }
   15249                 :             : 
   15250                 :             : static int
   15251                 :     2190170 : ix86_mode_priority (int, int n)
   15252                 :             : {
   15253                 :     2190170 :   return n;
   15254                 :             : }
   15255                 :             : 
   15256                 :             : /* Output code to initialize control word copies used by trunc?f?i and
   15257                 :             :    rounding patterns.  CURRENT_MODE is set to current control word,
   15258                 :             :    while NEW_MODE is set to new control word.  */
   15259                 :             : 
   15260                 :             : static void
   15261                 :        3326 : emit_i387_cw_initialization (int mode)
   15262                 :             : {
   15263                 :        3326 :   rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
   15264                 :        3326 :   rtx new_mode;
   15265                 :             : 
   15266                 :        3326 :   enum ix86_stack_slot slot;
   15267                 :             : 
   15268                 :        3326 :   rtx reg = gen_reg_rtx (HImode);
   15269                 :             : 
   15270                 :        3326 :   emit_insn (gen_x86_fnstcw_1 (stored_mode));
   15271                 :        3326 :   emit_move_insn (reg, copy_rtx (stored_mode));
   15272                 :             : 
   15273                 :        3326 :   switch (mode)
   15274                 :             :     {
   15275                 :           0 :     case I387_CW_ROUNDEVEN:
   15276                 :             :       /* round to nearest */
   15277                 :           0 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15278                 :           0 :       slot = SLOT_CW_ROUNDEVEN;
   15279                 :           0 :       break;
   15280                 :             : 
   15281                 :        3106 :     case I387_CW_TRUNC:
   15282                 :             :       /* round toward zero (truncate) */
   15283                 :        3106 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
   15284                 :        3106 :       slot = SLOT_CW_TRUNC;
   15285                 :        3106 :       break;
   15286                 :             : 
   15287                 :         153 :     case I387_CW_FLOOR:
   15288                 :             :       /* round down toward -oo */
   15289                 :         153 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15290                 :         153 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
   15291                 :         153 :       slot = SLOT_CW_FLOOR;
   15292                 :         153 :       break;
   15293                 :             : 
   15294                 :          67 :     case I387_CW_CEIL:
   15295                 :             :       /* round up toward +oo */
   15296                 :          67 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15297                 :          67 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
   15298                 :          67 :       slot = SLOT_CW_CEIL;
   15299                 :          67 :       break;
   15300                 :             : 
   15301                 :           0 :     default:
   15302                 :           0 :       gcc_unreachable ();
   15303                 :             :     }
   15304                 :             : 
   15305                 :        3326 :   gcc_assert (slot < MAX_386_STACK_LOCALS);
   15306                 :             : 
   15307                 :        3326 :   new_mode = assign_386_stack_local (HImode, slot);
   15308                 :        3326 :   emit_move_insn (new_mode, reg);
   15309                 :        3326 : }
   15310                 :             : 
   15311                 :             : /* Generate one or more insns to set ENTITY to MODE.  */
   15312                 :             : 
   15313                 :             : static void
   15314                 :       45552 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
   15315                 :             :                     HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
   15316                 :             : {
   15317                 :       45552 :   switch (entity)
   15318                 :             :     {
   15319                 :         263 :     case X86_DIRFLAG:
   15320                 :         263 :       if (mode == X86_DIRFLAG_RESET)
   15321                 :         263 :         emit_insn (gen_cld ());
   15322                 :             :       break;
   15323                 :       36461 :     case AVX_U128:
   15324                 :       36461 :       if (mode == AVX_U128_CLEAN)
   15325                 :       17315 :         ix86_expand_avx_vzeroupper ();
   15326                 :             :       break;
   15327                 :        8828 :     case I387_ROUNDEVEN:
   15328                 :        8828 :     case I387_TRUNC:
   15329                 :        8828 :     case I387_FLOOR:
   15330                 :        8828 :     case I387_CEIL:
   15331                 :        8828 :       if (mode != I387_CW_ANY
   15332                 :        8828 :           && mode != I387_CW_UNINITIALIZED)
   15333                 :        3326 :         emit_i387_cw_initialization (mode);
   15334                 :             :       break;
   15335                 :           0 :     default:
   15336                 :           0 :       gcc_unreachable ();
   15337                 :             :     }
   15338                 :       45552 : }
   15339                 :             : 
   15340                 :             : /* Output code for INSN to convert a float to a signed int.  OPERANDS
   15341                 :             :    are the insn operands.  The output may be [HSD]Imode and the input
   15342                 :             :    operand may be [SDX]Fmode.  */
   15343                 :             : 
   15344                 :             : const char *
   15345                 :        7493 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
   15346                 :             : {
   15347                 :        7493 :   bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   15348                 :        7493 :   bool dimode_p = GET_MODE (operands[0]) == DImode;
   15349                 :        7493 :   int round_mode = get_attr_i387_cw (insn);
   15350                 :             : 
   15351                 :        7493 :   static char buf[40];
   15352                 :        7493 :   const char *p;
   15353                 :             : 
   15354                 :             :   /* Jump through a hoop or two for DImode, since the hardware has no
   15355                 :             :      non-popping instruction.  We used to do this a different way, but
   15356                 :             :      that was somewhat fragile and broke with post-reload splitters.  */
   15357                 :        7493 :   if ((dimode_p || fisttp) && !stack_top_dies)
   15358                 :          25 :     output_asm_insn ("fld\t%y1", operands);
   15359                 :             : 
   15360                 :        7493 :   gcc_assert (STACK_TOP_P (operands[1]));
   15361                 :        7493 :   gcc_assert (MEM_P (operands[0]));
   15362                 :        7493 :   gcc_assert (GET_MODE (operands[1]) != TFmode);
   15363                 :             : 
   15364                 :        7493 :   if (fisttp)
   15365                 :             :     return "fisttp%Z0\t%0";
   15366                 :             : 
   15367                 :        7492 :   strcpy (buf, "fist");
   15368                 :             : 
   15369                 :        7492 :   if (round_mode != I387_CW_ANY)
   15370                 :        7444 :     output_asm_insn ("fldcw\t%3", operands);
   15371                 :             : 
   15372                 :        7492 :   p = "p%Z0\t%0";
   15373                 :        7492 :   strcat (buf, p + !(stack_top_dies || dimode_p));
   15374                 :             : 
   15375                 :        7492 :   output_asm_insn (buf, operands);
   15376                 :             : 
   15377                 :        7492 :   if (round_mode != I387_CW_ANY)
   15378                 :        7444 :     output_asm_insn ("fldcw\t%2", operands);
   15379                 :             : 
   15380                 :             :   return "";
   15381                 :             : }
   15382                 :             : 
   15383                 :             : /* Output code for x87 ffreep insn.  The OPNO argument, which may only
   15384                 :             :    have the values zero or one, indicates the ffreep insn's operand
   15385                 :             :    from the OPERANDS array.  */
   15386                 :             : 
   15387                 :             : static const char *
   15388                 :      281030 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
   15389                 :             : {
   15390                 :           0 :   if (TARGET_USE_FFREEP)
   15391                 :             : #ifdef HAVE_AS_IX86_FFREEP
   15392                 :           0 :     return opno ? "ffreep\t%y1" : "ffreep\t%y0";
   15393                 :             : #else
   15394                 :             :     {
   15395                 :             :       static char retval[32];
   15396                 :             :       int regno = REGNO (operands[opno]);
   15397                 :             : 
   15398                 :             :       gcc_assert (STACK_REGNO_P (regno));
   15399                 :             : 
   15400                 :             :       regno -= FIRST_STACK_REG;
   15401                 :             : 
   15402                 :             :       snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
   15403                 :             :       return retval;
   15404                 :             :     }
   15405                 :             : #endif
   15406                 :             : 
   15407                 :           0 :   return opno ? "fstp\t%y1" : "fstp\t%y0";
   15408                 :             : }
   15409                 :             : 
   15410                 :             : 
   15411                 :             : /* Output code for INSN to compare OPERANDS.  EFLAGS_P is 1 when fcomi
   15412                 :             :    should be used.  UNORDERED_P is true when fucom should be used.  */
   15413                 :             : 
   15414                 :             : const char *
   15415                 :      107654 : output_fp_compare (rtx_insn *insn, rtx *operands,
   15416                 :             :                    bool eflags_p, bool unordered_p)
   15417                 :             : {
   15418                 :      107654 :   rtx *xops = eflags_p ? &operands[0] : &operands[1];
   15419                 :      107654 :   bool stack_top_dies;
   15420                 :             : 
   15421                 :      107654 :   static char buf[40];
   15422                 :      107654 :   const char *p;
   15423                 :             : 
   15424                 :      107654 :   gcc_assert (STACK_TOP_P (xops[0]));
   15425                 :             : 
   15426                 :      107654 :   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   15427                 :             : 
   15428                 :      107654 :   if (eflags_p)
   15429                 :             :     {
   15430                 :      107654 :       p = unordered_p ? "fucomi" : "fcomi";
   15431                 :      107654 :       strcpy (buf, p);
   15432                 :             : 
   15433                 :      107654 :       p = "p\t{%y1, %0|%0, %y1}";
   15434                 :      107654 :       strcat (buf, p + !stack_top_dies);
   15435                 :             : 
   15436                 :      107654 :       return buf;
   15437                 :             :     }
   15438                 :             : 
   15439                 :           0 :   if (STACK_REG_P (xops[1])
   15440                 :           0 :       && stack_top_dies
   15441                 :           0 :       && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
   15442                 :             :     {
   15443                 :           0 :       gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
   15444                 :             : 
   15445                 :             :       /* If both the top of the 387 stack die, and the other operand
   15446                 :             :          is also a stack register that dies, then this must be a
   15447                 :             :          `fcompp' float compare.  */
   15448                 :           0 :       p = unordered_p ? "fucompp" : "fcompp";
   15449                 :           0 :       strcpy (buf, p);
   15450                 :             :     }
   15451                 :           0 :   else if (const0_operand (xops[1], VOIDmode))
   15452                 :             :     {
   15453                 :           0 :       gcc_assert (!unordered_p);
   15454                 :           0 :       strcpy (buf, "ftst");
   15455                 :             :     }
   15456                 :             :   else
   15457                 :             :     {
   15458                 :           0 :       if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
   15459                 :             :         {
   15460                 :           0 :           gcc_assert (!unordered_p);
   15461                 :             :           p = "ficom";
   15462                 :             :         }
   15463                 :             :       else
   15464                 :           0 :         p = unordered_p ? "fucom" : "fcom";
   15465                 :             : 
   15466                 :           0 :       strcpy (buf, p);
   15467                 :             : 
   15468                 :           0 :       p = "p%Z2\t%y2";
   15469                 :           0 :       strcat (buf, p + !stack_top_dies);
   15470                 :             :     }
   15471                 :             : 
   15472                 :           0 :   output_asm_insn (buf, operands);
   15473                 :           0 :   return "fnstsw\t%0";
   15474                 :             : }
   15475                 :             : 
   15476                 :             : void
   15477                 :      142860 : ix86_output_addr_vec_elt (FILE *file, int value)
   15478                 :             : {
   15479                 :      142860 :   const char *directive = ASM_LONG;
   15480                 :             : 
   15481                 :             : #ifdef ASM_QUAD
   15482                 :      142860 :   if (TARGET_LP64)
   15483                 :      129850 :     directive = ASM_QUAD;
   15484                 :             : #else
   15485                 :             :   gcc_assert (!TARGET_64BIT);
   15486                 :             : #endif
   15487                 :             : 
   15488                 :      142860 :   fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
   15489                 :      142860 : }
   15490                 :             : 
   15491                 :             : void
   15492                 :       25233 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
   15493                 :             : {
   15494                 :       25233 :   const char *directive = ASM_LONG;
   15495                 :             : 
   15496                 :             : #ifdef ASM_QUAD
   15497                 :       37393 :   if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
   15498                 :             :     directive = ASM_QUAD;
   15499                 :             : #else
   15500                 :             :   gcc_assert (!TARGET_64BIT);
   15501                 :             : #endif
   15502                 :             :   /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand.  */
   15503                 :       25233 :   if (TARGET_64BIT || TARGET_VXWORKS_RTP)
   15504                 :       12160 :     fprintf (file, "%s%s%d-%s%d\n",
   15505                 :             :              directive, LPREFIX, value, LPREFIX, rel);
   15506                 :             : #if TARGET_MACHO
   15507                 :             :   else if (TARGET_MACHO)
   15508                 :             :     {
   15509                 :             :       fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
   15510                 :             :       machopic_output_function_base_name (file);
   15511                 :             :       putc ('\n', file);
   15512                 :             :     }
   15513                 :             : #endif
   15514                 :       13073 :   else if (HAVE_AS_GOTOFF_IN_DATA)
   15515                 :       13073 :     fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
   15516                 :             :   else
   15517                 :             :     asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
   15518                 :             :                  GOT_SYMBOL_NAME, LPREFIX, value);
   15519                 :       25233 : }
   15520                 :             : 
   15521                 :             : #define LEA_MAX_STALL (3)
   15522                 :             : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
   15523                 :             : 
   15524                 :             : /* Increase given DISTANCE in half-cycles according to
   15525                 :             :    dependencies between PREV and NEXT instructions.
   15526                 :             :    Add 1 half-cycle if there is no dependency and
   15527                 :             :    go to next cycle if there is some dependecy.  */
   15528                 :             : 
   15529                 :             : static unsigned int
   15530                 :        2257 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
   15531                 :             : {
   15532                 :        2257 :   df_ref def, use;
   15533                 :             : 
   15534                 :        2257 :   if (!prev || !next)
   15535                 :         824 :     return distance + (distance & 1) + 2;
   15536                 :             : 
   15537                 :        1433 :   if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
   15538                 :         257 :     return distance + 1;
   15539                 :             : 
   15540                 :        1958 :   FOR_EACH_INSN_USE (use, next)
   15541                 :        2484 :     FOR_EACH_INSN_DEF (def, prev)
   15542                 :        1702 :       if (!DF_REF_IS_ARTIFICIAL (def)
   15543                 :        1702 :           && DF_REF_REGNO (use) == DF_REF_REGNO (def))
   15544                 :         744 :         return distance + (distance & 1) + 2;
   15545                 :             : 
   15546                 :         432 :   return distance + 1;
   15547                 :             : }
   15548                 :             : 
   15549                 :             : /* Function checks if instruction INSN defines register number
   15550                 :             :    REGNO1 or REGNO2.  */
   15551                 :             : 
   15552                 :             : bool
   15553                 :        2211 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
   15554                 :             :                   rtx_insn *insn)
   15555                 :             : {
   15556                 :        2211 :   df_ref def;
   15557                 :             : 
   15558                 :        3960 :   FOR_EACH_INSN_DEF (def, insn)
   15559                 :        2154 :     if (DF_REF_REG_DEF_P (def)
   15560                 :        2154 :         && !DF_REF_IS_ARTIFICIAL (def)
   15561                 :        2154 :         && (regno1 == DF_REF_REGNO (def)
   15562                 :        1765 :             || regno2 == DF_REF_REGNO (def)))
   15563                 :             :       return true;
   15564                 :             : 
   15565                 :             :   return false;
   15566                 :             : }
   15567                 :             : 
   15568                 :             : /* Function checks if instruction INSN uses register number
   15569                 :             :    REGNO as a part of address expression.  */
   15570                 :             : 
   15571                 :             : static bool
   15572                 :        1229 : insn_uses_reg_mem (unsigned int regno, rtx insn)
   15573                 :             : {
   15574                 :        1229 :   df_ref use;
   15575                 :             : 
   15576                 :        2606 :   FOR_EACH_INSN_USE (use, insn)
   15577                 :        1458 :     if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
   15578                 :             :       return true;
   15579                 :             : 
   15580                 :             :   return false;
   15581                 :             : }
   15582                 :             : 
   15583                 :             : /* Search backward for non-agu definition of register number REGNO1
   15584                 :             :    or register number REGNO2 in basic block starting from instruction
   15585                 :             :    START up to head of basic block or instruction INSN.
   15586                 :             : 
   15587                 :             :    Function puts true value into *FOUND var if definition was found
   15588                 :             :    and false otherwise.
   15589                 :             : 
   15590                 :             :    Distance in half-cycles between START and found instruction or head
   15591                 :             :    of BB is added to DISTANCE and returned.  */
   15592                 :             : 
   15593                 :             : static int
   15594                 :         656 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
   15595                 :             :                                rtx_insn *insn, int distance,
   15596                 :             :                                rtx_insn *start, bool *found)
   15597                 :             : {
   15598                 :         656 :   basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
   15599                 :         656 :   rtx_insn *prev = start;
   15600                 :         656 :   rtx_insn *next = NULL;
   15601                 :             : 
   15602                 :         656 :   *found = false;
   15603                 :             : 
   15604                 :         656 :   while (prev
   15605                 :        2008 :          && prev != insn
   15606                 :        2008 :          && distance < LEA_SEARCH_THRESHOLD)
   15607                 :             :     {
   15608                 :        1788 :       if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
   15609                 :             :         {
   15610                 :        1028 :           distance = increase_distance (prev, next, distance);
   15611                 :        1028 :           if (insn_defines_reg (regno1, regno2, prev))
   15612                 :             :             {
   15613                 :         242 :               if (recog_memoized (prev) < 0
   15614                 :         242 :                   || get_attr_type (prev) != TYPE_LEA)
   15615                 :             :                 {
   15616                 :         207 :                   *found = true;
   15617                 :         207 :                   return distance;
   15618                 :             :                 }
   15619                 :             :             }
   15620                 :             : 
   15621                 :             :           next = prev;
   15622                 :             :         }
   15623                 :        1581 :       if (prev == BB_HEAD (bb))
   15624                 :             :         break;
   15625                 :             : 
   15626                 :        1352 :       prev = PREV_INSN (prev);
   15627                 :             :     }
   15628                 :             : 
   15629                 :             :   return distance;
   15630                 :             : }
   15631                 :             : 
   15632                 :             : /* Search backward for non-agu definition of register number REGNO1
   15633                 :             :    or register number REGNO2 in INSN's basic block until
   15634                 :             :    1. Pass LEA_SEARCH_THRESHOLD instructions, or
   15635                 :             :    2. Reach neighbor BBs boundary, or
   15636                 :             :    3. Reach agu definition.
   15637                 :             :    Returns the distance between the non-agu definition point and INSN.
   15638                 :             :    If no definition point, returns -1.  */
   15639                 :             : 
   15640                 :             : static int
   15641                 :         451 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
   15642                 :             :                          rtx_insn *insn)
   15643                 :             : {
   15644                 :         451 :   basic_block bb = BLOCK_FOR_INSN (insn);
   15645                 :         451 :   int distance = 0;
   15646                 :         451 :   bool found = false;
   15647                 :             : 
   15648                 :         451 :   if (insn != BB_HEAD (bb))
   15649                 :         451 :     distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
   15650                 :             :                                               distance, PREV_INSN (insn),
   15651                 :             :                                               &found);
   15652                 :             : 
   15653                 :         451 :   if (!found && distance < LEA_SEARCH_THRESHOLD)
   15654                 :             :     {
   15655                 :         172 :       edge e;
   15656                 :         172 :       edge_iterator ei;
   15657                 :         172 :       bool simple_loop = false;
   15658                 :             : 
   15659                 :         351 :       FOR_EACH_EDGE (e, ei, bb->preds)
   15660                 :         221 :         if (e->src == bb)
   15661                 :             :           {
   15662                 :             :             simple_loop = true;
   15663                 :             :             break;
   15664                 :             :           }
   15665                 :             : 
   15666                 :         172 :       if (simple_loop)
   15667                 :          42 :         distance = distance_non_agu_define_in_bb (regno1, regno2,
   15668                 :             :                                                   insn, distance,
   15669                 :          42 :                                                   BB_END (bb), &found);
   15670                 :             :       else
   15671                 :             :         {
   15672                 :         130 :           int shortest_dist = -1;
   15673                 :         130 :           bool found_in_bb = false;
   15674                 :             : 
   15675                 :         293 :           FOR_EACH_EDGE (e, ei, bb->preds)
   15676                 :             :             {
   15677                 :         163 :               int bb_dist
   15678                 :         326 :                 = distance_non_agu_define_in_bb (regno1, regno2,
   15679                 :             :                                                  insn, distance,
   15680                 :         163 :                                                  BB_END (e->src),
   15681                 :             :                                                  &found_in_bb);
   15682                 :         163 :               if (found_in_bb)
   15683                 :             :                 {
   15684                 :          20 :                   if (shortest_dist < 0)
   15685                 :             :                     shortest_dist = bb_dist;
   15686                 :           0 :                   else if (bb_dist > 0)
   15687                 :           0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   15688                 :             : 
   15689                 :          20 :                   found = true;
   15690                 :             :                 }
   15691                 :             :             }
   15692                 :             : 
   15693                 :         130 :           distance = shortest_dist;
   15694                 :             :         }
   15695                 :             :     }
   15696                 :             : 
   15697                 :         451 :   if (!found)
   15698                 :             :     return -1;
   15699                 :             : 
   15700                 :         207 :   return distance >> 1;
   15701                 :             : }
   15702                 :             : 
   15703                 :             : /* Return the distance in half-cycles between INSN and the next
   15704                 :             :    insn that uses register number REGNO in memory address added
   15705                 :             :    to DISTANCE.  Return -1 if REGNO0 is set.
   15706                 :             : 
   15707                 :             :    Put true value into *FOUND if register usage was found and
   15708                 :             :    false otherwise.
   15709                 :             :    Put true value into *REDEFINED if register redefinition was
   15710                 :             :    found and false otherwise.  */
   15711                 :             : 
   15712                 :             : static int
   15713                 :         809 : distance_agu_use_in_bb (unsigned int regno,
   15714                 :             :                         rtx_insn *insn, int distance, rtx_insn *start,
   15715                 :             :                         bool *found, bool *redefined)
   15716                 :             : {
   15717                 :         809 :   basic_block bb = NULL;
   15718                 :         809 :   rtx_insn *next = start;
   15719                 :         809 :   rtx_insn *prev = NULL;
   15720                 :             : 
   15721                 :         809 :   *found = false;
   15722                 :         809 :   *redefined = false;
   15723                 :             : 
   15724                 :         809 :   if (start != NULL_RTX)
   15725                 :             :     {
   15726                 :         792 :       bb = BLOCK_FOR_INSN (start);
   15727                 :         792 :       if (start != BB_HEAD (bb))
   15728                 :             :         /* If insn and start belong to the same bb, set prev to insn,
   15729                 :             :            so the call to increase_distance will increase the distance
   15730                 :             :            between insns by 1.  */
   15731                 :         422 :         prev = insn;
   15732                 :             :     }
   15733                 :             : 
   15734                 :        2718 :   while (next
   15735                 :        2718 :          && next != insn
   15736                 :        2718 :          && distance < LEA_SEARCH_THRESHOLD)
   15737                 :             :     {
   15738                 :        2512 :       if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
   15739                 :             :         {
   15740                 :        1229 :           distance = increase_distance(prev, next, distance);
   15741                 :        1229 :           if (insn_uses_reg_mem (regno, next))
   15742                 :             :             {
   15743                 :             :               /* Return DISTANCE if OP0 is used in memory
   15744                 :             :                  address in NEXT.  */
   15745                 :          81 :               *found = true;
   15746                 :          81 :               return distance;
   15747                 :             :             }
   15748                 :             : 
   15749                 :        1148 :           if (insn_defines_reg (regno, INVALID_REGNUM, next))
   15750                 :             :             {
   15751                 :             :               /* Return -1 if OP0 is set in NEXT.  */
   15752                 :         158 :               *redefined = true;
   15753                 :         158 :               return -1;
   15754                 :             :             }
   15755                 :             : 
   15756                 :             :           prev = next;
   15757                 :             :         }
   15758                 :             : 
   15759                 :        2273 :       if (next == BB_END (bb))
   15760                 :             :         break;
   15761                 :             : 
   15762                 :        1909 :       next = NEXT_INSN (next);
   15763                 :             :     }
   15764                 :             : 
   15765                 :             :   return distance;
   15766                 :             : }
   15767                 :             : 
   15768                 :             : /* Return the distance between INSN and the next insn that uses
   15769                 :             :    register number REGNO0 in memory address.  Return -1 if no such
   15770                 :             :    a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set.  */
   15771                 :             : 
   15772                 :             : static int
   15773                 :         451 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
   15774                 :             : {
   15775                 :         451 :   basic_block bb = BLOCK_FOR_INSN (insn);
   15776                 :         451 :   int distance = 0;
   15777                 :         451 :   bool found = false;
   15778                 :         451 :   bool redefined = false;
   15779                 :             : 
   15780                 :         451 :   if (insn != BB_END (bb))
   15781                 :         422 :     distance = distance_agu_use_in_bb (regno0, insn, distance,
   15782                 :             :                                        NEXT_INSN (insn),
   15783                 :             :                                        &found, &redefined);
   15784                 :             : 
   15785                 :         451 :   if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
   15786                 :             :     {
   15787                 :         276 :       edge e;
   15788                 :         276 :       edge_iterator ei;
   15789                 :         276 :       bool simple_loop = false;
   15790                 :             : 
   15791                 :         587 :       FOR_EACH_EDGE (e, ei, bb->succs)
   15792                 :         387 :         if (e->dest == bb)
   15793                 :             :           {
   15794                 :             :             simple_loop = true;
   15795                 :             :             break;
   15796                 :             :           }
   15797                 :             : 
   15798                 :         276 :       if (simple_loop)
   15799                 :          76 :         distance = distance_agu_use_in_bb (regno0, insn,
   15800                 :             :                                            distance, BB_HEAD (bb),
   15801                 :             :                                            &found, &redefined);
   15802                 :             :       else
   15803                 :             :         {
   15804                 :         200 :           int shortest_dist = -1;
   15805                 :         200 :           bool found_in_bb = false;
   15806                 :         200 :           bool redefined_in_bb = false;
   15807                 :             : 
   15808                 :         511 :           FOR_EACH_EDGE (e, ei, bb->succs)
   15809                 :             :             {
   15810                 :         311 :               int bb_dist
   15811                 :         622 :                 = distance_agu_use_in_bb (regno0, insn,
   15812                 :         311 :                                           distance, BB_HEAD (e->dest),
   15813                 :             :                                           &found_in_bb, &redefined_in_bb);
   15814                 :         311 :               if (found_in_bb)
   15815                 :             :                 {
   15816                 :          16 :                   if (shortest_dist < 0)
   15817                 :             :                     shortest_dist = bb_dist;
   15818                 :           2 :                   else if (bb_dist > 0)
   15819                 :           2 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   15820                 :             : 
   15821                 :          16 :                   found = true;
   15822                 :             :                 }
   15823                 :             :             }
   15824                 :             : 
   15825                 :         200 :           distance = shortest_dist;
   15826                 :             :         }
   15827                 :             :     }
   15828                 :             : 
   15829                 :         451 :   if (!found || redefined)
   15830                 :             :     return -1;
   15831                 :             : 
   15832                 :          79 :   return distance >> 1;
   15833                 :             : }
   15834                 :             : 
   15835                 :             : /* Define this macro to tune LEA priority vs ADD, it take effect when
   15836                 :             :    there is a dilemma of choosing LEA or ADD
   15837                 :             :    Negative value: ADD is more preferred than LEA
   15838                 :             :    Zero: Neutral
   15839                 :             :    Positive value: LEA is more preferred than ADD.  */
   15840                 :             : #define IX86_LEA_PRIORITY 0
   15841                 :             : 
   15842                 :             : /* Return true if usage of lea INSN has performance advantage
   15843                 :             :    over a sequence of instructions.  Instructions sequence has
   15844                 :             :    SPLIT_COST cycles higher latency than lea latency.  */
   15845                 :             : 
   15846                 :             : static bool
   15847                 :        1589 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
   15848                 :             :                       unsigned int regno2, int split_cost, bool has_scale)
   15849                 :             : {
   15850                 :        1589 :   int dist_define, dist_use;
   15851                 :             : 
   15852                 :             :   /* For Atom processors newer than Bonnell, if using a 2-source or
   15853                 :             :      3-source LEA for non-destructive destination purposes, or due to
   15854                 :             :      wanting ability to use SCALE, the use of LEA is justified.  */
   15855                 :        1589 :   if (!TARGET_CPU_P (BONNELL))
   15856                 :             :     {
   15857                 :        1138 :       if (has_scale)
   15858                 :             :         return true;
   15859                 :        1121 :       if (split_cost < 1)
   15860                 :             :         return false;
   15861                 :         409 :       if (regno0 == regno1 || regno0 == regno2)
   15862                 :             :         return false;
   15863                 :             :       return true;
   15864                 :             :     }
   15865                 :             : 
   15866                 :             :   /* Remember recog_data content.  */
   15867                 :         451 :   struct recog_data_d recog_data_save = recog_data;
   15868                 :             : 
   15869                 :         451 :   dist_define = distance_non_agu_define (regno1, regno2, insn);
   15870                 :         451 :   dist_use = distance_agu_use (regno0, insn);
   15871                 :             : 
   15872                 :             :   /* distance_non_agu_define can call get_attr_type which can call
   15873                 :             :      recog_memoized, restore recog_data back to previous content.  */
   15874                 :         451 :   recog_data = recog_data_save;
   15875                 :             : 
   15876                 :         451 :   if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
   15877                 :             :     {
   15878                 :             :       /* If there is no non AGU operand definition, no AGU
   15879                 :             :          operand usage and split cost is 0 then both lea
   15880                 :             :          and non lea variants have same priority.  Currently
   15881                 :             :          we prefer lea for 64 bit code and non lea on 32 bit
   15882                 :             :          code.  */
   15883                 :         250 :       if (dist_use < 0 && split_cost == 0)
   15884                 :         128 :         return TARGET_64BIT || IX86_LEA_PRIORITY;
   15885                 :             :       else
   15886                 :             :         return true;
   15887                 :             :     }
   15888                 :             : 
   15889                 :             :   /* With longer definitions distance lea is more preferable.
   15890                 :             :      Here we change it to take into account splitting cost and
   15891                 :             :      lea priority.  */
   15892                 :         201 :   dist_define += split_cost + IX86_LEA_PRIORITY;
   15893                 :             : 
   15894                 :             :   /* If there is no use in memory addess then we just check
   15895                 :             :      that split cost exceeds AGU stall.  */
   15896                 :         201 :   if (dist_use < 0)
   15897                 :         198 :     return dist_define > LEA_MAX_STALL;
   15898                 :             : 
   15899                 :             :   /* If this insn has both backward non-agu dependence and forward
   15900                 :             :      agu dependence, the one with short distance takes effect.  */
   15901                 :           3 :   return dist_define >= dist_use;
   15902                 :             : }
   15903                 :             : 
   15904                 :             : /* Return true if we need to split op0 = op1 + op2 into a sequence of
   15905                 :             :    move and add to avoid AGU stalls.  */
   15906                 :             : 
   15907                 :             : bool
   15908                 :     8770467 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
   15909                 :             : {
   15910                 :     8770467 :   unsigned int regno0, regno1, regno2;
   15911                 :             : 
   15912                 :             :   /* Check if we need to optimize.  */
   15913                 :     8770467 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   15914                 :     8769614 :     return false;
   15915                 :             : 
   15916                 :         853 :   regno0 = true_regnum (operands[0]);
   15917                 :         853 :   regno1 = true_regnum (operands[1]);
   15918                 :         853 :   regno2 = true_regnum (operands[2]);
   15919                 :             : 
   15920                 :             :   /* We need to split only adds with non destructive
   15921                 :             :      destination operand.  */
   15922                 :         853 :   if (regno0 == regno1 || regno0 == regno2)
   15923                 :             :     return false;
   15924                 :             :   else
   15925                 :         255 :     return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
   15926                 :             : }
   15927                 :             : 
   15928                 :             : /* Return true if we should emit lea instruction instead of mov
   15929                 :             :    instruction.  */
   15930                 :             : 
   15931                 :             : bool
   15932                 :    27710406 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
   15933                 :             : {
   15934                 :    27710406 :   unsigned int regno0, regno1;
   15935                 :             : 
   15936                 :             :   /* Check if we need to optimize.  */
   15937                 :    27710406 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   15938                 :    27708493 :     return false;
   15939                 :             : 
   15940                 :             :   /* Use lea for reg to reg moves only.  */
   15941                 :        1913 :   if (!REG_P (operands[0]) || !REG_P (operands[1]))
   15942                 :             :     return false;
   15943                 :             : 
   15944                 :         385 :   regno0 = true_regnum (operands[0]);
   15945                 :         385 :   regno1 = true_regnum (operands[1]);
   15946                 :             : 
   15947                 :         385 :   return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
   15948                 :             : }
   15949                 :             : 
   15950                 :             : /* Return true if we need to split lea into a sequence of
   15951                 :             :    instructions to avoid AGU stalls during peephole2. */
   15952                 :             : 
   15953                 :             : bool
   15954                 :    10552463 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
   15955                 :             : {
   15956                 :    10552463 :   unsigned int regno0, regno1, regno2;
   15957                 :    10552463 :   int split_cost;
   15958                 :    10552463 :   struct ix86_address parts;
   15959                 :    10552463 :   int ok;
   15960                 :             : 
   15961                 :             :   /* The "at least two components" test below might not catch simple
   15962                 :             :      move or zero extension insns if parts.base is non-NULL and parts.disp
   15963                 :             :      is const0_rtx as the only components in the address, e.g. if the
   15964                 :             :      register is %rbp or %r13.  As this test is much cheaper and moves or
   15965                 :             :      zero extensions are the common case, do this check first.  */
   15966                 :    10552463 :   if (REG_P (operands[1])
   15967                 :    10552463 :       || (SImode_address_operand (operands[1], VOIDmode)
   15968                 :       96333 :           && REG_P (XEXP (operands[1], 0))))
   15969                 :     3941444 :     return false;
   15970                 :             : 
   15971                 :     6611019 :   ok = ix86_decompose_address (operands[1], &parts);
   15972                 :     6611019 :   gcc_assert (ok);
   15973                 :             : 
   15974                 :             :   /* There should be at least two components in the address.  */
   15975                 :     6611019 :   if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
   15976                 :     6611019 :       + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
   15977                 :             :     return false;
   15978                 :             : 
   15979                 :             :   /* We should not split into add if non legitimate pic
   15980                 :             :      operand is used as displacement. */
   15981                 :     2485885 :   if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
   15982                 :             :     return false;
   15983                 :             : 
   15984                 :     2436886 :   regno0 = true_regnum (operands[0]) ;
   15985                 :     2436886 :   regno1 = INVALID_REGNUM;
   15986                 :     2436886 :   regno2 = INVALID_REGNUM;
   15987                 :             : 
   15988                 :     2436886 :   if (parts.base)
   15989                 :     2374215 :     regno1 = true_regnum (parts.base);
   15990                 :     2436886 :   if (parts.index)
   15991                 :      427515 :     regno2 = true_regnum (parts.index);
   15992                 :             : 
   15993                 :             :   /* Use add for a = a + b and a = b + a since it is faster and shorter
   15994                 :             :      than lea for most processors.  For the processors like BONNELL, if
   15995                 :             :      the destination register of LEA holds an actual address which will
   15996                 :             :      be used soon, LEA is better and otherwise ADD is better.  */
   15997                 :     2436886 :   if (!TARGET_CPU_P (BONNELL)
   15998                 :     2436752 :       && parts.scale == 1
   15999                 :     2220330 :       && (!parts.disp || parts.disp == const0_rtx)
   16000                 :      157204 :       && (regno0 == regno1 || regno0 == regno2))
   16001                 :             :     return true;
   16002                 :             : 
   16003                 :             :   /* Split with -Oz if the encoding requires fewer bytes.  */
   16004                 :     2433059 :   if (optimize_size > 1
   16005                 :          27 :       && parts.scale > 1
   16006                 :           4 :       && !parts.base
   16007                 :           4 :       && (!parts.disp || parts.disp == const0_rtx))
   16008                 :             :     return true;
   16009                 :             : 
   16010                 :             :   /* Check we need to optimize.  */
   16011                 :     2433055 :   if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
   16012                 :     2432719 :     return false;
   16013                 :             : 
   16014                 :         336 :   split_cost = 0;
   16015                 :             : 
   16016                 :             :   /* Compute how many cycles we will add to execution time
   16017                 :             :      if split lea into a sequence of instructions.  */
   16018                 :         336 :   if (parts.base || parts.index)
   16019                 :             :     {
   16020                 :             :       /* Have to use mov instruction if non desctructive
   16021                 :             :          destination form is used.  */
   16022                 :         336 :       if (regno1 != regno0 && regno2 != regno0)
   16023                 :         247 :         split_cost += 1;
   16024                 :             : 
   16025                 :             :       /* Have to add index to base if both exist.  */
   16026                 :         336 :       if (parts.base && parts.index)
   16027                 :          51 :         split_cost += 1;
   16028                 :             : 
   16029                 :             :       /* Have to use shift and adds if scale is 2 or greater.  */
   16030                 :         336 :       if (parts.scale > 1)
   16031                 :             :         {
   16032                 :          24 :           if (regno0 != regno1)
   16033                 :          17 :             split_cost += 1;
   16034                 :           7 :           else if (regno2 == regno0)
   16035                 :           1 :             split_cost += 4;
   16036                 :             :           else
   16037                 :           6 :             split_cost += parts.scale;
   16038                 :             :         }
   16039                 :             : 
   16040                 :             :       /* Have to use add instruction with immediate if
   16041                 :             :          disp is non zero.  */
   16042                 :         336 :       if (parts.disp && parts.disp != const0_rtx)
   16043                 :         283 :         split_cost += 1;
   16044                 :             : 
   16045                 :             :       /* Subtract the price of lea.  */
   16046                 :         336 :       split_cost -= 1;
   16047                 :             :     }
   16048                 :             : 
   16049                 :         336 :   return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
   16050                 :         336 :                                 parts.scale > 1);
   16051                 :             : }
   16052                 :             : 
   16053                 :             : /* Return true if it is ok to optimize an ADD operation to LEA
   16054                 :             :    operation to avoid flag register consumation.  For most processors,
   16055                 :             :    ADD is faster than LEA.  For the processors like BONNELL, if the
   16056                 :             :    destination register of LEA holds an actual address which will be
   16057                 :             :    used soon, LEA is better and otherwise ADD is better.  */
   16058                 :             : 
   16059                 :             : bool
   16060                 :     8825306 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
   16061                 :             : {
   16062                 :     8825306 :   unsigned int regno0 = true_regnum (operands[0]);
   16063                 :     8825306 :   unsigned int regno1 = true_regnum (operands[1]);
   16064                 :     8825306 :   unsigned int regno2 = true_regnum (operands[2]);
   16065                 :             : 
   16066                 :             :   /* If a = b + c, (a!=b && a!=c), must use lea form. */
   16067                 :     8825306 :   if (regno0 != regno1 && regno0 != regno2)
   16068                 :             :     return true;
   16069                 :             : 
   16070                 :     6873244 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16071                 :     6872631 :     return false;
   16072                 :             : 
   16073                 :         613 :   return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
   16074                 :             : }
   16075                 :             : 
   16076                 :             : /* Return true if destination reg of SET_BODY is shift count of
   16077                 :             :    USE_BODY.  */
   16078                 :             : 
   16079                 :             : static bool
   16080                 :         215 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
   16081                 :             : {
   16082                 :         215 :   rtx set_dest;
   16083                 :         215 :   rtx shift_rtx;
   16084                 :         215 :   int i;
   16085                 :             : 
   16086                 :             :   /* Retrieve destination of SET_BODY.  */
   16087                 :         215 :   switch (GET_CODE (set_body))
   16088                 :             :     {
   16089                 :         181 :     case SET:
   16090                 :         181 :       set_dest = SET_DEST (set_body);
   16091                 :         181 :       if (!set_dest || !REG_P (set_dest))
   16092                 :             :         return false;
   16093                 :         180 :       break;
   16094                 :          17 :     case PARALLEL:
   16095                 :          51 :       for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
   16096                 :          34 :         if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
   16097                 :             :                                           use_body))
   16098                 :             :           return true;
   16099                 :             :       /* FALLTHROUGH */
   16100                 :             :     default:
   16101                 :             :       return false;
   16102                 :             :     }
   16103                 :             : 
   16104                 :             :   /* Retrieve shift count of USE_BODY.  */
   16105                 :         180 :   switch (GET_CODE (use_body))
   16106                 :             :     {
   16107                 :          60 :     case SET:
   16108                 :          60 :       shift_rtx = XEXP (use_body, 1);
   16109                 :          60 :       break;
   16110                 :          60 :     case PARALLEL:
   16111                 :         180 :       for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
   16112                 :         120 :         if (ix86_dep_by_shift_count_body (set_body,
   16113                 :         120 :                                           XVECEXP (use_body, 0, i)))
   16114                 :             :           return true;
   16115                 :             :       /* FALLTHROUGH */
   16116                 :             :     default:
   16117                 :             :       return false;
   16118                 :             :     }
   16119                 :             : 
   16120                 :          60 :   if (shift_rtx
   16121                 :          60 :       && (GET_CODE (shift_rtx) == ASHIFT
   16122                 :          45 :           || GET_CODE (shift_rtx) == LSHIFTRT
   16123                 :          23 :           || GET_CODE (shift_rtx) == ASHIFTRT
   16124                 :          12 :           || GET_CODE (shift_rtx) == ROTATE
   16125                 :          12 :           || GET_CODE (shift_rtx) == ROTATERT))
   16126                 :             :     {
   16127                 :          48 :       rtx shift_count = XEXP (shift_rtx, 1);
   16128                 :             : 
   16129                 :             :       /* Return true if shift count is dest of SET_BODY.  */
   16130                 :          48 :       if (REG_P (shift_count))
   16131                 :             :         {
   16132                 :             :           /* Add check since it can be invoked before register
   16133                 :             :              allocation in pre-reload schedule.  */
   16134                 :           0 :           if (reload_completed
   16135                 :           0 :               && true_regnum (set_dest) == true_regnum (shift_count))
   16136                 :             :             return true;
   16137                 :           0 :           else if (REGNO(set_dest) == REGNO(shift_count))
   16138                 :             :             return true;
   16139                 :             :         }
   16140                 :             :     }
   16141                 :             : 
   16142                 :             :   return false;
   16143                 :             : }
   16144                 :             : 
   16145                 :             : /* Return true if destination reg of SET_INSN is shift count of
   16146                 :             :    USE_INSN.  */
   16147                 :             : 
   16148                 :             : bool
   16149                 :          61 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
   16150                 :             : {
   16151                 :          61 :   return ix86_dep_by_shift_count_body (PATTERN (set_insn),
   16152                 :          61 :                                        PATTERN (use_insn));
   16153                 :             : }
   16154                 :             : 
   16155                 :             : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
   16156                 :             :    are ok, keeping in mind the possible movddup alternative.  */
   16157                 :             : 
   16158                 :             : bool
   16159                 :       88840 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
   16160                 :             : {
   16161                 :       88840 :   if (MEM_P (operands[0]))
   16162                 :        2091 :     return rtx_equal_p (operands[0], operands[1 + high]);
   16163                 :       86749 :   if (MEM_P (operands[1]) && MEM_P (operands[2]))
   16164                 :         923 :     return false;
   16165                 :             :   return true;
   16166                 :             : }
   16167                 :             : 
   16168                 :             : /* A subroutine of ix86_build_signbit_mask.  If VECT is true,
   16169                 :             :    then replicate the value for all elements of the vector
   16170                 :             :    register.  */
   16171                 :             : 
   16172                 :             : rtx
   16173                 :       73976 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
   16174                 :             : {
   16175                 :       73976 :   int i, n_elt;
   16176                 :       73976 :   rtvec v;
   16177                 :       73976 :   machine_mode scalar_mode;
   16178                 :             : 
   16179                 :       73976 :   switch (mode)
   16180                 :             :     {
   16181                 :        1031 :     case E_V64QImode:
   16182                 :        1031 :     case E_V32QImode:
   16183                 :        1031 :     case E_V16QImode:
   16184                 :        1031 :     case E_V32HImode:
   16185                 :        1031 :     case E_V16HImode:
   16186                 :        1031 :     case E_V8HImode:
   16187                 :        1031 :     case E_V16SImode:
   16188                 :        1031 :     case E_V8SImode:
   16189                 :        1031 :     case E_V4SImode:
   16190                 :        1031 :     case E_V2SImode:
   16191                 :        1031 :     case E_V8DImode:
   16192                 :        1031 :     case E_V4DImode:
   16193                 :        1031 :     case E_V2DImode:
   16194                 :        1031 :       gcc_assert (vect);
   16195                 :             :       /* FALLTHRU */
   16196                 :       73976 :     case E_V2HFmode:
   16197                 :       73976 :     case E_V4HFmode:
   16198                 :       73976 :     case E_V8HFmode:
   16199                 :       73976 :     case E_V16HFmode:
   16200                 :       73976 :     case E_V32HFmode:
   16201                 :       73976 :     case E_V16SFmode:
   16202                 :       73976 :     case E_V8SFmode:
   16203                 :       73976 :     case E_V4SFmode:
   16204                 :       73976 :     case E_V2SFmode:
   16205                 :       73976 :     case E_V8DFmode:
   16206                 :       73976 :     case E_V4DFmode:
   16207                 :       73976 :     case E_V2DFmode:
   16208                 :       73976 :     case E_V32BFmode:
   16209                 :       73976 :     case E_V16BFmode:
   16210                 :       73976 :     case E_V8BFmode:
   16211                 :       73976 :     case E_V4BFmode:
   16212                 :       73976 :     case E_V2BFmode:
   16213                 :       73976 :       n_elt = GET_MODE_NUNITS (mode);
   16214                 :       73976 :       v = rtvec_alloc (n_elt);
   16215                 :       73976 :       scalar_mode = GET_MODE_INNER (mode);
   16216                 :             : 
   16217                 :       73976 :       RTVEC_ELT (v, 0) = value;
   16218                 :             : 
   16219                 :      229362 :       for (i = 1; i < n_elt; ++i)
   16220                 :      155386 :         RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
   16221                 :             : 
   16222                 :       73976 :       return gen_rtx_CONST_VECTOR (mode, v);
   16223                 :             : 
   16224                 :           0 :     default:
   16225                 :           0 :       gcc_unreachable ();
   16226                 :             :     }
   16227                 :             : }
   16228                 :             : 
   16229                 :             : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
   16230                 :             :    and ix86_expand_int_vcond.  Create a mask for the sign bit in MODE
   16231                 :             :    for an SSE register.  If VECT is true, then replicate the mask for
   16232                 :             :    all elements of the vector register.  If INVERT is true, then create
   16233                 :             :    a mask excluding the sign bit.  */
   16234                 :             : 
   16235                 :             : rtx
   16236                 :       52828 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
   16237                 :             : {
   16238                 :       52828 :   machine_mode vec_mode, imode;
   16239                 :       52828 :   wide_int w;
   16240                 :       52828 :   rtx mask, v;
   16241                 :             : 
   16242                 :       52828 :   switch (mode)
   16243                 :             :     {
   16244                 :             :     case E_V2HFmode:
   16245                 :             :     case E_V4HFmode:
   16246                 :             :     case E_V8HFmode:
   16247                 :             :     case E_V16HFmode:
   16248                 :             :     case E_V32HFmode:
   16249                 :             :     case E_V32BFmode:
   16250                 :             :     case E_V16BFmode:
   16251                 :             :     case E_V8BFmode:
   16252                 :             :     case E_V4BFmode:
   16253                 :             :     case E_V2BFmode:
   16254                 :             :       vec_mode = mode;
   16255                 :             :       imode = HImode;
   16256                 :             :       break;
   16257                 :             : 
   16258                 :       22828 :     case E_V16SImode:
   16259                 :       22828 :     case E_V16SFmode:
   16260                 :       22828 :     case E_V8SImode:
   16261                 :       22828 :     case E_V4SImode:
   16262                 :       22828 :     case E_V8SFmode:
   16263                 :       22828 :     case E_V4SFmode:
   16264                 :       22828 :     case E_V2SFmode:
   16265                 :       22828 :     case E_V2SImode:
   16266                 :       22828 :       vec_mode = mode;
   16267                 :       22828 :       imode = SImode;
   16268                 :       22828 :       break;
   16269                 :             : 
   16270                 :       27233 :     case E_V8DImode:
   16271                 :       27233 :     case E_V4DImode:
   16272                 :       27233 :     case E_V2DImode:
   16273                 :       27233 :     case E_V8DFmode:
   16274                 :       27233 :     case E_V4DFmode:
   16275                 :       27233 :     case E_V2DFmode:
   16276                 :       27233 :       vec_mode = mode;
   16277                 :       27233 :       imode = DImode;
   16278                 :       27233 :       break;
   16279                 :             : 
   16280                 :        2367 :     case E_TImode:
   16281                 :        2367 :     case E_TFmode:
   16282                 :        2367 :       vec_mode = VOIDmode;
   16283                 :        2367 :       imode = TImode;
   16284                 :        2367 :       break;
   16285                 :             : 
   16286                 :           0 :     default:
   16287                 :           0 :       gcc_unreachable ();
   16288                 :             :     }
   16289                 :             : 
   16290                 :       52828 :   machine_mode inner_mode = GET_MODE_INNER (mode);
   16291                 :      105656 :   w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
   16292                 :      105656 :                            GET_MODE_BITSIZE (inner_mode));
   16293                 :       52828 :   if (invert)
   16294                 :       16638 :     w = wi::bit_not (w);
   16295                 :             : 
   16296                 :             :   /* Force this value into the low part of a fp vector constant.  */
   16297                 :       52828 :   mask = immed_wide_int_const (w, imode);
   16298                 :       52828 :   mask = gen_lowpart (inner_mode, mask);
   16299                 :             : 
   16300                 :       52828 :   if (vec_mode == VOIDmode)
   16301                 :        2367 :     return force_reg (inner_mode, mask);
   16302                 :             : 
   16303                 :       50461 :   v = ix86_build_const_vector (vec_mode, vect, mask);
   16304                 :       50461 :   return force_reg (vec_mode, v);
   16305                 :       52828 : }
   16306                 :             : 
   16307                 :             : /* Return HOST_WIDE_INT for const vector OP in MODE.  */
   16308                 :             : 
   16309                 :             : HOST_WIDE_INT
   16310                 :      138515 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
   16311                 :             : {
   16312                 :      298672 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   16313                 :           0 :     gcc_unreachable ();
   16314                 :             : 
   16315                 :      138515 :   int nunits = GET_MODE_NUNITS (mode);
   16316                 :      277030 :   wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
   16317                 :      138515 :   machine_mode innermode = GET_MODE_INNER (mode);
   16318                 :      138515 :   unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
   16319                 :             : 
   16320                 :      138515 :   switch (mode)
   16321                 :             :     {
   16322                 :             :     case E_V2QImode:
   16323                 :             :     case E_V4QImode:
   16324                 :             :     case E_V2HImode:
   16325                 :             :     case E_V8QImode:
   16326                 :             :     case E_V4HImode:
   16327                 :             :     case E_V2SImode:
   16328                 :      471352 :       for (int i = 0; i < nunits; ++i)
   16329                 :             :         {
   16330                 :      336026 :           int v = INTVAL (XVECEXP (op, 0, i));
   16331                 :      336026 :           wide_int wv = wi::shwi (v, innermode_bits);
   16332                 :      336026 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16333                 :      336026 :         }
   16334                 :             :       break;
   16335                 :             :     case E_V2HFmode:
   16336                 :             :     case E_V2BFmode:
   16337                 :             :     case E_V4HFmode:
   16338                 :             :     case E_V4BFmode:
   16339                 :             :     case E_V2SFmode:
   16340                 :        9577 :       for (int i = 0; i < nunits; ++i)
   16341                 :             :         {
   16342                 :        6388 :           rtx x = XVECEXP (op, 0, i);
   16343                 :        6388 :           int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   16344                 :        6388 :                                   REAL_MODE_FORMAT (innermode));
   16345                 :        6388 :           wide_int wv = wi::shwi (v, innermode_bits);
   16346                 :        6388 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16347                 :        6388 :         }
   16348                 :             :       break;
   16349                 :           0 :     default:
   16350                 :           0 :       gcc_unreachable ();
   16351                 :             :     }
   16352                 :             : 
   16353                 :      138515 :   return val.to_shwi ();
   16354                 :      138515 : }
   16355                 :             : 
   16356                 :          32 : int ix86_get_flags_cc (rtx_code code)
   16357                 :             : {
   16358                 :          32 :   switch (code)
   16359                 :             :     {
   16360                 :             :       case NE: return X86_CCNE;
   16361                 :             :       case EQ: return X86_CCE;
   16362                 :             :       case GE: return X86_CCNL;
   16363                 :             :       case GT: return X86_CCNLE;
   16364                 :             :       case LE: return X86_CCLE;
   16365                 :             :       case LT: return X86_CCL;
   16366                 :             :       case GEU: return X86_CCNB;
   16367                 :             :       case GTU: return X86_CCNBE;
   16368                 :             :       case LEU: return X86_CCBE;
   16369                 :             :       case LTU: return X86_CCB;
   16370                 :             :       default: return -1;
   16371                 :             :     }
   16372                 :             : }
   16373                 :             : 
   16374                 :             : /* Return TRUE or FALSE depending on whether the first SET in INSN
   16375                 :             :    has source and destination with matching CC modes, and that the
   16376                 :             :    CC mode is at least as constrained as REQ_MODE.  */
   16377                 :             : 
   16378                 :             : bool
   16379                 :    50381482 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
   16380                 :             : {
   16381                 :    50381482 :   rtx set;
   16382                 :    50381482 :   machine_mode set_mode;
   16383                 :             : 
   16384                 :    50381482 :   set = PATTERN (insn);
   16385                 :    50381482 :   if (GET_CODE (set) == PARALLEL)
   16386                 :      428077 :     set = XVECEXP (set, 0, 0);
   16387                 :    50381482 :   gcc_assert (GET_CODE (set) == SET);
   16388                 :    50381482 :   gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
   16389                 :             : 
   16390                 :    50381482 :   set_mode = GET_MODE (SET_DEST (set));
   16391                 :    50381482 :   switch (set_mode)
   16392                 :             :     {
   16393                 :     1336690 :     case E_CCNOmode:
   16394                 :     1336690 :       if (req_mode != CCNOmode
   16395                 :       62709 :           && (req_mode != CCmode
   16396                 :           0 :               || XEXP (SET_SRC (set), 1) != const0_rtx))
   16397                 :             :         return false;
   16398                 :             :       break;
   16399                 :     4622980 :     case E_CCmode:
   16400                 :     4622980 :       if (req_mode == CCGCmode)
   16401                 :             :         return false;
   16402                 :             :       /* FALLTHRU */
   16403                 :     8130670 :     case E_CCGCmode:
   16404                 :     8130670 :       if (req_mode == CCGOCmode || req_mode == CCNOmode)
   16405                 :             :         return false;
   16406                 :             :       /* FALLTHRU */
   16407                 :     9147503 :     case E_CCGOCmode:
   16408                 :     9147503 :       if (req_mode == CCZmode)
   16409                 :             :         return false;
   16410                 :             :       /* FALLTHRU */
   16411                 :             :     case E_CCZmode:
   16412                 :             :       break;
   16413                 :             : 
   16414                 :           0 :     case E_CCGZmode:
   16415                 :             : 
   16416                 :           0 :     case E_CCAmode:
   16417                 :           0 :     case E_CCCmode:
   16418                 :           0 :     case E_CCOmode:
   16419                 :           0 :     case E_CCPmode:
   16420                 :           0 :     case E_CCSmode:
   16421                 :           0 :       if (set_mode != req_mode)
   16422                 :             :         return false;
   16423                 :             :       break;
   16424                 :             : 
   16425                 :           0 :     default:
   16426                 :           0 :       gcc_unreachable ();
   16427                 :             :     }
   16428                 :             : 
   16429                 :    50310192 :   return GET_MODE (SET_SRC (set)) == set_mode;
   16430                 :             : }
   16431                 :             : 
   16432                 :             : machine_mode
   16433                 :    12720171 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
   16434                 :             : {
   16435                 :    12720171 :   machine_mode mode = GET_MODE (op0);
   16436                 :             : 
   16437                 :    12720171 :   if (SCALAR_FLOAT_MODE_P (mode))
   16438                 :             :     {
   16439                 :      121233 :       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
   16440                 :             :       return CCFPmode;
   16441                 :             :     }
   16442                 :             : 
   16443                 :    12598938 :   switch (code)
   16444                 :             :     {
   16445                 :             :       /* Only zero flag is needed.  */
   16446                 :             :     case EQ:                    /* ZF=0 */
   16447                 :             :     case NE:                    /* ZF!=0 */
   16448                 :             :       return CCZmode;
   16449                 :             :       /* Codes needing carry flag.  */
   16450                 :      866118 :     case GEU:                   /* CF=0 */
   16451                 :      866118 :     case LTU:                   /* CF=1 */
   16452                 :      866118 :       rtx geu;
   16453                 :             :       /* Detect overflow checks.  They need just the carry flag.  */
   16454                 :      866118 :       if (GET_CODE (op0) == PLUS
   16455                 :      866118 :           && (rtx_equal_p (op1, XEXP (op0, 0))
   16456                 :       99621 :               || rtx_equal_p (op1, XEXP (op0, 1))))
   16457                 :       16776 :         return CCCmode;
   16458                 :             :       /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
   16459                 :             :          Match LTU of op0
   16460                 :             :          (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   16461                 :             :          and op1
   16462                 :             :          (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
   16463                 :             :          where CC_CCC is either CC or CCC.  */
   16464                 :      849342 :       else if (code == LTU
   16465                 :      318743 :                && GET_CODE (op0) == NEG
   16466                 :        5035 :                && GET_CODE (geu = XEXP (op0, 0)) == GEU
   16467                 :        3651 :                && REG_P (XEXP (geu, 0))
   16468                 :        3329 :                && (GET_MODE (XEXP (geu, 0)) == CCCmode
   16469                 :          37 :                    || GET_MODE (XEXP (geu, 0)) == CCmode)
   16470                 :        3318 :                && REGNO (XEXP (geu, 0)) == FLAGS_REG
   16471                 :        3318 :                && XEXP (geu, 1) == const0_rtx
   16472                 :        3318 :                && GET_CODE (op1) == LTU
   16473                 :        3318 :                && REG_P (XEXP (op1, 0))
   16474                 :        3318 :                && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   16475                 :        3318 :                && REGNO (XEXP (op1, 0)) == FLAGS_REG
   16476                 :      852660 :                && XEXP (op1, 1) == const0_rtx)
   16477                 :             :         return CCCmode;
   16478                 :             :       /* Similarly for *x86_cmc pattern.
   16479                 :             :          Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   16480                 :             :          and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
   16481                 :             :          It is sufficient to test that the operand modes are CCCmode.  */
   16482                 :      846024 :       else if (code == LTU
   16483                 :      315425 :                && GET_CODE (op0) == NEG
   16484                 :        1717 :                && GET_CODE (XEXP (op0, 0)) == LTU
   16485                 :         374 :                && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   16486                 :           3 :                && GET_CODE (op1) == GEU
   16487                 :           3 :                && GET_MODE (XEXP (op1, 0)) == CCCmode)
   16488                 :             :         return CCCmode;
   16489                 :             :       /* Similarly for the comparison of addcarry/subborrow pattern.  */
   16490                 :      315422 :       else if (code == LTU
   16491                 :      315422 :                && GET_CODE (op0) == ZERO_EXTEND
   16492                 :       14895 :                && GET_CODE (op1) == PLUS
   16493                 :        9510 :                && ix86_carry_flag_operator (XEXP (op1, 0), VOIDmode)
   16494                 :        9510 :                && GET_CODE (XEXP (op1, 1)) == ZERO_EXTEND)
   16495                 :             :         return CCCmode;
   16496                 :             :       else
   16497                 :      836511 :         return CCmode;
   16498                 :             :     case GTU:                   /* CF=0 & ZF=0 */
   16499                 :             :     case LEU:                   /* CF=1 | ZF=1 */
   16500                 :             :       return CCmode;
   16501                 :             :       /* Codes possibly doable only with sign flag when
   16502                 :             :          comparing against zero.  */
   16503                 :      754744 :     case GE:                    /* SF=OF   or   SF=0 */
   16504                 :      754744 :     case LT:                    /* SF<>OF  or   SF=1 */
   16505                 :      754744 :       if (op1 == const0_rtx)
   16506                 :             :         return CCGOCmode;
   16507                 :             :       else
   16508                 :             :         /* For other cases Carry flag is not required.  */
   16509                 :      421925 :         return CCGCmode;
   16510                 :             :       /* Codes doable only with sign flag when comparing
   16511                 :             :          against zero, but we miss jump instruction for it
   16512                 :             :          so we need to use relational tests against overflow
   16513                 :             :          that thus needs to be zero.  */
   16514                 :      874413 :     case GT:                    /* ZF=0 & SF=OF */
   16515                 :      874413 :     case LE:                    /* ZF=1 | SF<>OF */
   16516                 :      874413 :       if (op1 == const0_rtx)
   16517                 :             :         return CCNOmode;
   16518                 :             :       else
   16519                 :      589711 :         return CCGCmode;
   16520                 :             :     default:
   16521                 :             :       /* CCmode should be used in all other cases.  */
   16522                 :             :       return CCmode;
   16523                 :             :     }
   16524                 :             : }
   16525                 :             : 
   16526                 :             : /* Return TRUE or FALSE depending on whether the ptest instruction
   16527                 :             :    INSN has source and destination with suitable matching CC modes.  */
   16528                 :             : 
   16529                 :             : bool
   16530                 :       36898 : ix86_match_ptest_ccmode (rtx insn)
   16531                 :             : {
   16532                 :       36898 :   rtx set, src;
   16533                 :       36898 :   machine_mode set_mode;
   16534                 :             : 
   16535                 :       36898 :   set = PATTERN (insn);
   16536                 :       36898 :   gcc_assert (GET_CODE (set) == SET);
   16537                 :       36898 :   src = SET_SRC (set);
   16538                 :       36898 :   gcc_assert (GET_CODE (src) == UNSPEC
   16539                 :             :               && XINT (src, 1) == UNSPEC_PTEST);
   16540                 :             : 
   16541                 :       36898 :   set_mode = GET_MODE (src);
   16542                 :       36898 :   if (set_mode != CCZmode
   16543                 :             :       && set_mode != CCCmode
   16544                 :             :       && set_mode != CCmode)
   16545                 :             :     return false;
   16546                 :       36898 :   return GET_MODE (SET_DEST (set)) == set_mode;
   16547                 :             : }
   16548                 :             : 
   16549                 :             : /* Return the fixed registers used for condition codes.  */
   16550                 :             : 
   16551                 :             : static bool
   16552                 :     9590747 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
   16553                 :             : {
   16554                 :     9590747 :   *p1 = FLAGS_REG;
   16555                 :     9590747 :   *p2 = INVALID_REGNUM;
   16556                 :     9590747 :   return true;
   16557                 :             : }
   16558                 :             : 
   16559                 :             : /* If two condition code modes are compatible, return a condition code
   16560                 :             :    mode which is compatible with both.  Otherwise, return
   16561                 :             :    VOIDmode.  */
   16562                 :             : 
   16563                 :             : static machine_mode
   16564                 :       28378 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
   16565                 :             : {
   16566                 :       28378 :   if (m1 == m2)
   16567                 :             :     return m1;
   16568                 :             : 
   16569                 :       27791 :   if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
   16570                 :             :     return VOIDmode;
   16571                 :             : 
   16572                 :       27791 :   if ((m1 == CCGCmode && m2 == CCGOCmode)
   16573                 :       27791 :       || (m1 == CCGOCmode && m2 == CCGCmode))
   16574                 :             :     return CCGCmode;
   16575                 :             : 
   16576                 :       27791 :   if ((m1 == CCNOmode && m2 == CCGOCmode)
   16577                 :       27603 :       || (m1 == CCGOCmode && m2 == CCNOmode))
   16578                 :             :     return CCNOmode;
   16579                 :             : 
   16580                 :       27473 :   if (m1 == CCZmode
   16581                 :       17396 :       && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
   16582                 :             :     return m2;
   16583                 :       14603 :   else if (m2 == CCZmode
   16584                 :        9826 :            && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
   16585                 :             :     return m1;
   16586                 :             : 
   16587                 :        6105 :   switch (m1)
   16588                 :             :     {
   16589                 :           0 :     default:
   16590                 :           0 :       gcc_unreachable ();
   16591                 :             : 
   16592                 :        6105 :     case E_CCmode:
   16593                 :        6105 :     case E_CCGCmode:
   16594                 :        6105 :     case E_CCGOCmode:
   16595                 :        6105 :     case E_CCNOmode:
   16596                 :        6105 :     case E_CCAmode:
   16597                 :        6105 :     case E_CCCmode:
   16598                 :        6105 :     case E_CCOmode:
   16599                 :        6105 :     case E_CCPmode:
   16600                 :        6105 :     case E_CCSmode:
   16601                 :        6105 :     case E_CCZmode:
   16602                 :        6105 :       switch (m2)
   16603                 :             :         {
   16604                 :             :         default:
   16605                 :             :           return VOIDmode;
   16606                 :             : 
   16607                 :             :         case E_CCmode:
   16608                 :             :         case E_CCGCmode:
   16609                 :             :         case E_CCGOCmode:
   16610                 :             :         case E_CCNOmode:
   16611                 :             :         case E_CCAmode:
   16612                 :             :         case E_CCCmode:
   16613                 :             :         case E_CCOmode:
   16614                 :             :         case E_CCPmode:
   16615                 :             :         case E_CCSmode:
   16616                 :             :         case E_CCZmode:
   16617                 :             :           return CCmode;
   16618                 :             :         }
   16619                 :             : 
   16620                 :             :     case E_CCFPmode:
   16621                 :             :       /* These are only compatible with themselves, which we already
   16622                 :             :          checked above.  */
   16623                 :             :       return VOIDmode;
   16624                 :             :     }
   16625                 :             : }
   16626                 :             : 
   16627                 :             : /* Return strategy to use for floating-point.  We assume that fcomi is always
   16628                 :             :    preferrable where available, since that is also true when looking at size
   16629                 :             :    (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
   16630                 :             : 
   16631                 :             : enum ix86_fpcmp_strategy
   16632                 :     5544372 : ix86_fp_comparison_strategy (enum rtx_code)
   16633                 :             : {
   16634                 :             :   /* Do fcomi/sahf based test when profitable.  */
   16635                 :             : 
   16636                 :     5544372 :   if (TARGET_CMOVE)
   16637                 :             :     return IX86_FPCMP_COMI;
   16638                 :             : 
   16639                 :           0 :   if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
   16640                 :           0 :     return IX86_FPCMP_SAHF;
   16641                 :             : 
   16642                 :             :   return IX86_FPCMP_ARITH;
   16643                 :             : }
   16644                 :             : 
   16645                 :             : /* Convert comparison codes we use to represent FP comparison to integer
   16646                 :             :    code that will result in proper branch.  Return UNKNOWN if no such code
   16647                 :             :    is available.  */
   16648                 :             : 
   16649                 :             : enum rtx_code
   16650                 :      579042 : ix86_fp_compare_code_to_integer (enum rtx_code code)
   16651                 :             : {
   16652                 :      579042 :   switch (code)
   16653                 :             :     {
   16654                 :             :     case GT:
   16655                 :             :       return GTU;
   16656                 :       18280 :     case GE:
   16657                 :       18280 :       return GEU;
   16658                 :             :     case ORDERED:
   16659                 :             :     case UNORDERED:
   16660                 :             :       return code;
   16661                 :      118660 :     case UNEQ:
   16662                 :      118660 :       return EQ;
   16663                 :       19448 :     case UNLT:
   16664                 :       19448 :       return LTU;
   16665                 :       31563 :     case UNLE:
   16666                 :       31563 :       return LEU;
   16667                 :      111914 :     case LTGT:
   16668                 :      111914 :       return NE;
   16669                 :          19 :     case EQ:
   16670                 :          19 :     case NE:
   16671                 :          19 :       if (TARGET_AVX10_2_256)
   16672                 :             :         return code;
   16673                 :             :       /* FALLTHRU.  */
   16674                 :         205 :     default:
   16675                 :         205 :       return UNKNOWN;
   16676                 :             :     }
   16677                 :             : }
   16678                 :             : 
   16679                 :             : /* Zero extend possibly SImode EXP to Pmode register.  */
   16680                 :             : rtx
   16681                 :       66278 : ix86_zero_extend_to_Pmode (rtx exp)
   16682                 :             : {
   16683                 :       66278 :   return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
   16684                 :             : }
   16685                 :             : 
   16686                 :             : /* Return true if the function is called via PLT.   */
   16687                 :             : 
   16688                 :             : bool
   16689                 :      961520 : ix86_call_use_plt_p (rtx call_op)
   16690                 :             : {
   16691                 :      961520 :   if (SYMBOL_REF_LOCAL_P (call_op))
   16692                 :             :     {
   16693                 :      190155 :       if (SYMBOL_REF_DECL (call_op)
   16694                 :      190155 :           && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
   16695                 :             :         {
   16696                 :             :           /* NB: All ifunc functions must be called via PLT.  */
   16697                 :      107057 :           cgraph_node *node
   16698                 :      107057 :             = cgraph_node::get (SYMBOL_REF_DECL (call_op));
   16699                 :      107057 :           if (node && node->ifunc_resolver)
   16700                 :             :             return true;
   16701                 :             :         }
   16702                 :      190135 :       return false;
   16703                 :             :     }
   16704                 :             :   return true;
   16705                 :             : }
   16706                 :             : 
   16707                 :             : /* Implement TARGET_IFUNC_REF_LOCAL_OK.  If this hook returns true,
   16708                 :             :    the PLT entry will be used as the function address for local IFUNC
   16709                 :             :    functions.  When the PIC register is needed for PLT call, indirect
   16710                 :             :    call via the PLT entry will fail since the PIC register may not be
   16711                 :             :    set up properly for indirect call.  In this case, we should return
   16712                 :             :    false.  */
   16713                 :             : 
   16714                 :             : static bool
   16715                 :   718450025 : ix86_ifunc_ref_local_ok (void)
   16716                 :             : {
   16717                 :   718450025 :   return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
   16718                 :             : }
   16719                 :             : 
   16720                 :             : /* Return true if the function being called was marked with attribute
   16721                 :             :    "noplt" or using -fno-plt and we are compiling for non-PIC.  We need
   16722                 :             :    to handle the non-PIC case in the backend because there is no easy
   16723                 :             :    interface for the front-end to force non-PLT calls to use the GOT.
   16724                 :             :    This is currently used only with 64-bit or 32-bit GOT32X ELF targets
   16725                 :             :    to call the function marked "noplt" indirectly.  */
   16726                 :             : 
   16727                 :             : bool
   16728                 :     5688214 : ix86_nopic_noplt_attribute_p (rtx call_op)
   16729                 :             : {
   16730                 :     5213441 :   if (flag_pic || ix86_cmodel == CM_LARGE
   16731                 :             :       || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
   16732                 :             :       || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
   16733                 :    10901655 :       || SYMBOL_REF_LOCAL_P (call_op))
   16734                 :             :     return false;
   16735                 :             : 
   16736                 :     3656229 :   tree symbol_decl = SYMBOL_REF_DECL (call_op);
   16737                 :             : 
   16738                 :     3656229 :   if (!flag_plt
   16739                 :     3656229 :       || (symbol_decl != NULL_TREE
   16740                 :     3656197 :           && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
   16741                 :          34 :     return true;
   16742                 :             : 
   16743                 :             :   return false;
   16744                 :             : }
   16745                 :             : 
   16746                 :             : /* Helper to output the jmp/call.  */
   16747                 :             : static void
   16748                 :          33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
   16749                 :             : {
   16750                 :          33 :   if (thunk_name != NULL)
   16751                 :             :     {
   16752                 :          22 :       if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   16753                 :           1 :           && ix86_indirect_branch_cs_prefix)
   16754                 :           1 :         fprintf (asm_out_file, "\tcs\n");
   16755                 :          22 :       fprintf (asm_out_file, "\tjmp\t");
   16756                 :          22 :       assemble_name (asm_out_file, thunk_name);
   16757                 :          22 :       putc ('\n', asm_out_file);
   16758                 :          22 :       if ((ix86_harden_sls & harden_sls_indirect_jmp))
   16759                 :           2 :         fputs ("\tint3\n", asm_out_file);
   16760                 :             :     }
   16761                 :             :   else
   16762                 :          11 :     output_indirect_thunk (regno);
   16763                 :          33 : }
   16764                 :             : 
   16765                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is a
   16766                 :             :    register which contains the branch target.  XASM is the assembly
   16767                 :             :    template for CALL_OP.  Branch is a tail call if SIBCALL_P is true.
   16768                 :             :    A normal call is converted to:
   16769                 :             : 
   16770                 :             :         call __x86_indirect_thunk_reg
   16771                 :             : 
   16772                 :             :    and a tail call is converted to:
   16773                 :             : 
   16774                 :             :         jmp __x86_indirect_thunk_reg
   16775                 :             :  */
   16776                 :             : 
   16777                 :             : static void
   16778                 :          50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
   16779                 :             : {
   16780                 :          50 :   char thunk_name_buf[32];
   16781                 :          50 :   char *thunk_name;
   16782                 :          50 :   enum indirect_thunk_prefix need_prefix
   16783                 :          50 :     = indirect_thunk_need_prefix (current_output_insn);
   16784                 :          50 :   int regno = REGNO (call_op);
   16785                 :             : 
   16786                 :          50 :   if (cfun->machine->indirect_branch_type
   16787                 :          50 :       != indirect_branch_thunk_inline)
   16788                 :             :     {
   16789                 :          39 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   16790                 :          16 :         SET_HARD_REG_BIT (indirect_thunks_used, regno);
   16791                 :             : 
   16792                 :          39 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   16793                 :          39 :       thunk_name = thunk_name_buf;
   16794                 :             :     }
   16795                 :             :   else
   16796                 :             :     thunk_name = NULL;
   16797                 :             : 
   16798                 :          50 :   if (sibcall_p)
   16799                 :          27 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16800                 :             :   else
   16801                 :             :     {
   16802                 :          23 :       if (thunk_name != NULL)
   16803                 :             :         {
   16804                 :          17 :           if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
   16805                 :           1 :               && ix86_indirect_branch_cs_prefix)
   16806                 :           1 :             fprintf (asm_out_file, "\tcs\n");
   16807                 :          17 :           fprintf (asm_out_file, "\tcall\t");
   16808                 :          17 :           assemble_name (asm_out_file, thunk_name);
   16809                 :          17 :           putc ('\n', asm_out_file);
   16810                 :          17 :           return;
   16811                 :             :         }
   16812                 :             : 
   16813                 :           6 :       char indirectlabel1[32];
   16814                 :           6 :       char indirectlabel2[32];
   16815                 :             : 
   16816                 :           6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   16817                 :             :                                    INDIRECT_LABEL,
   16818                 :             :                                    indirectlabelno++);
   16819                 :           6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   16820                 :             :                                    INDIRECT_LABEL,
   16821                 :             :                                    indirectlabelno++);
   16822                 :             : 
   16823                 :             :       /* Jump.  */
   16824                 :           6 :       fputs ("\tjmp\t", asm_out_file);
   16825                 :           6 :       assemble_name_raw (asm_out_file, indirectlabel2);
   16826                 :           6 :       fputc ('\n', asm_out_file);
   16827                 :             : 
   16828                 :           6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   16829                 :             : 
   16830                 :           6 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16831                 :             : 
   16832                 :           6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   16833                 :             : 
   16834                 :             :       /* Call.  */
   16835                 :           6 :       fputs ("\tcall\t", asm_out_file);
   16836                 :           6 :       assemble_name_raw (asm_out_file, indirectlabel1);
   16837                 :           6 :       fputc ('\n', asm_out_file);
   16838                 :             :     }
   16839                 :             : }
   16840                 :             : 
   16841                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is
   16842                 :             :    the branch target.  XASM is the assembly template for CALL_OP.
   16843                 :             :    Branch is a tail call if SIBCALL_P is true.  A normal call is
   16844                 :             :    converted to:
   16845                 :             : 
   16846                 :             :         jmp L2
   16847                 :             :    L1:
   16848                 :             :         push CALL_OP
   16849                 :             :         jmp __x86_indirect_thunk
   16850                 :             :    L2:
   16851                 :             :         call L1
   16852                 :             : 
   16853                 :             :    and a tail call is converted to:
   16854                 :             : 
   16855                 :             :         push CALL_OP
   16856                 :             :         jmp __x86_indirect_thunk
   16857                 :             :  */
   16858                 :             : 
   16859                 :             : static void
   16860                 :           0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
   16861                 :             :                                       bool sibcall_p)
   16862                 :             : {
   16863                 :           0 :   char thunk_name_buf[32];
   16864                 :           0 :   char *thunk_name;
   16865                 :           0 :   char push_buf[64];
   16866                 :           0 :   enum indirect_thunk_prefix need_prefix
   16867                 :           0 :     = indirect_thunk_need_prefix (current_output_insn);
   16868                 :           0 :   int regno = -1;
   16869                 :             : 
   16870                 :           0 :   if (cfun->machine->indirect_branch_type
   16871                 :           0 :       != indirect_branch_thunk_inline)
   16872                 :             :     {
   16873                 :           0 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   16874                 :           0 :         indirect_thunk_needed = true;
   16875                 :           0 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   16876                 :           0 :       thunk_name = thunk_name_buf;
   16877                 :             :     }
   16878                 :             :   else
   16879                 :             :     thunk_name = NULL;
   16880                 :             : 
   16881                 :           0 :   snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
   16882                 :           0 :             TARGET_64BIT ? 'q' : 'l', xasm);
   16883                 :             : 
   16884                 :           0 :   if (sibcall_p)
   16885                 :             :     {
   16886                 :           0 :       output_asm_insn (push_buf, &call_op);
   16887                 :           0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16888                 :             :     }
   16889                 :             :   else
   16890                 :             :     {
   16891                 :           0 :       char indirectlabel1[32];
   16892                 :           0 :       char indirectlabel2[32];
   16893                 :             : 
   16894                 :           0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   16895                 :             :                                    INDIRECT_LABEL,
   16896                 :             :                                    indirectlabelno++);
   16897                 :           0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   16898                 :             :                                    INDIRECT_LABEL,
   16899                 :             :                                    indirectlabelno++);
   16900                 :             : 
   16901                 :             :       /* Jump.  */
   16902                 :           0 :       fputs ("\tjmp\t", asm_out_file);
   16903                 :           0 :       assemble_name_raw (asm_out_file, indirectlabel2);
   16904                 :           0 :       fputc ('\n', asm_out_file);
   16905                 :             : 
   16906                 :           0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   16907                 :             : 
   16908                 :             :       /* An external function may be called via GOT, instead of PLT.  */
   16909                 :           0 :       if (MEM_P (call_op))
   16910                 :             :         {
   16911                 :           0 :           struct ix86_address parts;
   16912                 :           0 :           rtx addr = XEXP (call_op, 0);
   16913                 :           0 :           if (ix86_decompose_address (addr, &parts)
   16914                 :           0 :               && parts.base == stack_pointer_rtx)
   16915                 :             :             {
   16916                 :             :               /* Since call will adjust stack by -UNITS_PER_WORD,
   16917                 :             :                  we must convert "disp(stack, index, scale)" to
   16918                 :             :                  "disp+UNITS_PER_WORD(stack, index, scale)".  */
   16919                 :           0 :               if (parts.index)
   16920                 :             :                 {
   16921                 :           0 :                   addr = gen_rtx_MULT (Pmode, parts.index,
   16922                 :             :                                        GEN_INT (parts.scale));
   16923                 :           0 :                   addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   16924                 :             :                                        addr);
   16925                 :             :                 }
   16926                 :             :               else
   16927                 :             :                 addr = stack_pointer_rtx;
   16928                 :             : 
   16929                 :           0 :               rtx disp;
   16930                 :           0 :               if (parts.disp != NULL_RTX)
   16931                 :           0 :                 disp = plus_constant (Pmode, parts.disp,
   16932                 :           0 :                                       UNITS_PER_WORD);
   16933                 :             :               else
   16934                 :           0 :                 disp = GEN_INT (UNITS_PER_WORD);
   16935                 :             : 
   16936                 :           0 :               addr = gen_rtx_PLUS (Pmode, addr, disp);
   16937                 :           0 :               call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
   16938                 :             :             }
   16939                 :             :         }
   16940                 :             : 
   16941                 :           0 :       output_asm_insn (push_buf, &call_op);
   16942                 :             : 
   16943                 :           0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16944                 :             : 
   16945                 :           0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   16946                 :             : 
   16947                 :             :       /* Call.  */
   16948                 :           0 :       fputs ("\tcall\t", asm_out_file);
   16949                 :           0 :       assemble_name_raw (asm_out_file, indirectlabel1);
   16950                 :           0 :       fputc ('\n', asm_out_file);
   16951                 :             :     }
   16952                 :           0 : }
   16953                 :             : 
   16954                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is
   16955                 :             :    the branch target.  XASM is the assembly template for CALL_OP.
   16956                 :             :    Branch is a tail call if SIBCALL_P is true.   */
   16957                 :             : 
   16958                 :             : static void
   16959                 :          50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
   16960                 :             :                              bool sibcall_p)
   16961                 :             : {
   16962                 :          50 :   if (REG_P (call_op))
   16963                 :          50 :     ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
   16964                 :             :   else
   16965                 :           0 :     ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
   16966                 :          50 : }
   16967                 :             : 
   16968                 :             : /* Output indirect jump.  CALL_OP is the jump target.  */
   16969                 :             : 
   16970                 :             : const char *
   16971                 :        7829 : ix86_output_indirect_jmp (rtx call_op)
   16972                 :             : {
   16973                 :        7829 :   if (cfun->machine->indirect_branch_type != indirect_branch_keep)
   16974                 :             :     {
   16975                 :             :       /* We can't have red-zone since "call" in the indirect thunk
   16976                 :             :          pushes the return address onto stack, destroying red-zone.  */
   16977                 :           4 :       if (ix86_red_zone_used)
   16978                 :           0 :         gcc_unreachable ();
   16979                 :             : 
   16980                 :           4 :       ix86_output_indirect_branch (call_op, "%0", true);
   16981                 :             :     }
   16982                 :             :   else
   16983                 :        7825 :     output_asm_insn ("%!jmp\t%A0", &call_op);
   16984                 :        7829 :   return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
   16985                 :             : }
   16986                 :             : 
   16987                 :             : /* Output return instrumentation for current function if needed.  */
   16988                 :             : 
   16989                 :             : static void
   16990                 :     1665984 : output_return_instrumentation (void)
   16991                 :             : {
   16992                 :     1665984 :   if (ix86_instrument_return != instrument_return_none
   16993                 :           6 :       && flag_fentry
   16994                 :     1665990 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
   16995                 :             :     {
   16996                 :           5 :       if (ix86_flag_record_return)
   16997                 :           5 :         fprintf (asm_out_file, "1:\n");
   16998                 :           5 :       switch (ix86_instrument_return)
   16999                 :             :         {
   17000                 :           2 :         case instrument_return_call:
   17001                 :           2 :           fprintf (asm_out_file, "\tcall\t__return__\n");
   17002                 :           2 :           break;
   17003                 :           3 :         case instrument_return_nop5:
   17004                 :             :           /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1)  */
   17005                 :           3 :           fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   17006                 :           3 :           break;
   17007                 :             :         case instrument_return_none:
   17008                 :             :           break;
   17009                 :             :         }
   17010                 :             : 
   17011                 :           5 :       if (ix86_flag_record_return)
   17012                 :             :         {
   17013                 :           5 :           fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
   17014                 :           5 :           fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   17015                 :           5 :           fprintf (asm_out_file, "\t.previous\n");
   17016                 :             :         }
   17017                 :             :     }
   17018                 :     1665984 : }
   17019                 :             : 
   17020                 :             : /* Output function return.  CALL_OP is the jump target.  Add a REP
   17021                 :             :    prefix to RET if LONG_P is true and function return is kept.  */
   17022                 :             : 
   17023                 :             : const char *
   17024                 :     1547051 : ix86_output_function_return (bool long_p)
   17025                 :             : {
   17026                 :     1547051 :   output_return_instrumentation ();
   17027                 :             : 
   17028                 :     1547051 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17029                 :             :     {
   17030                 :          17 :       char thunk_name[32];
   17031                 :          17 :       enum indirect_thunk_prefix need_prefix
   17032                 :          17 :         = indirect_thunk_need_prefix (current_output_insn);
   17033                 :             : 
   17034                 :          17 :       if (cfun->machine->function_return_type
   17035                 :          17 :           != indirect_branch_thunk_inline)
   17036                 :             :         {
   17037                 :          12 :           bool need_thunk = (cfun->machine->function_return_type
   17038                 :             :                              == indirect_branch_thunk);
   17039                 :          12 :           indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
   17040                 :             :                                true);
   17041                 :          12 :           indirect_return_needed |= need_thunk;
   17042                 :          12 :           fprintf (asm_out_file, "\tjmp\t");
   17043                 :          12 :           assemble_name (asm_out_file, thunk_name);
   17044                 :          12 :           putc ('\n', asm_out_file);
   17045                 :             :         }
   17046                 :             :       else
   17047                 :           5 :         output_indirect_thunk (INVALID_REGNUM);
   17048                 :             : 
   17049                 :          17 :       return "";
   17050                 :             :     }
   17051                 :             : 
   17052                 :     3093585 :   output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
   17053                 :     1547034 :   return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
   17054                 :             : }
   17055                 :             : 
   17056                 :             : /* Output indirect function return.  RET_OP is the function return
   17057                 :             :    target.  */
   17058                 :             : 
   17059                 :             : const char *
   17060                 :          17 : ix86_output_indirect_function_return (rtx ret_op)
   17061                 :             : {
   17062                 :          17 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17063                 :             :     {
   17064                 :           0 :       char thunk_name[32];
   17065                 :           0 :       enum indirect_thunk_prefix need_prefix
   17066                 :           0 :         = indirect_thunk_need_prefix (current_output_insn);
   17067                 :           0 :       unsigned int regno = REGNO (ret_op);
   17068                 :           0 :       gcc_assert (regno == CX_REG);
   17069                 :             : 
   17070                 :           0 :       if (cfun->machine->function_return_type
   17071                 :           0 :           != indirect_branch_thunk_inline)
   17072                 :             :         {
   17073                 :           0 :           bool need_thunk = (cfun->machine->function_return_type
   17074                 :             :                              == indirect_branch_thunk);
   17075                 :           0 :           indirect_thunk_name (thunk_name, regno, need_prefix, true);
   17076                 :             : 
   17077                 :           0 :           if (need_thunk)
   17078                 :             :             {
   17079                 :           0 :               indirect_return_via_cx = true;
   17080                 :           0 :               SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
   17081                 :             :             }
   17082                 :           0 :           fprintf (asm_out_file, "\tjmp\t");
   17083                 :           0 :           assemble_name (asm_out_file, thunk_name);
   17084                 :           0 :           putc ('\n', asm_out_file);
   17085                 :             :         }
   17086                 :             :       else
   17087                 :           0 :         output_indirect_thunk (regno);
   17088                 :             :     }
   17089                 :             :   else
   17090                 :             :     {
   17091                 :          17 :       output_asm_insn ("%!jmp\t%A0", &ret_op);
   17092                 :          17 :       if (ix86_harden_sls & harden_sls_indirect_jmp)
   17093                 :           1 :         fputs ("\tint3\n", asm_out_file);
   17094                 :             :     }
   17095                 :          17 :   return "";
   17096                 :             : }
   17097                 :             : 
   17098                 :             : /* Output the assembly for a call instruction.  */
   17099                 :             : 
   17100                 :             : const char *
   17101                 :     5867980 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
   17102                 :             : {
   17103                 :     5867980 :   bool direct_p = constant_call_address_operand (call_op, VOIDmode);
   17104                 :     5867980 :   bool output_indirect_p
   17105                 :             :     = (!TARGET_SEH
   17106                 :     5867980 :        && cfun->machine->indirect_branch_type != indirect_branch_keep);
   17107                 :     5867980 :   bool seh_nop_p = false;
   17108                 :     5867980 :   const char *xasm;
   17109                 :             : 
   17110                 :     5867980 :   if (SIBLING_CALL_P (insn))
   17111                 :             :     {
   17112                 :      118933 :       output_return_instrumentation ();
   17113                 :      118933 :       if (direct_p)
   17114                 :             :         {
   17115                 :      110157 :           if (ix86_nopic_noplt_attribute_p (call_op))
   17116                 :             :             {
   17117                 :           4 :               direct_p = false;
   17118                 :           4 :               if (TARGET_64BIT)
   17119                 :             :                 {
   17120                 :           4 :                   if (output_indirect_p)
   17121                 :             :                     xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17122                 :             :                   else
   17123                 :           4 :                     xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17124                 :             :                 }
   17125                 :             :               else
   17126                 :             :                 {
   17127                 :           0 :                   if (output_indirect_p)
   17128                 :             :                     xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17129                 :             :                   else
   17130                 :           0 :                     xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17131                 :             :                 }
   17132                 :             :             }
   17133                 :             :           else
   17134                 :             :             xasm = "%!jmp\t%P0";
   17135                 :             :         }
   17136                 :             :       /* SEH epilogue detection requires the indirect branch case
   17137                 :             :          to include REX.W.  */
   17138                 :        8776 :       else if (TARGET_SEH)
   17139                 :             :         xasm = "%!rex.W jmp\t%A0";
   17140                 :             :       else
   17141                 :             :         {
   17142                 :        8776 :           if (output_indirect_p)
   17143                 :             :             xasm = "%0";
   17144                 :             :           else
   17145                 :        8753 :             xasm = "%!jmp\t%A0";
   17146                 :             :         }
   17147                 :             : 
   17148                 :      118933 :       if (output_indirect_p && !direct_p)
   17149                 :          23 :         ix86_output_indirect_branch (call_op, xasm, true);
   17150                 :             :       else
   17151                 :             :         {
   17152                 :      118910 :           output_asm_insn (xasm, &call_op);
   17153                 :      118910 :           if (!direct_p
   17154                 :        8757 :               && (ix86_harden_sls & harden_sls_indirect_jmp))
   17155                 :             :             return "int3";
   17156                 :             :         }
   17157                 :      118932 :       return "";
   17158                 :             :     }
   17159                 :             : 
   17160                 :             :   /* SEH unwinding can require an extra nop to be emitted in several
   17161                 :             :      circumstances.  Determine if we have one of those.  */
   17162                 :     5749047 :   if (TARGET_SEH)
   17163                 :             :     {
   17164                 :             :       rtx_insn *i;
   17165                 :             : 
   17166                 :             :       for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
   17167                 :             :         {
   17168                 :             :           /* Prevent a catch region from being adjacent to a jump that would
   17169                 :             :              be interpreted as an epilogue sequence by the unwinder.  */
   17170                 :             :           if (JUMP_P(i) && CROSSING_JUMP_P (i))
   17171                 :             :             {
   17172                 :             :               seh_nop_p = true;
   17173                 :             :               break;
   17174                 :             :             }
   17175                 :             : 
   17176                 :             :           /* If we get to another real insn, we don't need the nop.  */
   17177                 :             :           if (INSN_P (i))
   17178                 :             :             break;
   17179                 :             : 
   17180                 :             :           /* If we get to the epilogue note, prevent a catch region from
   17181                 :             :              being adjacent to the standard epilogue sequence.  Note that,
   17182                 :             :              if non-call exceptions are enabled, we already did it during
   17183                 :             :              epilogue expansion, or else, if the insn can throw internally,
   17184                 :             :              we already did it during the reorg pass.  */
   17185                 :             :           if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
   17186                 :             :               && !flag_non_call_exceptions
   17187                 :             :               && !can_throw_internal (insn))
   17188                 :             :             {
   17189                 :             :               seh_nop_p = true;
   17190                 :             :               break;
   17191                 :             :             }
   17192                 :             :         }
   17193                 :             : 
   17194                 :             :       /* If we didn't find a real insn following the call, prevent the
   17195                 :             :          unwinder from looking into the next function.  */
   17196                 :             :       if (i == NULL)
   17197                 :             :         seh_nop_p = true;
   17198                 :             :     }
   17199                 :             : 
   17200                 :     5749047 :   if (direct_p)
   17201                 :             :     {
   17202                 :     5577035 :       if (ix86_nopic_noplt_attribute_p (call_op))
   17203                 :             :         {
   17204                 :           6 :           direct_p = false;
   17205                 :           6 :           if (TARGET_64BIT)
   17206                 :             :             {
   17207                 :           6 :               if (output_indirect_p)
   17208                 :             :                 xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17209                 :             :               else
   17210                 :           6 :                 xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17211                 :             :             }
   17212                 :             :           else
   17213                 :             :             {
   17214                 :           0 :               if (output_indirect_p)
   17215                 :             :                 xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17216                 :             :               else
   17217                 :           0 :                 xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17218                 :             :             }
   17219                 :             :         }
   17220                 :             :       else
   17221                 :             :         xasm = "%!call\t%P0";
   17222                 :             :     }
   17223                 :             :   else
   17224                 :             :     {
   17225                 :      172012 :       if (output_indirect_p)
   17226                 :             :         xasm = "%0";
   17227                 :             :       else
   17228                 :      171989 :         xasm = "%!call\t%A0";
   17229                 :             :     }
   17230                 :             : 
   17231                 :     5749047 :   if (output_indirect_p && !direct_p)
   17232                 :          23 :     ix86_output_indirect_branch (call_op, xasm, false);
   17233                 :             :   else
   17234                 :     5749024 :     output_asm_insn (xasm, &call_op);
   17235                 :             : 
   17236                 :             :   if (seh_nop_p)
   17237                 :             :     return "nop";
   17238                 :             : 
   17239                 :             :   return "";
   17240                 :             : }
   17241                 :             : 
   17242                 :             : /* Return a MEM corresponding to a stack slot with mode MODE.
   17243                 :             :    Allocate a new slot if necessary.
   17244                 :             : 
   17245                 :             :    The RTL for a function can have several slots available: N is
   17246                 :             :    which slot to use.  */
   17247                 :             : 
   17248                 :             : rtx
   17249                 :       22563 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
   17250                 :             : {
   17251                 :       22563 :   struct stack_local_entry *s;
   17252                 :             : 
   17253                 :       22563 :   gcc_assert (n < MAX_386_STACK_LOCALS);
   17254                 :             : 
   17255                 :       34063 :   for (s = ix86_stack_locals; s; s = s->next)
   17256                 :       31424 :     if (s->mode == mode && s->n == n)
   17257                 :       19924 :       return validize_mem (copy_rtx (s->rtl));
   17258                 :             : 
   17259                 :        2639 :   int align = 0;
   17260                 :             :   /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
   17261                 :             :      alignment with -m32 -mpreferred-stack-boundary=2.  */
   17262                 :        2639 :   if (mode == DImode
   17263                 :         343 :       && !TARGET_64BIT
   17264                 :         343 :       && n == SLOT_FLOATxFDI_387
   17265                 :        2982 :       && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
   17266                 :             :     align = 32;
   17267                 :        2639 :   s = ggc_alloc<stack_local_entry> ();
   17268                 :        2639 :   s->n = n;
   17269                 :        2639 :   s->mode = mode;
   17270                 :        5278 :   s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
   17271                 :             : 
   17272                 :        2639 :   s->next = ix86_stack_locals;
   17273                 :        2639 :   ix86_stack_locals = s;
   17274                 :        2639 :   return validize_mem (copy_rtx (s->rtl));
   17275                 :             : }
   17276                 :             : 
   17277                 :             : static void
   17278                 :     1433096 : ix86_instantiate_decls (void)
   17279                 :             : {
   17280                 :     1433096 :   struct stack_local_entry *s;
   17281                 :             : 
   17282                 :     1433096 :   for (s = ix86_stack_locals; s; s = s->next)
   17283                 :           0 :     if (s->rtl != NULL_RTX)
   17284                 :           0 :       instantiate_decl_rtl (s->rtl);
   17285                 :     1433096 : }
   17286                 :             : 
   17287                 :             : /* Check whether x86 address PARTS is a pc-relative address.  */
   17288                 :             : 
   17289                 :             : bool
   17290                 :    23119837 : ix86_rip_relative_addr_p (struct ix86_address *parts)
   17291                 :             : {
   17292                 :    23119837 :   rtx base, index, disp;
   17293                 :             : 
   17294                 :    23119837 :   base = parts->base;
   17295                 :    23119837 :   index = parts->index;
   17296                 :    23119837 :   disp = parts->disp;
   17297                 :             : 
   17298                 :    23119837 :   if (disp && !base && !index)
   17299                 :             :     {
   17300                 :    22543547 :       if (TARGET_64BIT)
   17301                 :             :         {
   17302                 :    21052957 :           rtx symbol = disp;
   17303                 :             : 
   17304                 :    21052957 :           if (GET_CODE (disp) == CONST)
   17305                 :     5935585 :             symbol = XEXP (disp, 0);
   17306                 :    21052957 :           if (GET_CODE (symbol) == PLUS
   17307                 :     5447885 :               && CONST_INT_P (XEXP (symbol, 1)))
   17308                 :     5447885 :             symbol = XEXP (symbol, 0);
   17309                 :             : 
   17310                 :    21052957 :           if (GET_CODE (symbol) == LABEL_REF
   17311                 :    21045728 :               || (GET_CODE (symbol) == SYMBOL_REF
   17312                 :    19950940 :                   && SYMBOL_REF_TLS_MODEL (symbol) == 0)
   17313                 :    22147745 :               || (GET_CODE (symbol) == UNSPEC
   17314                 :      505957 :                   && (XINT (symbol, 1) == UNSPEC_GOTPCREL
   17315                 :             :                       || XINT (symbol, 1) == UNSPEC_PCREL
   17316                 :             :                       || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
   17317                 :    20438416 :             return true;
   17318                 :             :         }
   17319                 :             :     }
   17320                 :             :   return false;
   17321                 :             : }
   17322                 :             : 
   17323                 :             : /* Calculate the length of the memory address in the instruction encoding.
   17324                 :             :    Includes addr32 prefix, does not include the one-byte modrm, opcode,
   17325                 :             :    or other prefixes.  We never generate addr32 prefix for LEA insn.  */
   17326                 :             : 
   17327                 :             : int
   17328                 :   238116445 : memory_address_length (rtx addr, bool lea)
   17329                 :             : {
   17330                 :   238116445 :   struct ix86_address parts;
   17331                 :   238116445 :   rtx base, index, disp;
   17332                 :   238116445 :   int len;
   17333                 :   238116445 :   int ok;
   17334                 :             : 
   17335                 :   238116445 :   if (GET_CODE (addr) == PRE_DEC
   17336                 :   229280704 :       || GET_CODE (addr) == POST_INC
   17337                 :   224074731 :       || GET_CODE (addr) == PRE_MODIFY
   17338                 :   224074731 :       || GET_CODE (addr) == POST_MODIFY)
   17339                 :             :     return 0;
   17340                 :             : 
   17341                 :   224074731 :   ok = ix86_decompose_address (addr, &parts);
   17342                 :   224074731 :   gcc_assert (ok);
   17343                 :             : 
   17344                 :   224074731 :   len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
   17345                 :             : 
   17346                 :             :   /*  If this is not LEA instruction, add the length of addr32 prefix.  */
   17347                 :   187178864 :   if (TARGET_64BIT && !lea
   17348                 :   388446850 :       && (SImode_address_operand (addr, VOIDmode)
   17349                 :   164372029 :           || (parts.base && GET_MODE (parts.base) == SImode)
   17350                 :   164371395 :           || (parts.index && GET_MODE (parts.index) == SImode)))
   17351                 :         724 :     len++;
   17352                 :             : 
   17353                 :   224074731 :   base = parts.base;
   17354                 :   224074731 :   index = parts.index;
   17355                 :   224074731 :   disp = parts.disp;
   17356                 :             : 
   17357                 :   224074731 :   if (base && SUBREG_P (base))
   17358                 :           2 :     base = SUBREG_REG (base);
   17359                 :   224074731 :   if (index && SUBREG_P (index))
   17360                 :           0 :     index = SUBREG_REG (index);
   17361                 :             : 
   17362                 :   224074731 :   gcc_assert (base == NULL_RTX || REG_P (base));
   17363                 :   224074731 :   gcc_assert (index == NULL_RTX || REG_P (index));
   17364                 :             : 
   17365                 :             :   /* Rule of thumb:
   17366                 :             :        - esp as the base always wants an index,
   17367                 :             :        - ebp as the base always wants a displacement,
   17368                 :             :        - r12 as the base always wants an index,
   17369                 :             :        - r13 as the base always wants a displacement.  */
   17370                 :             : 
   17371                 :             :   /* Register Indirect.  */
   17372                 :   224074731 :   if (base && !index && !disp)
   17373                 :             :     {
   17374                 :             :       /* esp (for its index) and ebp (for its displacement) need
   17375                 :             :          the two-byte modrm form.  Similarly for r12 and r13 in 64-bit
   17376                 :             :          code.  */
   17377                 :    14709365 :       if (base == arg_pointer_rtx
   17378                 :    14709365 :           || base == frame_pointer_rtx
   17379                 :    14709365 :           || REGNO (base) == SP_REG
   17380                 :     9091979 :           || REGNO (base) == BP_REG
   17381                 :     9091979 :           || REGNO (base) == R12_REG
   17382                 :    23401329 :           || REGNO (base) == R13_REG)
   17383                 :     6017401 :         len++;
   17384                 :             :     }
   17385                 :             : 
   17386                 :             :   /* Direct Addressing.  In 64-bit mode mod 00 r/m 5
   17387                 :             :      is not disp32, but disp32(%rip), so for disp32
   17388                 :             :      SIB byte is needed, unless print_operand_address
   17389                 :             :      optimizes it into disp32(%rip) or (%rip) is implied
   17390                 :             :      by UNSPEC.  */
   17391                 :   209365366 :   else if (disp && !base && !index)
   17392                 :             :     {
   17393                 :    22234339 :       len += 4;
   17394                 :    22234339 :       if (!ix86_rip_relative_addr_p (&parts))
   17395                 :     1862448 :         len++;
   17396                 :             :     }
   17397                 :             :   else
   17398                 :             :     {
   17399                 :             :       /* Find the length of the displacement constant.  */
   17400                 :   187131027 :       if (disp)
   17401                 :             :         {
   17402                 :   183516416 :           if (base && satisfies_constraint_K (disp))
   17403                 :   104141611 :             len += 1;
   17404                 :             :           else
   17405                 :    79374805 :             len += 4;
   17406                 :             :         }
   17407                 :             :       /* ebp always wants a displacement.  Similarly r13.  */
   17408                 :     3614611 :       else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
   17409                 :        8535 :         len++;
   17410                 :             : 
   17411                 :             :       /* An index requires the two-byte modrm form....  */
   17412                 :   187131027 :       if (index
   17413                 :             :           /* ...like esp (or r12), which always wants an index.  */
   17414                 :   179133896 :           || base == arg_pointer_rtx
   17415                 :   179133896 :           || base == frame_pointer_rtx
   17416                 :   366264923 :           || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
   17417                 :   131543901 :         len++;
   17418                 :             :     }
   17419                 :             : 
   17420                 :             :   return len;
   17421                 :             : }
   17422                 :             : 
   17423                 :             : /* Compute default value for "length_immediate" attribute.  When SHORTFORM
   17424                 :             :    is set, expect that insn have 8bit immediate alternative.  */
   17425                 :             : int
   17426                 :   281295966 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
   17427                 :             : {
   17428                 :   281295966 :   int len = 0;
   17429                 :   281295966 :   int i;
   17430                 :   281295966 :   extract_insn_cached (insn);
   17431                 :   879786757 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17432                 :   598490791 :     if (CONSTANT_P (recog_data.operand[i]))
   17433                 :             :       {
   17434                 :   124453014 :         enum attr_mode mode = get_attr_mode (insn);
   17435                 :             : 
   17436                 :   124453014 :         gcc_assert (!len);
   17437                 :   124453014 :         if (shortform && CONST_INT_P (recog_data.operand[i]))
   17438                 :             :           {
   17439                 :    33562554 :             HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
   17440                 :    33562554 :             switch (mode)
   17441                 :             :               {
   17442                 :      984816 :               case MODE_QI:
   17443                 :      984816 :                 len = 1;
   17444                 :      984816 :                 continue;
   17445                 :      376821 :               case MODE_HI:
   17446                 :      376821 :                 ival = trunc_int_for_mode (ival, HImode);
   17447                 :      376821 :                 break;
   17448                 :    14805039 :               case MODE_SI:
   17449                 :    14805039 :                 ival = trunc_int_for_mode (ival, SImode);
   17450                 :    14805039 :                 break;
   17451                 :             :               default:
   17452                 :             :                 break;
   17453                 :             :               }
   17454                 :    32577738 :             if (IN_RANGE (ival, -128, 127))
   17455                 :             :               {
   17456                 :    28959138 :                 len = 1;
   17457                 :    28959138 :                 continue;
   17458                 :             :               }
   17459                 :             :           }
   17460                 :    94509060 :         switch (mode)
   17461                 :             :           {
   17462                 :             :           case MODE_QI:
   17463                 :             :             len = 1;
   17464                 :             :             break;
   17465                 :             :           case MODE_HI:
   17466                 :   598490791 :             len = 2;
   17467                 :             :             break;
   17468                 :             :           case MODE_SI:
   17469                 :    89645531 :             len = 4;
   17470                 :             :             break;
   17471                 :             :           /* Immediates for DImode instructions are encoded
   17472                 :             :              as 32bit sign extended values.  */
   17473                 :             :           case MODE_DI:
   17474                 :    89645531 :             len = 4;
   17475                 :             :             break;
   17476                 :           0 :           default:
   17477                 :           0 :             fatal_insn ("unknown insn mode", insn);
   17478                 :             :         }
   17479                 :             :       }
   17480                 :   281295966 :   return len;
   17481                 :             : }
   17482                 :             : 
   17483                 :             : /* Compute default value for "length_address" attribute.  */
   17484                 :             : int
   17485                 :   399142946 : ix86_attr_length_address_default (rtx_insn *insn)
   17486                 :             : {
   17487                 :   399142946 :   int i;
   17488                 :             : 
   17489                 :   399142946 :   if (get_attr_type (insn) == TYPE_LEA)
   17490                 :             :     {
   17491                 :    25490518 :       rtx set = PATTERN (insn), addr;
   17492                 :             : 
   17493                 :    25490518 :       if (GET_CODE (set) == PARALLEL)
   17494                 :       86385 :         set = XVECEXP (set, 0, 0);
   17495                 :             : 
   17496                 :    25490518 :       gcc_assert (GET_CODE (set) == SET);
   17497                 :             : 
   17498                 :    25490518 :       addr = SET_SRC (set);
   17499                 :             : 
   17500                 :    25490518 :       return memory_address_length (addr, true);
   17501                 :             :     }
   17502                 :             : 
   17503                 :   373652428 :   extract_insn_cached (insn);
   17504                 :   866403836 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17505                 :             :     {
   17506                 :   705108150 :       rtx op = recog_data.operand[i];
   17507                 :   705108150 :       if (MEM_P (op))
   17508                 :             :         {
   17509                 :   212663503 :           constrain_operands_cached (insn, reload_completed);
   17510                 :   212663503 :           if (which_alternative != -1)
   17511                 :             :             {
   17512                 :   212663503 :               const char *constraints = recog_data.constraints[i];
   17513                 :   212663503 :               int alt = which_alternative;
   17514                 :             : 
   17515                 :   335250738 :               while (*constraints == '=' || *constraints == '+')
   17516                 :   122587235 :                 constraints++;
   17517                 :   949341935 :               while (alt-- > 0)
   17518                 :  1815654899 :                 while (*constraints++ != ',')
   17519                 :             :                   ;
   17520                 :             :               /* Skip ignored operands.  */
   17521                 :   212663503 :               if (*constraints == 'X')
   17522                 :      306761 :                 continue;
   17523                 :             :             }
   17524                 :             : 
   17525                 :   212356742 :           int len = memory_address_length (XEXP (op, 0), false);
   17526                 :             : 
   17527                 :             :           /* Account for segment prefix for non-default addr spaces.  */
   17528                 :   223597835 :           if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
   17529                 :      777034 :             len++;
   17530                 :             : 
   17531                 :   212356742 :           return len;
   17532                 :             :         }
   17533                 :             :     }
   17534                 :             :   return 0;
   17535                 :             : }
   17536                 :             : 
   17537                 :             : /* Compute default value for "length_vex" attribute. It includes
   17538                 :             :    2 or 3 byte VEX prefix and 1 opcode byte.  */
   17539                 :             : 
   17540                 :             : int
   17541                 :     4762370 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
   17542                 :             :                               bool has_vex_w)
   17543                 :             : {
   17544                 :     4762370 :   int i, reg_only = 2 + 1;
   17545                 :     4762370 :   bool has_mem = false;
   17546                 :             : 
   17547                 :             :   /* Only 0f opcode can use 2 byte VEX prefix and  VEX W bit uses 3
   17548                 :             :      byte VEX prefix.  */
   17549                 :     4762370 :   if (!has_0f_opcode || has_vex_w)
   17550                 :             :     return 3 + 1;
   17551                 :             : 
   17552                 :             :  /* We can always use 2 byte VEX prefix in 32bit.  */
   17553                 :     4370418 :   if (!TARGET_64BIT)
   17554                 :             :     return 2 + 1;
   17555                 :             : 
   17556                 :     3271685 :   extract_insn_cached (insn);
   17557                 :             : 
   17558                 :    10261718 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17559                 :     7310968 :     if (REG_P (recog_data.operand[i]))
   17560                 :             :       {
   17561                 :             :         /* REX.W bit uses 3 byte VEX prefix.
   17562                 :             :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   17563                 :     4804817 :         if (GET_MODE (recog_data.operand[i]) == DImode
   17564                 :     4804817 :             && GENERAL_REG_P (recog_data.operand[i]))
   17565                 :             :           return 3 + 1;
   17566                 :             : 
   17567                 :             :         /* REX.B bit requires 3-byte VEX. Right here we don't know which
   17568                 :             :            operand will be encoded using VEX.B, so be conservative.
   17569                 :             :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   17570                 :     4787391 :         if (REX_INT_REGNO_P (recog_data.operand[i])
   17571                 :     4787391 :             || REX2_INT_REGNO_P (recog_data.operand[i])
   17572                 :     4787391 :             || REX_SSE_REGNO_P (recog_data.operand[i]))
   17573                 :           0 :           reg_only = 3 + 1;
   17574                 :             :       }
   17575                 :     2506151 :     else if (MEM_P (recog_data.operand[i]))
   17576                 :             :       {
   17577                 :             :         /* REX2.X or REX2.B bits use 3 byte VEX prefix.  */
   17578                 :     1881744 :         if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
   17579                 :             :           return 4;
   17580                 :             : 
   17581                 :             :         /* REX.X or REX.B bits use 3 byte VEX prefix.  */
   17582                 :     1881503 :         if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
   17583                 :             :           return 3 + 1;
   17584                 :             : 
   17585                 :             :         has_mem = true;
   17586                 :             :       }
   17587                 :             : 
   17588                 :     2950750 :   return has_mem ? 2 + 1 : reg_only;
   17589                 :             : }
   17590                 :             : 
   17591                 :             : 
   17592                 :             : static bool
   17593                 :             : ix86_class_likely_spilled_p (reg_class_t);
   17594                 :             : 
   17595                 :             : /* Returns true if lhs of insn is HW function argument register and set up
   17596                 :             :    is_spilled to true if it is likely spilled HW register.  */
   17597                 :             : static bool
   17598                 :        1233 : insn_is_function_arg (rtx insn, bool* is_spilled)
   17599                 :             : {
   17600                 :        1233 :   rtx dst;
   17601                 :             : 
   17602                 :        1233 :   if (!NONDEBUG_INSN_P (insn))
   17603                 :             :     return false;
   17604                 :             :   /* Call instructions are not movable, ignore it.  */
   17605                 :        1233 :   if (CALL_P (insn))
   17606                 :             :     return false;
   17607                 :        1161 :   insn = PATTERN (insn);
   17608                 :        1161 :   if (GET_CODE (insn) == PARALLEL)
   17609                 :          76 :     insn = XVECEXP (insn, 0, 0);
   17610                 :        1161 :   if (GET_CODE (insn) != SET)
   17611                 :             :     return false;
   17612                 :        1161 :   dst = SET_DEST (insn);
   17613                 :        1051 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   17614                 :        2109 :       && ix86_function_arg_regno_p (REGNO (dst)))
   17615                 :             :     {
   17616                 :             :       /* Is it likely spilled HW register?  */
   17617                 :         948 :       if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
   17618                 :         948 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
   17619                 :         894 :         *is_spilled = true;
   17620                 :         948 :       return true;
   17621                 :             :     }
   17622                 :             :   return false;
   17623                 :             : }
   17624                 :             : 
   17625                 :             : /* Add output dependencies for chain of function adjacent arguments if only
   17626                 :             :    there is a move to likely spilled HW register.  Return first argument
   17627                 :             :    if at least one dependence was added or NULL otherwise.  */
   17628                 :             : static rtx_insn *
   17629                 :         443 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
   17630                 :             : {
   17631                 :         443 :   rtx_insn *insn;
   17632                 :         443 :   rtx_insn *last = call;
   17633                 :         443 :   rtx_insn *first_arg = NULL;
   17634                 :         443 :   bool is_spilled = false;
   17635                 :             : 
   17636                 :         443 :   head = PREV_INSN (head);
   17637                 :             : 
   17638                 :             :   /* Find nearest to call argument passing instruction.  */
   17639                 :         443 :   while (true)
   17640                 :             :     {
   17641                 :         443 :       last = PREV_INSN (last);
   17642                 :         443 :       if (last == head)
   17643                 :             :         return NULL;
   17644                 :         443 :       if (!NONDEBUG_INSN_P (last))
   17645                 :           0 :         continue;
   17646                 :         443 :       if (insn_is_function_arg (last, &is_spilled))
   17647                 :             :         break;
   17648                 :             :       return NULL;
   17649                 :             :     }
   17650                 :             : 
   17651                 :             :   first_arg = last;
   17652                 :        1223 :   while (true)
   17653                 :             :     {
   17654                 :        1223 :       insn = PREV_INSN (last);
   17655                 :        1223 :       if (!INSN_P (insn))
   17656                 :             :         break;
   17657                 :        1106 :       if (insn == head)
   17658                 :             :         break;
   17659                 :        1065 :       if (!NONDEBUG_INSN_P (insn))
   17660                 :             :         {
   17661                 :         275 :           last = insn;
   17662                 :         275 :           continue;
   17663                 :             :         }
   17664                 :         790 :       if (insn_is_function_arg (insn, &is_spilled))
   17665                 :             :         {
   17666                 :             :           /* Add output depdendence between two function arguments if chain
   17667                 :             :              of output arguments contains likely spilled HW registers.  */
   17668                 :         517 :           if (is_spilled)
   17669                 :         517 :             add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   17670                 :             :           first_arg = last = insn;
   17671                 :             :         }
   17672                 :             :       else
   17673                 :             :         break;
   17674                 :             :     }
   17675                 :         431 :   if (!is_spilled)
   17676                 :             :     return NULL;
   17677                 :             :   return first_arg;
   17678                 :             : }
   17679                 :             : 
   17680                 :             : /* Add output or anti dependency from insn to first_arg to restrict its code
   17681                 :             :    motion.  */
   17682                 :             : static void
   17683                 :        2533 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
   17684                 :             : {
   17685                 :        2533 :   rtx set;
   17686                 :        2533 :   rtx tmp;
   17687                 :             : 
   17688                 :        2533 :   set = single_set (insn);
   17689                 :        2533 :   if (!set)
   17690                 :             :     return;
   17691                 :        1533 :   tmp = SET_DEST (set);
   17692                 :        1533 :   if (REG_P (tmp))
   17693                 :             :     {
   17694                 :             :       /* Add output dependency to the first function argument.  */
   17695                 :        1284 :       add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   17696                 :        1284 :       return;
   17697                 :             :     }
   17698                 :             :   /* Add anti dependency.  */
   17699                 :         249 :   add_dependence (first_arg, insn, REG_DEP_ANTI);
   17700                 :             : }
   17701                 :             : 
   17702                 :             : /* Avoid cross block motion of function argument through adding dependency
   17703                 :             :    from the first non-jump instruction in bb.  */
   17704                 :             : static void
   17705                 :          68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
   17706                 :             : {
   17707                 :          68 :   rtx_insn *insn = BB_END (bb);
   17708                 :             : 
   17709                 :         134 :   while (insn)
   17710                 :             :     {
   17711                 :         134 :       if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
   17712                 :             :         {
   17713                 :          67 :           rtx set = single_set (insn);
   17714                 :          67 :           if (set)
   17715                 :             :             {
   17716                 :          67 :               avoid_func_arg_motion (arg, insn);
   17717                 :          67 :               return;
   17718                 :             :             }
   17719                 :             :         }
   17720                 :          67 :       if (insn == BB_HEAD (bb))
   17721                 :             :         return;
   17722                 :          66 :       insn = PREV_INSN (insn);
   17723                 :             :     }
   17724                 :             : }
   17725                 :             : 
   17726                 :             : /* Hook for pre-reload schedule - avoid motion of function arguments
   17727                 :             :    passed in likely spilled HW registers.  */
   17728                 :             : static void
   17729                 :     9566162 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
   17730                 :             : {
   17731                 :     9566162 :   rtx_insn *insn;
   17732                 :     9566162 :   rtx_insn *first_arg = NULL;
   17733                 :     9566162 :   if (reload_completed)
   17734                 :             :     return;
   17735                 :        2263 :   while (head != tail && DEBUG_INSN_P (head))
   17736                 :         794 :     head = NEXT_INSN (head);
   17737                 :        9873 :   for (insn = tail; insn != head; insn = PREV_INSN (insn))
   17738                 :        8549 :     if (INSN_P (insn) && CALL_P (insn))
   17739                 :             :       {
   17740                 :         443 :         first_arg = add_parameter_dependencies (insn, head);
   17741                 :         443 :         if (first_arg)
   17742                 :             :           {
   17743                 :             :             /* Add dependee for first argument to predecessors if only
   17744                 :             :                region contains more than one block.  */
   17745                 :         431 :             basic_block bb =  BLOCK_FOR_INSN (insn);
   17746                 :         431 :             int rgn = CONTAINING_RGN (bb->index);
   17747                 :         431 :             int nr_blks = RGN_NR_BLOCKS (rgn);
   17748                 :             :             /* Skip trivial regions and region head blocks that can have
   17749                 :             :                predecessors outside of region.  */
   17750                 :         431 :             if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
   17751                 :             :               {
   17752                 :          67 :                 edge e;
   17753                 :          67 :                 edge_iterator ei;
   17754                 :             : 
   17755                 :             :                 /* Regions are SCCs with the exception of selective
   17756                 :             :                    scheduling with pipelining of outer blocks enabled.
   17757                 :             :                    So also check that immediate predecessors of a non-head
   17758                 :             :                    block are in the same region.  */
   17759                 :         137 :                 FOR_EACH_EDGE (e, ei, bb->preds)
   17760                 :             :                   {
   17761                 :             :                     /* Avoid creating of loop-carried dependencies through
   17762                 :             :                        using topological ordering in the region.  */
   17763                 :          70 :                     if (rgn == CONTAINING_RGN (e->src->index)
   17764                 :          69 :                         && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
   17765                 :          68 :                       add_dependee_for_func_arg (first_arg, e->src);
   17766                 :             :                   }
   17767                 :             :               }
   17768                 :         431 :             insn = first_arg;
   17769                 :         431 :             if (insn == head)
   17770                 :             :               break;
   17771                 :             :           }
   17772                 :             :       }
   17773                 :        8106 :     else if (first_arg)
   17774                 :        2466 :       avoid_func_arg_motion (first_arg, insn);
   17775                 :             : }
   17776                 :             : 
   17777                 :             : /* Hook for pre-reload schedule - set priority of moves from likely spilled
   17778                 :             :    HW registers to maximum, to schedule them at soon as possible. These are
   17779                 :             :    moves from function argument registers at the top of the function entry
   17780                 :             :    and moves from function return value registers after call.  */
   17781                 :             : static int
   17782                 :    96490198 : ix86_adjust_priority (rtx_insn *insn, int priority)
   17783                 :             : {
   17784                 :    96490198 :   rtx set;
   17785                 :             : 
   17786                 :    96490198 :   if (reload_completed)
   17787                 :             :     return priority;
   17788                 :             : 
   17789                 :       13692 :   if (!NONDEBUG_INSN_P (insn))
   17790                 :             :     return priority;
   17791                 :             : 
   17792                 :       11463 :   set = single_set (insn);
   17793                 :       11463 :   if (set)
   17794                 :             :     {
   17795                 :       10903 :       rtx tmp = SET_SRC (set);
   17796                 :       10903 :       if (REG_P (tmp)
   17797                 :        2323 :           && HARD_REGISTER_P (tmp)
   17798                 :         503 :           && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
   17799                 :       10903 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
   17800                 :         453 :         return current_sched_info->sched_max_insns_priority;
   17801                 :             :     }
   17802                 :             : 
   17803                 :             :   return priority;
   17804                 :             : }
   17805                 :             : 
   17806                 :             : /* Prepare for scheduling pass.  */
   17807                 :             : static void
   17808                 :      929912 : ix86_sched_init_global (FILE *, int, int)
   17809                 :             : {
   17810                 :             :   /* Install scheduling hooks for current CPU.  Some of these hooks are used
   17811                 :             :      in time-critical parts of the scheduler, so we only set them up when
   17812                 :             :      they are actually used.  */
   17813                 :      929912 :   switch (ix86_tune)
   17814                 :             :     {
   17815                 :      881677 :     case PROCESSOR_CORE2:
   17816                 :      881677 :     case PROCESSOR_NEHALEM:
   17817                 :      881677 :     case PROCESSOR_SANDYBRIDGE:
   17818                 :      881677 :     case PROCESSOR_HASWELL:
   17819                 :      881677 :     case PROCESSOR_TREMONT:
   17820                 :      881677 :     case PROCESSOR_ALDERLAKE:
   17821                 :      881677 :     case PROCESSOR_GENERIC:
   17822                 :             :       /* Do not perform multipass scheduling for pre-reload schedule
   17823                 :             :          to save compile time.  */
   17824                 :      881677 :       if (reload_completed)
   17825                 :             :         {
   17826                 :      881361 :           ix86_core2i7_init_hooks ();
   17827                 :      881361 :           break;
   17828                 :             :         }
   17829                 :             :       /* Fall through.  */
   17830                 :       48551 :     default:
   17831                 :       48551 :       targetm.sched.dfa_post_advance_cycle = NULL;
   17832                 :       48551 :       targetm.sched.first_cycle_multipass_init = NULL;
   17833                 :       48551 :       targetm.sched.first_cycle_multipass_begin = NULL;
   17834                 :       48551 :       targetm.sched.first_cycle_multipass_issue = NULL;
   17835                 :       48551 :       targetm.sched.first_cycle_multipass_backtrack = NULL;
   17836                 :       48551 :       targetm.sched.first_cycle_multipass_end = NULL;
   17837                 :       48551 :       targetm.sched.first_cycle_multipass_fini = NULL;
   17838                 :       48551 :       break;
   17839                 :             :     }
   17840                 :      929912 : }
   17841                 :             : 
   17842                 :             : 
   17843                 :             : /* Implement TARGET_STATIC_RTX_ALIGNMENT.  */
   17844                 :             : 
   17845                 :             : static HOST_WIDE_INT
   17846                 :      706191 : ix86_static_rtx_alignment (machine_mode mode)
   17847                 :             : {
   17848                 :      706191 :   if (mode == DFmode)
   17849                 :             :     return 64;
   17850                 :             :   if (ALIGN_MODE_128 (mode))
   17851                 :      151074 :     return MAX (128, GET_MODE_ALIGNMENT (mode));
   17852                 :      471195 :   return GET_MODE_ALIGNMENT (mode);
   17853                 :             : }
   17854                 :             : 
   17855                 :             : /* Implement TARGET_CONSTANT_ALIGNMENT.  */
   17856                 :             : 
   17857                 :             : static HOST_WIDE_INT
   17858                 :     6677170 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
   17859                 :             : {
   17860                 :     6677170 :   if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
   17861                 :             :       || TREE_CODE (exp) == INTEGER_CST)
   17862                 :             :     {
   17863                 :      359224 :       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   17864                 :      359224 :       HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
   17865                 :      359224 :       return MAX (mode_align, align);
   17866                 :             :     }
   17867                 :     6179042 :   else if (!optimize_size && TREE_CODE (exp) == STRING_CST
   17868                 :     9266753 :            && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
   17869                 :             :     return BITS_PER_WORD;
   17870                 :             : 
   17871                 :             :   return align;
   17872                 :             : }
   17873                 :             : 
   17874                 :             : /* Implement TARGET_EMPTY_RECORD_P.  */
   17875                 :             : 
   17876                 :             : static bool
   17877                 :  1240198592 : ix86_is_empty_record (const_tree type)
   17878                 :             : {
   17879                 :  1240198592 :   if (!TARGET_64BIT)
   17880                 :             :     return false;
   17881                 :  1210575113 :   return default_is_empty_record (type);
   17882                 :             : }
   17883                 :             : 
   17884                 :             : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI.  */
   17885                 :             : 
   17886                 :             : static void
   17887                 :    14781587 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
   17888                 :             : {
   17889                 :    14781587 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   17890                 :             : 
   17891                 :    14781587 :   if (!cum->warn_empty)
   17892                 :             :     return;
   17893                 :             : 
   17894                 :    14660915 :   if (!TYPE_EMPTY_P (type))
   17895                 :             :     return;
   17896                 :             : 
   17897                 :             :   /* Don't warn if the function isn't visible outside of the TU.  */
   17898                 :       15556 :   if (cum->decl && !TREE_PUBLIC (cum->decl))
   17899                 :             :     return;
   17900                 :             : 
   17901                 :       13968 :   const_tree ctx = get_ultimate_context (cum->decl);
   17902                 :       13968 :   if (ctx != NULL_TREE
   17903                 :       27865 :       && !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
   17904                 :             :     return;
   17905                 :             : 
   17906                 :             :   /* If the actual size of the type is zero, then there is no change
   17907                 :             :      in how objects of this size are passed.  */
   17908                 :         137 :   if (int_size_in_bytes (type) == 0)
   17909                 :             :     return;
   17910                 :             : 
   17911                 :         106 :   warning (OPT_Wabi, "empty class %qT parameter passing ABI "
   17912                 :             :            "changes in %<-fabi-version=12%> (GCC 8)", type);
   17913                 :             : 
   17914                 :             :   /* Only warn once.  */
   17915                 :         106 :   cum->warn_empty = false;
   17916                 :             : }
   17917                 :             : 
   17918                 :             : /* This hook returns name of multilib ABI.  */
   17919                 :             : 
   17920                 :             : static const char *
   17921                 :     3320571 : ix86_get_multilib_abi_name (void)
   17922                 :             : {
   17923                 :     3320571 :   if (!(TARGET_64BIT_P (ix86_isa_flags)))
   17924                 :             :     return "i386";
   17925                 :     3276615 :   else if (TARGET_X32_P (ix86_isa_flags))
   17926                 :             :     return "x32";
   17927                 :             :   else
   17928                 :     3276615 :     return "x86_64";
   17929                 :             : }
   17930                 :             : 
   17931                 :             : /* Compute the alignment for a variable for Intel MCU psABI.  TYPE is
   17932                 :             :    the data type, and ALIGN is the alignment that the object would
   17933                 :             :    ordinarily have.  */
   17934                 :             : 
   17935                 :             : static int
   17936                 :           0 : iamcu_alignment (tree type, int align)
   17937                 :             : {
   17938                 :           0 :   machine_mode mode;
   17939                 :             : 
   17940                 :           0 :   if (align < 32 || TYPE_USER_ALIGN (type))
   17941                 :             :     return align;
   17942                 :             : 
   17943                 :             :   /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
   17944                 :             :      bytes.  */
   17945                 :           0 :   type = strip_array_types (type);
   17946                 :           0 :   if (TYPE_ATOMIC (type))
   17947                 :             :     return align;
   17948                 :             : 
   17949                 :           0 :   mode = TYPE_MODE (type);
   17950                 :           0 :   switch (GET_MODE_CLASS (mode))
   17951                 :             :     {
   17952                 :             :     case MODE_INT:
   17953                 :             :     case MODE_COMPLEX_INT:
   17954                 :             :     case MODE_COMPLEX_FLOAT:
   17955                 :             :     case MODE_FLOAT:
   17956                 :             :     case MODE_DECIMAL_FLOAT:
   17957                 :             :       return 32;
   17958                 :             :     default:
   17959                 :             :       return align;
   17960                 :             :     }
   17961                 :             : }
   17962                 :             : 
   17963                 :             : /* Compute the alignment for a static variable.
   17964                 :             :    TYPE is the data type, and ALIGN is the alignment that
   17965                 :             :    the object would ordinarily have.  The value of this function is used
   17966                 :             :    instead of that alignment to align the object.  */
   17967                 :             : 
   17968                 :             : int
   17969                 :    11833513 : ix86_data_alignment (tree type, unsigned int align, bool opt)
   17970                 :             : {
   17971                 :             :   /* GCC 4.8 and earlier used to incorrectly assume this alignment even
   17972                 :             :      for symbols from other compilation units or symbols that don't need
   17973                 :             :      to bind locally.  In order to preserve some ABI compatibility with
   17974                 :             :      those compilers, ensure we don't decrease alignment from what we
   17975                 :             :      used to assume.  */
   17976                 :             : 
   17977                 :    11833513 :   unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
   17978                 :             : 
   17979                 :             :   /* A data structure, equal or greater than the size of a cache line
   17980                 :             :      (64 bytes in the Pentium 4 and other recent Intel processors, including
   17981                 :             :      processors based on Intel Core microarchitecture) should be aligned
   17982                 :             :      so that its base address is a multiple of a cache line size.  */
   17983                 :             : 
   17984                 :    23667026 :   unsigned int max_align
   17985                 :    11833513 :     = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
   17986                 :             : 
   17987                 :    14412685 :   if (max_align < BITS_PER_WORD)
   17988                 :           0 :     max_align = BITS_PER_WORD;
   17989                 :             : 
   17990                 :    11833513 :   switch (ix86_align_data_type)
   17991                 :             :     {
   17992                 :    11833513 :     case ix86_align_data_type_abi: opt = false; break;
   17993                 :    11833493 :     case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
   17994                 :             :     case ix86_align_data_type_cacheline: break;
   17995                 :             :     }
   17996                 :             : 
   17997                 :    11833513 :   if (TARGET_IAMCU)
   17998                 :           0 :     align = iamcu_alignment (type, align);
   17999                 :             : 
   18000                 :    11833513 :   if (opt
   18001                 :     5726065 :       && AGGREGATE_TYPE_P (type)
   18002                 :     3667532 :       && TYPE_SIZE (type)
   18003                 :    15501013 :       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
   18004                 :             :     {
   18005                 :     6642831 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
   18006                 :     3667500 :           && align < max_align_compat)
   18007                 :      692169 :         align = max_align_compat;
   18008                 :     7274780 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
   18009                 :     3667500 :           && align < max_align)
   18010                 :       60220 :         align = max_align;
   18011                 :             :     }
   18012                 :             : 
   18013                 :             :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18014                 :             :      to 16byte boundary.  */
   18015                 :    11833513 :   if (TARGET_64BIT)
   18016                 :             :     {
   18017                 :     4817212 :       if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
   18018                 :     3201304 :           && TYPE_SIZE (type)
   18019                 :     3201262 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18020                 :    10661253 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18021                 :    11263890 :           && align < 128)
   18022                 :      602637 :         return 128;
   18023                 :             :     }
   18024                 :             : 
   18025                 :    11230876 :   if (!opt)
   18026                 :     5918211 :     return align;
   18027                 :             : 
   18028                 :     5312665 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18029                 :             :     {
   18030                 :     1082118 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18031                 :             :         return 64;
   18032                 :     1082118 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18033                 :             :         return 128;
   18034                 :             :     }
   18035                 :     4230547 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18036                 :             :     {
   18037                 :             : 
   18038                 :       13059 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18039                 :             :         return 64;
   18040                 :       13059 :       if ((TYPE_MODE (type) == XCmode
   18041                 :       13059 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18042                 :             :         return 128;
   18043                 :             :     }
   18044                 :     4217488 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18045                 :     4217488 :            && TYPE_FIELDS (type))
   18046                 :             :     {
   18047                 :     2170357 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18048                 :             :         return 64;
   18049                 :     2170357 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18050                 :             :         return 128;
   18051                 :             :     }
   18052                 :     2047131 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18053                 :             :            || TREE_CODE (type) == INTEGER_TYPE)
   18054                 :             :     {
   18055                 :     1907555 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18056                 :             :         return 64;
   18057                 :     1907555 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18058                 :             :         return 128;
   18059                 :             :     }
   18060                 :             : 
   18061                 :     5312552 :   return align;
   18062                 :             : }
   18063                 :             : 
   18064                 :             : /* Implememnt TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
   18065                 :             : static void
   18066                 :    29182054 : ix86_lower_local_decl_alignment (tree decl)
   18067                 :             : {
   18068                 :    29182054 :   unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
   18069                 :    29182054 :                                                  DECL_ALIGN (decl), true);
   18070                 :    29182054 :   if (new_align < DECL_ALIGN (decl))
   18071                 :           0 :     SET_DECL_ALIGN (decl, new_align);
   18072                 :    29182054 : }
   18073                 :             : 
   18074                 :             : /* Compute the alignment for a local variable or a stack slot.  EXP is
   18075                 :             :    the data type or decl itself, MODE is the widest mode available and
   18076                 :             :    ALIGN is the alignment that the object would ordinarily have.  The
   18077                 :             :    value of this macro is used instead of that alignment to align the
   18078                 :             :    object.  */
   18079                 :             : 
   18080                 :             : unsigned int
   18081                 :    45470455 : ix86_local_alignment (tree exp, machine_mode mode,
   18082                 :             :                       unsigned int align, bool may_lower)
   18083                 :             : {
   18084                 :    45470455 :   tree type, decl;
   18085                 :             : 
   18086                 :    45470455 :   if (exp && DECL_P (exp))
   18087                 :             :     {
   18088                 :    43429795 :       type = TREE_TYPE (exp);
   18089                 :    43429795 :       decl = exp;
   18090                 :             :     }
   18091                 :             :   else
   18092                 :             :     {
   18093                 :             :       type = exp;
   18094                 :             :       decl = NULL;
   18095                 :             :     }
   18096                 :             : 
   18097                 :             :   /* Don't do dynamic stack realignment for long long objects with
   18098                 :             :      -mpreferred-stack-boundary=2.  */
   18099                 :    45470455 :   if (may_lower
   18100                 :    29182054 :       && !TARGET_64BIT
   18101                 :      243766 :       && align == 64
   18102                 :       37813 :       && ix86_preferred_stack_boundary < 64
   18103                 :           0 :       && (mode == DImode || (type && TYPE_MODE (type) == DImode))
   18104                 :           0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18105                 :           0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18106                 :    45470455 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18107                 :             :     align = 32;
   18108                 :             : 
   18109                 :             :   /* If TYPE is NULL, we are allocating a stack slot for caller-save
   18110                 :             :      register in MODE.  We will return the largest alignment of XF
   18111                 :             :      and DF.  */
   18112                 :    45470455 :   if (!type)
   18113                 :             :     {
   18114                 :     1295577 :       if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
   18115                 :        1531 :         align = GET_MODE_ALIGNMENT (DFmode);
   18116                 :     1295577 :       return align;
   18117                 :             :     }
   18118                 :             : 
   18119                 :             :   /* Don't increase alignment for Intel MCU psABI.  */
   18120                 :    44174878 :   if (TARGET_IAMCU)
   18121                 :             :     return align;
   18122                 :             : 
   18123                 :             :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18124                 :             :      to 16byte boundary.  Exact wording is:
   18125                 :             : 
   18126                 :             :      An array uses the same alignment as its elements, except that a local or
   18127                 :             :      global array variable of length at least 16 bytes or
   18128                 :             :      a C99 variable-length array variable always has alignment of at least 16 bytes.
   18129                 :             : 
   18130                 :             :      This was added to allow use of aligned SSE instructions at arrays.  This
   18131                 :             :      rule is meant for static storage (where compiler cannot do the analysis
   18132                 :             :      by itself).  We follow it for automatic variables only when convenient.
   18133                 :             :      We fully control everything in the function compiled and functions from
   18134                 :             :      other unit cannot rely on the alignment.
   18135                 :             : 
   18136                 :             :      Exclude va_list type.  It is the common case of local array where
   18137                 :             :      we cannot benefit from the alignment.
   18138                 :             : 
   18139                 :             :      TODO: Probably one should optimize for size only when var is not escaping.  */
   18140                 :    41330390 :   if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
   18141                 :    85177478 :       && TARGET_SSE)
   18142                 :             :     {
   18143                 :    40963915 :       if (AGGREGATE_TYPE_P (type)
   18144                 :     8092940 :           && (va_list_type_node == NULL_TREE
   18145                 :     8092940 :               || (TYPE_MAIN_VARIANT (type)
   18146                 :     8092940 :                   != TYPE_MAIN_VARIANT (va_list_type_node)))
   18147                 :     7996367 :           && TYPE_SIZE (type)
   18148                 :     7996367 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18149                 :    41899465 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18150                 :    46899830 :           && align < 128)
   18151                 :     5000365 :         return 128;
   18152                 :             :     }
   18153                 :    39174513 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18154                 :             :     {
   18155                 :      753070 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18156                 :             :         return 64;
   18157                 :      753070 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18158                 :             :         return 128;
   18159                 :             :     }
   18160                 :    38421443 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18161                 :             :     {
   18162                 :      152523 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18163                 :             :         return 64;
   18164                 :      152523 :       if ((TYPE_MODE (type) == XCmode
   18165                 :      152523 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18166                 :             :         return 128;
   18167                 :             :     }
   18168                 :    38268920 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18169                 :    38268920 :            && TYPE_FIELDS (type))
   18170                 :             :     {
   18171                 :     4300641 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18172                 :             :         return 64;
   18173                 :     4297538 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18174                 :             :         return 128;
   18175                 :             :     }
   18176                 :    33968279 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18177                 :             :            || TREE_CODE (type) == INTEGER_TYPE)
   18178                 :             :     {
   18179                 :             : 
   18180                 :    28353629 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18181                 :             :         return 64;
   18182                 :    28353629 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18183                 :             :         return 128;
   18184                 :             :     }
   18185                 :             :   return align;
   18186                 :             : }
   18187                 :             : 
   18188                 :             : /* Compute the minimum required alignment for dynamic stack realignment
   18189                 :             :    purposes for a local variable, parameter or a stack slot.  EXP is
   18190                 :             :    the data type or decl itself, MODE is its mode and ALIGN is the
   18191                 :             :    alignment that the object would ordinarily have.  */
   18192                 :             : 
   18193                 :             : unsigned int
   18194                 :    45536405 : ix86_minimum_alignment (tree exp, machine_mode mode,
   18195                 :             :                         unsigned int align)
   18196                 :             : {
   18197                 :    45536405 :   tree type, decl;
   18198                 :             : 
   18199                 :    45536405 :   if (exp && DECL_P (exp))
   18200                 :             :     {
   18201                 :    14469364 :       type = TREE_TYPE (exp);
   18202                 :    14469364 :       decl = exp;
   18203                 :             :     }
   18204                 :             :   else
   18205                 :             :     {
   18206                 :             :       type = exp;
   18207                 :             :       decl = NULL;
   18208                 :             :     }
   18209                 :             : 
   18210                 :    45536405 :   if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
   18211                 :             :     return align;
   18212                 :             : 
   18213                 :             :   /* Don't do dynamic stack realignment for long long objects with
   18214                 :             :      -mpreferred-stack-boundary=2.  */
   18215                 :           0 :   if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
   18216                 :           0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18217                 :           0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18218                 :           0 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18219                 :             :     {
   18220                 :           0 :       gcc_checking_assert (!TARGET_STV);
   18221                 :             :       return 32;
   18222                 :             :     }
   18223                 :             : 
   18224                 :             :   return align;
   18225                 :             : }
   18226                 :             : 
   18227                 :             : /* Find a location for the static chain incoming to a nested function.
   18228                 :             :    This is a register, unless all free registers are used by arguments.  */
   18229                 :             : 
   18230                 :             : static rtx
   18231                 :      266955 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
   18232                 :             : {
   18233                 :      266955 :   unsigned regno;
   18234                 :             : 
   18235                 :      266955 :   if (TARGET_64BIT)
   18236                 :             :     {
   18237                 :             :       /* We always use R10 in 64-bit mode.  */
   18238                 :             :       regno = R10_REG;
   18239                 :             :     }
   18240                 :             :   else
   18241                 :             :     {
   18242                 :       88418 :       const_tree fntype, fndecl;
   18243                 :       88418 :       unsigned int ccvt;
   18244                 :             : 
   18245                 :             :       /* By default in 32-bit mode we use ECX to pass the static chain.  */
   18246                 :       88418 :       regno = CX_REG;
   18247                 :             : 
   18248                 :       88418 :       if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
   18249                 :             :         {
   18250                 :       78513 :           fntype = TREE_TYPE (fndecl_or_type);
   18251                 :       78513 :           fndecl = fndecl_or_type;
   18252                 :             :         }
   18253                 :             :       else
   18254                 :             :         {
   18255                 :             :           fntype = fndecl_or_type;
   18256                 :             :           fndecl = NULL;
   18257                 :             :         }
   18258                 :             : 
   18259                 :       88418 :       ccvt = ix86_get_callcvt (fntype);
   18260                 :       88418 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   18261                 :             :         {
   18262                 :             :           /* Fastcall functions use ecx/edx for arguments, which leaves
   18263                 :             :              us with EAX for the static chain.
   18264                 :             :              Thiscall functions use ecx for arguments, which also
   18265                 :             :              leaves us with EAX for the static chain.  */
   18266                 :             :           regno = AX_REG;
   18267                 :             :         }
   18268                 :       88418 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   18269                 :             :         {
   18270                 :             :           /* Thiscall functions use ecx for arguments, which leaves
   18271                 :             :              us with EAX and EDX for the static chain.
   18272                 :             :              We are using for abi-compatibility EAX.  */
   18273                 :             :           regno = AX_REG;
   18274                 :             :         }
   18275                 :       88418 :       else if (ix86_function_regparm (fntype, fndecl) == 3)
   18276                 :             :         {
   18277                 :             :           /* For regparm 3, we have no free call-clobbered registers in
   18278                 :             :              which to store the static chain.  In order to implement this,
   18279                 :             :              we have the trampoline push the static chain to the stack.
   18280                 :             :              However, we can't push a value below the return address when
   18281                 :             :              we call the nested function directly, so we have to use an
   18282                 :             :              alternate entry point.  For this we use ESI, and have the
   18283                 :             :              alternate entry point push ESI, so that things appear the
   18284                 :             :              same once we're executing the nested function.  */
   18285                 :           0 :           if (incoming_p)
   18286                 :             :             {
   18287                 :           0 :               if (fndecl == current_function_decl
   18288                 :           0 :                   && !ix86_static_chain_on_stack)
   18289                 :             :                 {
   18290                 :           0 :                   gcc_assert (!reload_completed);
   18291                 :           0 :                   ix86_static_chain_on_stack = true;
   18292                 :             :                 }
   18293                 :           0 :               return gen_frame_mem (SImode,
   18294                 :           0 :                                     plus_constant (Pmode,
   18295                 :           0 :                                                    arg_pointer_rtx, -8));
   18296                 :             :             }
   18297                 :             :           regno = SI_REG;
   18298                 :             :         }
   18299                 :             :     }
   18300                 :             : 
   18301                 :      266955 :   return gen_rtx_REG (Pmode, regno);
   18302                 :             : }
   18303                 :             : 
   18304                 :             : /* Emit RTL insns to initialize the variable parts of a trampoline.
   18305                 :             :    FNDECL is the decl of the target address; M_TRAMP is a MEM for
   18306                 :             :    the trampoline, and CHAIN_VALUE is an RTX for the static chain
   18307                 :             :    to be passed to the target function.  */
   18308                 :             : 
   18309                 :             : static void
   18310                 :         272 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   18311                 :             : {
   18312                 :         272 :   rtx mem, fnaddr;
   18313                 :         272 :   int opcode;
   18314                 :         272 :   int offset = 0;
   18315                 :         272 :   bool need_endbr = (flag_cf_protection & CF_BRANCH);
   18316                 :             : 
   18317                 :         272 :   fnaddr = XEXP (DECL_RTL (fndecl), 0);
   18318                 :             : 
   18319                 :         272 :   if (TARGET_64BIT)
   18320                 :             :     {
   18321                 :         272 :       int size;
   18322                 :             : 
   18323                 :         272 :       if (need_endbr)
   18324                 :             :         {
   18325                 :             :           /* Insert ENDBR64.  */
   18326                 :           1 :           mem = adjust_address (m_tramp, SImode, offset);
   18327                 :           1 :           emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
   18328                 :           1 :           offset += 4;
   18329                 :             :         }
   18330                 :             : 
   18331                 :             :       /* Load the function address to r11.  Try to load address using
   18332                 :             :          the shorter movl instead of movabs.  We may want to support
   18333                 :             :          movq for kernel mode, but kernel does not use trampolines at
   18334                 :             :          the moment.  FNADDR is a 32bit address and may not be in
   18335                 :             :          DImode when ptr_mode == SImode.  Always use movl in this
   18336                 :             :          case.  */
   18337                 :         272 :       if (ptr_mode == SImode
   18338                 :         272 :           || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
   18339                 :             :         {
   18340                 :         240 :           fnaddr = copy_addr_to_reg (fnaddr);
   18341                 :             : 
   18342                 :         240 :           mem = adjust_address (m_tramp, HImode, offset);
   18343                 :         240 :           emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
   18344                 :             : 
   18345                 :         240 :           mem = adjust_address (m_tramp, SImode, offset + 2);
   18346                 :         240 :           emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
   18347                 :         240 :           offset += 6;
   18348                 :             :         }
   18349                 :             :       else
   18350                 :             :         {
   18351                 :          32 :           mem = adjust_address (m_tramp, HImode, offset);
   18352                 :          32 :           emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
   18353                 :             : 
   18354                 :          32 :           mem = adjust_address (m_tramp, DImode, offset + 2);
   18355                 :          32 :           emit_move_insn (mem, fnaddr);
   18356                 :          32 :           offset += 10;
   18357                 :             :         }
   18358                 :             : 
   18359                 :             :       /* Load static chain using movabs to r10.  Use the shorter movl
   18360                 :             :          instead of movabs when ptr_mode == SImode.  */
   18361                 :         272 :       if (ptr_mode == SImode)
   18362                 :             :         {
   18363                 :             :           opcode = 0xba41;
   18364                 :             :           size = 6;
   18365                 :             :         }
   18366                 :             :       else
   18367                 :             :         {
   18368                 :         272 :           opcode = 0xba49;
   18369                 :         272 :           size = 10;
   18370                 :             :         }
   18371                 :             : 
   18372                 :         272 :       mem = adjust_address (m_tramp, HImode, offset);
   18373                 :         272 :       emit_move_insn (mem, gen_int_mode (opcode, HImode));
   18374                 :             : 
   18375                 :         272 :       mem = adjust_address (m_tramp, ptr_mode, offset + 2);
   18376                 :         272 :       emit_move_insn (mem, chain_value);
   18377                 :         272 :       offset += size;
   18378                 :             : 
   18379                 :             :       /* Jump to r11; the last (unused) byte is a nop, only there to
   18380                 :             :          pad the write out to a single 32-bit store.  */
   18381                 :         272 :       mem = adjust_address (m_tramp, SImode, offset);
   18382                 :         272 :       emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
   18383                 :         272 :       offset += 4;
   18384                 :             :     }
   18385                 :             :   else
   18386                 :             :     {
   18387                 :           0 :       rtx disp, chain;
   18388                 :             : 
   18389                 :             :       /* Depending on the static chain location, either load a register
   18390                 :             :          with a constant, or push the constant to the stack.  All of the
   18391                 :             :          instructions are the same size.  */
   18392                 :           0 :       chain = ix86_static_chain (fndecl, true);
   18393                 :           0 :       if (REG_P (chain))
   18394                 :             :         {
   18395                 :           0 :           switch (REGNO (chain))
   18396                 :             :             {
   18397                 :             :             case AX_REG:
   18398                 :             :               opcode = 0xb8; break;
   18399                 :           0 :             case CX_REG:
   18400                 :           0 :               opcode = 0xb9; break;
   18401                 :           0 :             default:
   18402                 :           0 :               gcc_unreachable ();
   18403                 :             :             }
   18404                 :             :         }
   18405                 :             :       else
   18406                 :             :         opcode = 0x68;
   18407                 :             : 
   18408                 :           0 :       if (need_endbr)
   18409                 :             :         {
   18410                 :             :           /* Insert ENDBR32.  */
   18411                 :           0 :           mem = adjust_address (m_tramp, SImode, offset);
   18412                 :           0 :           emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
   18413                 :           0 :           offset += 4;
   18414                 :             :         }
   18415                 :             : 
   18416                 :           0 :       mem = adjust_address (m_tramp, QImode, offset);
   18417                 :           0 :       emit_move_insn (mem, gen_int_mode (opcode, QImode));
   18418                 :             : 
   18419                 :           0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   18420                 :           0 :       emit_move_insn (mem, chain_value);
   18421                 :           0 :       offset += 5;
   18422                 :             : 
   18423                 :           0 :       mem = adjust_address (m_tramp, QImode, offset);
   18424                 :           0 :       emit_move_insn (mem, gen_int_mode (0xe9, QImode));
   18425                 :             : 
   18426                 :           0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   18427                 :             : 
   18428                 :             :       /* Compute offset from the end of the jmp to the target function.
   18429                 :             :          In the case in which the trampoline stores the static chain on
   18430                 :             :          the stack, we need to skip the first insn which pushes the
   18431                 :             :          (call-saved) register static chain; this push is 1 byte.  */
   18432                 :           0 :       offset += 5;
   18433                 :           0 :       int skip = MEM_P (chain) ? 1 : 0;
   18434                 :             :       /* Skip ENDBR32 at the entry of the target function.  */
   18435                 :           0 :       if (need_endbr
   18436                 :           0 :           && !cgraph_node::get (fndecl)->only_called_directly_p ())
   18437                 :           0 :         skip += 4;
   18438                 :           0 :       disp = expand_binop (SImode, sub_optab, fnaddr,
   18439                 :           0 :                            plus_constant (Pmode, XEXP (m_tramp, 0),
   18440                 :           0 :                                           offset - skip),
   18441                 :             :                            NULL_RTX, 1, OPTAB_DIRECT);
   18442                 :           0 :       emit_move_insn (mem, disp);
   18443                 :             :     }
   18444                 :             : 
   18445                 :         272 :   gcc_assert (offset <= TRAMPOLINE_SIZE);
   18446                 :             : 
   18447                 :             : #ifdef HAVE_ENABLE_EXECUTE_STACK
   18448                 :             : #ifdef CHECK_EXECUTE_STACK_ENABLED
   18449                 :             :   if (CHECK_EXECUTE_STACK_ENABLED)
   18450                 :             : #endif
   18451                 :             :   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
   18452                 :             :                      LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
   18453                 :             : #endif
   18454                 :         272 : }
   18455                 :             : 
   18456                 :             : static bool
   18457                 :    51975872 : ix86_allocate_stack_slots_for_args (void)
   18458                 :             : {
   18459                 :             :   /* Naked functions should not allocate stack slots for arguments.  */
   18460                 :    51975872 :   return !ix86_function_naked (current_function_decl);
   18461                 :             : }
   18462                 :             : 
   18463                 :             : static bool
   18464                 :    30784737 : ix86_warn_func_return (tree decl)
   18465                 :             : {
   18466                 :             :   /* Naked functions are implemented entirely in assembly, including the
   18467                 :             :      return sequence, so suppress warnings about this.  */
   18468                 :    30784737 :   return !ix86_function_naked (decl);
   18469                 :             : }
   18470                 :             : 
   18471                 :             : /* Return the shift count of a vector by scalar shift builtin second argument
   18472                 :             :    ARG1.  */
   18473                 :             : static tree
   18474                 :       14017 : ix86_vector_shift_count (tree arg1)
   18475                 :             : {
   18476                 :       14017 :   if (tree_fits_uhwi_p (arg1))
   18477                 :             :     return arg1;
   18478                 :        8297 :   else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
   18479                 :             :     {
   18480                 :             :       /* The count argument is weird, passed in as various 128-bit
   18481                 :             :          (or 64-bit) vectors, the low 64 bits from it are the count.  */
   18482                 :         162 :       unsigned char buf[16];
   18483                 :         162 :       int len = native_encode_expr (arg1, buf, 16);
   18484                 :         162 :       if (len == 0)
   18485                 :         162 :         return NULL_TREE;
   18486                 :         162 :       tree t = native_interpret_expr (uint64_type_node, buf, len);
   18487                 :         162 :       if (t && tree_fits_uhwi_p (t))
   18488                 :             :         return t;
   18489                 :             :     }
   18490                 :             :   return NULL_TREE;
   18491                 :             : }
   18492                 :             : 
   18493                 :             : /* Return true if arg_mask is all ones, ELEMS is elements number of
   18494                 :             :    corresponding vector.  */
   18495                 :             : static bool
   18496                 :       25076 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
   18497                 :             : {
   18498                 :       25076 :   if (TREE_CODE (arg_mask) != INTEGER_CST)
   18499                 :             :     return false;
   18500                 :             : 
   18501                 :        7308 :   unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
   18502                 :        7308 :   if (elems == HOST_BITS_PER_WIDE_INT)
   18503                 :          33 :     return  mask == HOST_WIDE_INT_M1U;
   18504                 :        7275 :   if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
   18505                 :        2527 :     return false;
   18506                 :             : 
   18507                 :             :   return true;
   18508                 :             : }
   18509                 :             : 
   18510                 :             : static tree
   18511                 :    69041549 : ix86_fold_builtin (tree fndecl, int n_args,
   18512                 :             :                    tree *args, bool ignore ATTRIBUTE_UNUSED)
   18513                 :             : {
   18514                 :    69041549 :   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
   18515                 :             :     {
   18516                 :    69041549 :       enum ix86_builtins fn_code
   18517                 :    69041549 :         = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   18518                 :    69041549 :       enum rtx_code rcode;
   18519                 :    69041549 :       bool is_vshift;
   18520                 :    69041549 :       enum tree_code tcode;
   18521                 :    69041549 :       bool is_scalar;
   18522                 :    69041549 :       unsigned HOST_WIDE_INT mask;
   18523                 :             : 
   18524                 :    69041549 :       switch (fn_code)
   18525                 :             :         {
   18526                 :        8373 :         case IX86_BUILTIN_CPU_IS:
   18527                 :        8373 :         case IX86_BUILTIN_CPU_SUPPORTS:
   18528                 :        8373 :           gcc_assert (n_args == 1);
   18529                 :        8373 :           return fold_builtin_cpu (fndecl, args);
   18530                 :             : 
   18531                 :       20439 :         case IX86_BUILTIN_NANQ:
   18532                 :       20439 :         case IX86_BUILTIN_NANSQ:
   18533                 :       20439 :           {
   18534                 :       20439 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18535                 :       20439 :             const char *str = c_getstr (*args);
   18536                 :       20439 :             int quiet = fn_code == IX86_BUILTIN_NANQ;
   18537                 :       20439 :             REAL_VALUE_TYPE real;
   18538                 :             : 
   18539                 :       20439 :             if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
   18540                 :       20439 :               return build_real (type, real);
   18541                 :           0 :             return NULL_TREE;
   18542                 :             :           }
   18543                 :             : 
   18544                 :         108 :         case IX86_BUILTIN_INFQ:
   18545                 :         108 :         case IX86_BUILTIN_HUGE_VALQ:
   18546                 :         108 :           {
   18547                 :         108 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18548                 :         108 :             REAL_VALUE_TYPE inf;
   18549                 :         108 :             real_inf (&inf);
   18550                 :         108 :             return build_real (type, inf);
   18551                 :             :           }
   18552                 :             : 
   18553                 :       60593 :         case IX86_BUILTIN_TZCNT16:
   18554                 :       60593 :         case IX86_BUILTIN_CTZS:
   18555                 :       60593 :         case IX86_BUILTIN_TZCNT32:
   18556                 :       60593 :         case IX86_BUILTIN_TZCNT64:
   18557                 :       60593 :           gcc_assert (n_args == 1);
   18558                 :       60593 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   18559                 :             :             {
   18560                 :          45 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18561                 :          45 :               tree arg = args[0];
   18562                 :          45 :               if (fn_code == IX86_BUILTIN_TZCNT16
   18563                 :          45 :                   || fn_code == IX86_BUILTIN_CTZS)
   18564                 :           3 :                 arg = fold_convert (short_unsigned_type_node, arg);
   18565                 :          45 :               if (integer_zerop (arg))
   18566                 :           6 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   18567                 :             :               else
   18568                 :          39 :                 return fold_const_call (CFN_CTZ, type, arg);
   18569                 :             :             }
   18570                 :             :           break;
   18571                 :             : 
   18572                 :       50453 :         case IX86_BUILTIN_LZCNT16:
   18573                 :       50453 :         case IX86_BUILTIN_CLZS:
   18574                 :       50453 :         case IX86_BUILTIN_LZCNT32:
   18575                 :       50453 :         case IX86_BUILTIN_LZCNT64:
   18576                 :       50453 :           gcc_assert (n_args == 1);
   18577                 :       50453 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   18578                 :             :             {
   18579                 :          54 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18580                 :          54 :               tree arg = args[0];
   18581                 :          54 :               if (fn_code == IX86_BUILTIN_LZCNT16
   18582                 :          54 :                   || fn_code == IX86_BUILTIN_CLZS)
   18583                 :          18 :                 arg = fold_convert (short_unsigned_type_node, arg);
   18584                 :          54 :               if (integer_zerop (arg))
   18585                 :           3 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   18586                 :             :               else
   18587                 :          51 :                 return fold_const_call (CFN_CLZ, type, arg);
   18588                 :             :             }
   18589                 :             :           break;
   18590                 :             : 
   18591                 :       59553 :         case IX86_BUILTIN_BEXTR32:
   18592                 :       59553 :         case IX86_BUILTIN_BEXTR64:
   18593                 :       59553 :         case IX86_BUILTIN_BEXTRI32:
   18594                 :       59553 :         case IX86_BUILTIN_BEXTRI64:
   18595                 :       59553 :           gcc_assert (n_args == 2);
   18596                 :       59553 :           if (tree_fits_uhwi_p (args[1]))
   18597                 :             :             {
   18598                 :         152 :               unsigned HOST_WIDE_INT res = 0;
   18599                 :         152 :               unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
   18600                 :         152 :               unsigned int start = tree_to_uhwi (args[1]);
   18601                 :         152 :               unsigned int len = (start & 0xff00) >> 8;
   18602                 :         152 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   18603                 :         152 :               start &= 0xff;
   18604                 :         152 :               if (start >= prec || len == 0)
   18605                 :         111 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   18606                 :             :                                          args[0]);
   18607                 :          41 :               else if (!tree_fits_uhwi_p (args[0]))
   18608                 :             :                 break;
   18609                 :             :               else
   18610                 :          24 :                 res = tree_to_uhwi (args[0]) >> start;
   18611                 :          24 :               if (len > prec)
   18612                 :             :                 len = prec;
   18613                 :          24 :               if (len < HOST_BITS_PER_WIDE_INT)
   18614                 :          15 :                 res &= (HOST_WIDE_INT_1U << len) - 1;
   18615                 :          24 :               return build_int_cstu (lhs_type, res);
   18616                 :             :             }
   18617                 :             :           break;
   18618                 :             : 
   18619                 :       20424 :         case IX86_BUILTIN_BZHI32:
   18620                 :       20424 :         case IX86_BUILTIN_BZHI64:
   18621                 :       20424 :           gcc_assert (n_args == 2);
   18622                 :       20424 :           if (tree_fits_uhwi_p (args[1]))
   18623                 :             :             {
   18624                 :         190 :               unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
   18625                 :         190 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   18626                 :         190 :               if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
   18627                 :             :                 return args[0];
   18628                 :         190 :               if (idx == 0)
   18629                 :          52 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   18630                 :             :                                          args[0]);
   18631                 :         138 :               if (!tree_fits_uhwi_p (args[0]))
   18632                 :             :                 break;
   18633                 :          12 :               unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
   18634                 :          12 :               res &= ~(HOST_WIDE_INT_M1U << idx);
   18635                 :          12 :               return build_int_cstu (lhs_type, res);
   18636                 :             :             }
   18637                 :             :           break;
   18638                 :             : 
   18639                 :       20182 :         case IX86_BUILTIN_PDEP32:
   18640                 :       20182 :         case IX86_BUILTIN_PDEP64:
   18641                 :       20182 :           gcc_assert (n_args == 2);
   18642                 :       20182 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   18643                 :             :             {
   18644                 :          46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   18645                 :          46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   18646                 :          46 :               unsigned HOST_WIDE_INT res = 0;
   18647                 :          46 :               unsigned HOST_WIDE_INT m, k = 1;
   18648                 :        2990 :               for (m = 1; m; m <<= 1)
   18649                 :        2944 :                 if ((mask & m) != 0)
   18650                 :             :                   {
   18651                 :        1440 :                     if ((src & k) != 0)
   18652                 :         789 :                       res |= m;
   18653                 :        1440 :                     k <<= 1;
   18654                 :             :                   }
   18655                 :          46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18656                 :             :             }
   18657                 :             :           break;
   18658                 :             : 
   18659                 :       20184 :         case IX86_BUILTIN_PEXT32:
   18660                 :       20184 :         case IX86_BUILTIN_PEXT64:
   18661                 :       20184 :           gcc_assert (n_args == 2);
   18662                 :       20184 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   18663                 :             :             {
   18664                 :          46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   18665                 :          46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   18666                 :          46 :               unsigned HOST_WIDE_INT res = 0;
   18667                 :          46 :               unsigned HOST_WIDE_INT m, k = 1;
   18668                 :        2990 :               for (m = 1; m; m <<= 1)
   18669                 :        2944 :                 if ((mask & m) != 0)
   18670                 :             :                   {
   18671                 :        2016 :                     if ((src & m) != 0)
   18672                 :        1063 :                       res |= k;
   18673                 :        2016 :                     k <<= 1;
   18674                 :             :                   }
   18675                 :          46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18676                 :             :             }
   18677                 :             :           break;
   18678                 :             : 
   18679                 :       79098 :         case IX86_BUILTIN_MOVMSKPS:
   18680                 :       79098 :         case IX86_BUILTIN_PMOVMSKB:
   18681                 :       79098 :         case IX86_BUILTIN_MOVMSKPD:
   18682                 :       79098 :         case IX86_BUILTIN_PMOVMSKB128:
   18683                 :       79098 :         case IX86_BUILTIN_MOVMSKPD256:
   18684                 :       79098 :         case IX86_BUILTIN_MOVMSKPS256:
   18685                 :       79098 :         case IX86_BUILTIN_PMOVMSKB256:
   18686                 :       79098 :           gcc_assert (n_args == 1);
   18687                 :       79098 :           if (TREE_CODE (args[0]) == VECTOR_CST)
   18688                 :             :             {
   18689                 :             :               HOST_WIDE_INT res = 0;
   18690                 :         139 :               for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
   18691                 :             :                 {
   18692                 :         124 :                   tree e = VECTOR_CST_ELT (args[0], i);
   18693                 :         124 :                   if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
   18694                 :             :                     {
   18695                 :          80 :                       if (wi::neg_p (wi::to_wide (e)))
   18696                 :          31 :                         res |= HOST_WIDE_INT_1 << i;
   18697                 :             :                     }
   18698                 :          44 :                   else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
   18699                 :             :                     {
   18700                 :          44 :                       if (TREE_REAL_CST (e).sign)
   18701                 :          19 :                         res |= HOST_WIDE_INT_1 << i;
   18702                 :             :                     }
   18703                 :             :                   else
   18704                 :             :                     return NULL_TREE;
   18705                 :             :                 }
   18706                 :          15 :               return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18707                 :             :             }
   18708                 :             :           break;
   18709                 :             : 
   18710                 :      642284 :         case IX86_BUILTIN_PSLLD:
   18711                 :      642284 :         case IX86_BUILTIN_PSLLD128:
   18712                 :      642284 :         case IX86_BUILTIN_PSLLD128_MASK:
   18713                 :      642284 :         case IX86_BUILTIN_PSLLD256:
   18714                 :      642284 :         case IX86_BUILTIN_PSLLD256_MASK:
   18715                 :      642284 :         case IX86_BUILTIN_PSLLD512:
   18716                 :      642284 :         case IX86_BUILTIN_PSLLDI:
   18717                 :      642284 :         case IX86_BUILTIN_PSLLDI128:
   18718                 :      642284 :         case IX86_BUILTIN_PSLLDI128_MASK:
   18719                 :      642284 :         case IX86_BUILTIN_PSLLDI256:
   18720                 :      642284 :         case IX86_BUILTIN_PSLLDI256_MASK:
   18721                 :      642284 :         case IX86_BUILTIN_PSLLDI512:
   18722                 :      642284 :         case IX86_BUILTIN_PSLLQ:
   18723                 :      642284 :         case IX86_BUILTIN_PSLLQ128:
   18724                 :      642284 :         case IX86_BUILTIN_PSLLQ128_MASK:
   18725                 :      642284 :         case IX86_BUILTIN_PSLLQ256:
   18726                 :      642284 :         case IX86_BUILTIN_PSLLQ256_MASK:
   18727                 :      642284 :         case IX86_BUILTIN_PSLLQ512:
   18728                 :      642284 :         case IX86_BUILTIN_PSLLQI:
   18729                 :      642284 :         case IX86_BUILTIN_PSLLQI128:
   18730                 :      642284 :         case IX86_BUILTIN_PSLLQI128_MASK:
   18731                 :      642284 :         case IX86_BUILTIN_PSLLQI256:
   18732                 :      642284 :         case IX86_BUILTIN_PSLLQI256_MASK:
   18733                 :      642284 :         case IX86_BUILTIN_PSLLQI512:
   18734                 :      642284 :         case IX86_BUILTIN_PSLLW:
   18735                 :      642284 :         case IX86_BUILTIN_PSLLW128:
   18736                 :      642284 :         case IX86_BUILTIN_PSLLW128_MASK:
   18737                 :      642284 :         case IX86_BUILTIN_PSLLW256:
   18738                 :      642284 :         case IX86_BUILTIN_PSLLW256_MASK:
   18739                 :      642284 :         case IX86_BUILTIN_PSLLW512_MASK:
   18740                 :      642284 :         case IX86_BUILTIN_PSLLWI:
   18741                 :      642284 :         case IX86_BUILTIN_PSLLWI128:
   18742                 :      642284 :         case IX86_BUILTIN_PSLLWI128_MASK:
   18743                 :      642284 :         case IX86_BUILTIN_PSLLWI256:
   18744                 :      642284 :         case IX86_BUILTIN_PSLLWI256_MASK:
   18745                 :      642284 :         case IX86_BUILTIN_PSLLWI512_MASK:
   18746                 :      642284 :           rcode = ASHIFT;
   18747                 :      642284 :           is_vshift = false;
   18748                 :      642284 :           goto do_shift;
   18749                 :      586019 :         case IX86_BUILTIN_PSRAD:
   18750                 :      586019 :         case IX86_BUILTIN_PSRAD128:
   18751                 :      586019 :         case IX86_BUILTIN_PSRAD128_MASK:
   18752                 :      586019 :         case IX86_BUILTIN_PSRAD256:
   18753                 :      586019 :         case IX86_BUILTIN_PSRAD256_MASK:
   18754                 :      586019 :         case IX86_BUILTIN_PSRAD512:
   18755                 :      586019 :         case IX86_BUILTIN_PSRADI:
   18756                 :      586019 :         case IX86_BUILTIN_PSRADI128:
   18757                 :      586019 :         case IX86_BUILTIN_PSRADI128_MASK:
   18758                 :      586019 :         case IX86_BUILTIN_PSRADI256:
   18759                 :      586019 :         case IX86_BUILTIN_PSRADI256_MASK:
   18760                 :      586019 :         case IX86_BUILTIN_PSRADI512:
   18761                 :      586019 :         case IX86_BUILTIN_PSRAQ128_MASK:
   18762                 :      586019 :         case IX86_BUILTIN_PSRAQ256_MASK:
   18763                 :      586019 :         case IX86_BUILTIN_PSRAQ512:
   18764                 :      586019 :         case IX86_BUILTIN_PSRAQI128_MASK:
   18765                 :      586019 :         case IX86_BUILTIN_PSRAQI256_MASK:
   18766                 :      586019 :         case IX86_BUILTIN_PSRAQI512:
   18767                 :      586019 :         case IX86_BUILTIN_PSRAW:
   18768                 :      586019 :         case IX86_BUILTIN_PSRAW128:
   18769                 :      586019 :         case IX86_BUILTIN_PSRAW128_MASK:
   18770                 :      586019 :         case IX86_BUILTIN_PSRAW256:
   18771                 :      586019 :         case IX86_BUILTIN_PSRAW256_MASK:
   18772                 :      586019 :         case IX86_BUILTIN_PSRAW512:
   18773                 :      586019 :         case IX86_BUILTIN_PSRAWI:
   18774                 :      586019 :         case IX86_BUILTIN_PSRAWI128:
   18775                 :      586019 :         case IX86_BUILTIN_PSRAWI128_MASK:
   18776                 :      586019 :         case IX86_BUILTIN_PSRAWI256:
   18777                 :      586019 :         case IX86_BUILTIN_PSRAWI256_MASK:
   18778                 :      586019 :         case IX86_BUILTIN_PSRAWI512:
   18779                 :      586019 :           rcode = ASHIFTRT;
   18780                 :      586019 :           is_vshift = false;
   18781                 :      586019 :           goto do_shift;
   18782                 :      617387 :         case IX86_BUILTIN_PSRLD:
   18783                 :      617387 :         case IX86_BUILTIN_PSRLD128:
   18784                 :      617387 :         case IX86_BUILTIN_PSRLD128_MASK:
   18785                 :      617387 :         case IX86_BUILTIN_PSRLD256:
   18786                 :      617387 :         case IX86_BUILTIN_PSRLD256_MASK:
   18787                 :      617387 :         case IX86_BUILTIN_PSRLD512:
   18788                 :      617387 :         case IX86_BUILTIN_PSRLDI:
   18789                 :      617387 :         case IX86_BUILTIN_PSRLDI128:
   18790                 :      617387 :         case IX86_BUILTIN_PSRLDI128_MASK:
   18791                 :      617387 :         case IX86_BUILTIN_PSRLDI256:
   18792                 :      617387 :         case IX86_BUILTIN_PSRLDI256_MASK:
   18793                 :      617387 :         case IX86_BUILTIN_PSRLDI512:
   18794                 :      617387 :         case IX86_BUILTIN_PSRLQ:
   18795                 :      617387 :         case IX86_BUILTIN_PSRLQ128:
   18796                 :      617387 :         case IX86_BUILTIN_PSRLQ128_MASK:
   18797                 :      617387 :         case IX86_BUILTIN_PSRLQ256:
   18798                 :      617387 :         case IX86_BUILTIN_PSRLQ256_MASK:
   18799                 :      617387 :         case IX86_BUILTIN_PSRLQ512:
   18800                 :      617387 :         case IX86_BUILTIN_PSRLQI:
   18801                 :      617387 :         case IX86_BUILTIN_PSRLQI128:
   18802                 :      617387 :         case IX86_BUILTIN_PSRLQI128_MASK:
   18803                 :      617387 :         case IX86_BUILTIN_PSRLQI256:
   18804                 :      617387 :         case IX86_BUILTIN_PSRLQI256_MASK:
   18805                 :      617387 :         case IX86_BUILTIN_PSRLQI512:
   18806                 :      617387 :         case IX86_BUILTIN_PSRLW:
   18807                 :      617387 :         case IX86_BUILTIN_PSRLW128:
   18808                 :      617387 :         case IX86_BUILTIN_PSRLW128_MASK:
   18809                 :      617387 :         case IX86_BUILTIN_PSRLW256:
   18810                 :      617387 :         case IX86_BUILTIN_PSRLW256_MASK:
   18811                 :      617387 :         case IX86_BUILTIN_PSRLW512:
   18812                 :      617387 :         case IX86_BUILTIN_PSRLWI:
   18813                 :      617387 :         case IX86_BUILTIN_PSRLWI128:
   18814                 :      617387 :         case IX86_BUILTIN_PSRLWI128_MASK:
   18815                 :      617387 :         case IX86_BUILTIN_PSRLWI256:
   18816                 :      617387 :         case IX86_BUILTIN_PSRLWI256_MASK:
   18817                 :      617387 :         case IX86_BUILTIN_PSRLWI512:
   18818                 :      617387 :           rcode = LSHIFTRT;
   18819                 :      617387 :           is_vshift = false;
   18820                 :      617387 :           goto do_shift;
   18821                 :      268150 :         case IX86_BUILTIN_PSLLVV16HI:
   18822                 :      268150 :         case IX86_BUILTIN_PSLLVV16SI:
   18823                 :      268150 :         case IX86_BUILTIN_PSLLVV2DI:
   18824                 :      268150 :         case IX86_BUILTIN_PSLLVV2DI_MASK:
   18825                 :      268150 :         case IX86_BUILTIN_PSLLVV32HI:
   18826                 :      268150 :         case IX86_BUILTIN_PSLLVV4DI:
   18827                 :      268150 :         case IX86_BUILTIN_PSLLVV4DI_MASK:
   18828                 :      268150 :         case IX86_BUILTIN_PSLLVV4SI:
   18829                 :      268150 :         case IX86_BUILTIN_PSLLVV4SI_MASK:
   18830                 :      268150 :         case IX86_BUILTIN_PSLLVV8DI:
   18831                 :      268150 :         case IX86_BUILTIN_PSLLVV8HI:
   18832                 :      268150 :         case IX86_BUILTIN_PSLLVV8SI:
   18833                 :      268150 :         case IX86_BUILTIN_PSLLVV8SI_MASK:
   18834                 :      268150 :           rcode = ASHIFT;
   18835                 :      268150 :           is_vshift = true;
   18836                 :      268150 :           goto do_shift;
   18837                 :      267775 :         case IX86_BUILTIN_PSRAVQ128:
   18838                 :      267775 :         case IX86_BUILTIN_PSRAVQ256:
   18839                 :      267775 :         case IX86_BUILTIN_PSRAVV16HI:
   18840                 :      267775 :         case IX86_BUILTIN_PSRAVV16SI:
   18841                 :      267775 :         case IX86_BUILTIN_PSRAVV32HI:
   18842                 :      267775 :         case IX86_BUILTIN_PSRAVV4SI:
   18843                 :      267775 :         case IX86_BUILTIN_PSRAVV4SI_MASK:
   18844                 :      267775 :         case IX86_BUILTIN_PSRAVV8DI:
   18845                 :      267775 :         case IX86_BUILTIN_PSRAVV8HI:
   18846                 :      267775 :         case IX86_BUILTIN_PSRAVV8SI:
   18847                 :      267775 :         case IX86_BUILTIN_PSRAVV8SI_MASK:
   18848                 :      267775 :           rcode = ASHIFTRT;
   18849                 :      267775 :           is_vshift = true;
   18850                 :      267775 :           goto do_shift;
   18851                 :      268141 :         case IX86_BUILTIN_PSRLVV16HI:
   18852                 :      268141 :         case IX86_BUILTIN_PSRLVV16SI:
   18853                 :      268141 :         case IX86_BUILTIN_PSRLVV2DI:
   18854                 :      268141 :         case IX86_BUILTIN_PSRLVV2DI_MASK:
   18855                 :      268141 :         case IX86_BUILTIN_PSRLVV32HI:
   18856                 :      268141 :         case IX86_BUILTIN_PSRLVV4DI:
   18857                 :      268141 :         case IX86_BUILTIN_PSRLVV4DI_MASK:
   18858                 :      268141 :         case IX86_BUILTIN_PSRLVV4SI:
   18859                 :      268141 :         case IX86_BUILTIN_PSRLVV4SI_MASK:
   18860                 :      268141 :         case IX86_BUILTIN_PSRLVV8DI:
   18861                 :      268141 :         case IX86_BUILTIN_PSRLVV8HI:
   18862                 :      268141 :         case IX86_BUILTIN_PSRLVV8SI:
   18863                 :      268141 :         case IX86_BUILTIN_PSRLVV8SI_MASK:
   18864                 :      268141 :           rcode = LSHIFTRT;
   18865                 :      268141 :           is_vshift = true;
   18866                 :      268141 :           goto do_shift;
   18867                 :             : 
   18868                 :     2649756 :         do_shift:
   18869                 :     2649756 :           gcc_assert (n_args >= 2);
   18870                 :     2649756 :           if (TREE_CODE (args[0]) != VECTOR_CST)
   18871                 :             :             break;
   18872                 :         912 :           mask = HOST_WIDE_INT_M1U;
   18873                 :         912 :           if (n_args > 2)
   18874                 :             :             {
   18875                 :             :               /* This is masked shift.  */
   18876                 :         667 :               if (!tree_fits_uhwi_p (args[n_args - 1])
   18877                 :         667 :                   || TREE_SIDE_EFFECTS (args[n_args - 2]))
   18878                 :             :                 break;
   18879                 :         667 :               mask = tree_to_uhwi (args[n_args - 1]);
   18880                 :         667 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   18881                 :         667 :               mask |= HOST_WIDE_INT_M1U << elems;
   18882                 :         667 :               if (mask != HOST_WIDE_INT_M1U
   18883                 :         556 :                   && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
   18884                 :             :                 break;
   18885                 :         633 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   18886                 :             :                 return args[n_args - 2];
   18887                 :             :             }
   18888                 :         875 :           if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
   18889                 :             :             break;
   18890                 :         178 :           if (tree tem = (is_vshift ? integer_one_node
   18891                 :         875 :                           : ix86_vector_shift_count (args[1])))
   18892                 :             :             {
   18893                 :         554 :               unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
   18894                 :         554 :               unsigned HOST_WIDE_INT prec
   18895                 :         554 :                 = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
   18896                 :         554 :               if (count == 0 && mask == HOST_WIDE_INT_M1U)
   18897                 :             :                 return args[0];
   18898                 :         554 :               if (count >= prec)
   18899                 :             :                 {
   18900                 :          72 :                   if (rcode == ASHIFTRT)
   18901                 :          27 :                     count = prec - 1;
   18902                 :          45 :                   else if (mask == HOST_WIDE_INT_M1U)
   18903                 :           3 :                     return build_zero_cst (TREE_TYPE (args[0]));
   18904                 :             :                 }
   18905                 :         551 :               tree countt = NULL_TREE;
   18906                 :         551 :               if (!is_vshift)
   18907                 :             :                 {
   18908                 :         373 :                   if (count >= prec)
   18909                 :          42 :                     countt = integer_zero_node;
   18910                 :             :                   else
   18911                 :         331 :                     countt = build_int_cst (integer_type_node, count);
   18912                 :             :                 }
   18913                 :         551 :               tree_vector_builder builder;
   18914                 :         551 :               if (mask != HOST_WIDE_INT_M1U || is_vshift)
   18915                 :         392 :                 builder.new_vector (TREE_TYPE (args[0]),
   18916                 :         784 :                                     TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
   18917                 :             :                                     1);
   18918                 :             :               else
   18919                 :         159 :                 builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
   18920                 :             :                                              false);
   18921                 :         551 :               unsigned int cnt = builder.encoded_nelts ();
   18922                 :        5959 :               for (unsigned int i = 0; i < cnt; ++i)
   18923                 :             :                 {
   18924                 :        5408 :                   tree elt = VECTOR_CST_ELT (args[0], i);
   18925                 :        5408 :                   if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
   18926                 :           0 :                     return NULL_TREE;
   18927                 :        5408 :                   tree type = TREE_TYPE (elt);
   18928                 :        5408 :                   if (rcode == LSHIFTRT)
   18929                 :        2036 :                     elt = fold_convert (unsigned_type_for (type), elt);
   18930                 :        5408 :                   if (is_vshift)
   18931                 :             :                     {
   18932                 :        1846 :                       countt = VECTOR_CST_ELT (args[1], i);
   18933                 :        1846 :                       if (TREE_CODE (countt) != INTEGER_CST
   18934                 :        1846 :                           || TREE_OVERFLOW (countt))
   18935                 :             :                         return NULL_TREE;
   18936                 :        1846 :                       if (wi::neg_p (wi::to_wide (countt))
   18937                 :        3610 :                           || wi::to_widest (countt) >= prec)
   18938                 :             :                         {
   18939                 :         325 :                           if (rcode == ASHIFTRT)
   18940                 :         108 :                             countt = build_int_cst (TREE_TYPE (countt),
   18941                 :         108 :                                                     prec - 1);
   18942                 :             :                           else
   18943                 :             :                             {
   18944                 :         217 :                               elt = build_zero_cst (TREE_TYPE (elt));
   18945                 :         217 :                               countt = build_zero_cst (TREE_TYPE (countt));
   18946                 :             :                             }
   18947                 :             :                         }
   18948                 :             :                     }
   18949                 :        3562 :                   else if (count >= prec)
   18950                 :         504 :                     elt = build_zero_cst (TREE_TYPE (elt));
   18951                 :        8942 :                   elt = const_binop (rcode == ASHIFT
   18952                 :             :                                      ? LSHIFT_EXPR : RSHIFT_EXPR,
   18953                 :        5408 :                                      TREE_TYPE (elt), elt, countt);
   18954                 :        5408 :                   if (!elt || TREE_CODE (elt) != INTEGER_CST)
   18955                 :             :                     return NULL_TREE;
   18956                 :        5408 :                   if (rcode == LSHIFTRT)
   18957                 :        2036 :                     elt = fold_convert (type, elt);
   18958                 :        5408 :                   if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
   18959                 :             :                     {
   18960                 :        1566 :                       elt = VECTOR_CST_ELT (args[n_args - 2], i);
   18961                 :        1566 :                       if (TREE_CODE (elt) != INTEGER_CST
   18962                 :        1566 :                           || TREE_OVERFLOW (elt))
   18963                 :             :                         return NULL_TREE;
   18964                 :             :                     }
   18965                 :        5408 :                   builder.quick_push (elt);
   18966                 :             :                 }
   18967                 :         551 :               return builder.build ();
   18968                 :         551 :             }
   18969                 :             :           break;
   18970                 :             : 
   18971                 :       31832 :         case IX86_BUILTIN_MINSS:
   18972                 :       31832 :         case IX86_BUILTIN_MINSH_MASK:
   18973                 :       31832 :           tcode = LT_EXPR;
   18974                 :       31832 :           is_scalar = true;
   18975                 :       31832 :           goto do_minmax;
   18976                 :             : 
   18977                 :       31832 :         case IX86_BUILTIN_MAXSS:
   18978                 :       31832 :         case IX86_BUILTIN_MAXSH_MASK:
   18979                 :       31832 :           tcode = GT_EXPR;
   18980                 :       31832 :           is_scalar = true;
   18981                 :       31832 :           goto do_minmax;
   18982                 :             : 
   18983                 :      340522 :         case IX86_BUILTIN_MINPS:
   18984                 :      340522 :         case IX86_BUILTIN_MINPD:
   18985                 :      340522 :         case IX86_BUILTIN_MINPS256:
   18986                 :      340522 :         case IX86_BUILTIN_MINPD256:
   18987                 :      340522 :         case IX86_BUILTIN_MINPS512:
   18988                 :      340522 :         case IX86_BUILTIN_MINPD512:
   18989                 :      340522 :         case IX86_BUILTIN_MINPS128_MASK:
   18990                 :      340522 :         case IX86_BUILTIN_MINPD128_MASK:
   18991                 :      340522 :         case IX86_BUILTIN_MINPS256_MASK:
   18992                 :      340522 :         case IX86_BUILTIN_MINPD256_MASK:
   18993                 :      340522 :         case IX86_BUILTIN_MINPH128_MASK:
   18994                 :      340522 :         case IX86_BUILTIN_MINPH256_MASK:
   18995                 :      340522 :         case IX86_BUILTIN_MINPH512_MASK:
   18996                 :      340522 :           tcode = LT_EXPR;
   18997                 :      340522 :           is_scalar = false;
   18998                 :      340522 :           goto do_minmax;
   18999                 :             : 
   19000                 :             :         case IX86_BUILTIN_MAXPS:
   19001                 :             :         case IX86_BUILTIN_MAXPD:
   19002                 :             :         case IX86_BUILTIN_MAXPS256:
   19003                 :             :         case IX86_BUILTIN_MAXPD256:
   19004                 :             :         case IX86_BUILTIN_MAXPS512:
   19005                 :             :         case IX86_BUILTIN_MAXPD512:
   19006                 :             :         case IX86_BUILTIN_MAXPS128_MASK:
   19007                 :             :         case IX86_BUILTIN_MAXPD128_MASK:
   19008                 :             :         case IX86_BUILTIN_MAXPS256_MASK:
   19009                 :             :         case IX86_BUILTIN_MAXPD256_MASK:
   19010                 :             :         case IX86_BUILTIN_MAXPH128_MASK:
   19011                 :             :         case IX86_BUILTIN_MAXPH256_MASK:
   19012                 :             :         case IX86_BUILTIN_MAXPH512_MASK:
   19013                 :             :           tcode = GT_EXPR;
   19014                 :             :           is_scalar = false;
   19015                 :      744728 :         do_minmax:
   19016                 :      744728 :           gcc_assert (n_args >= 2);
   19017                 :      744728 :           if (TREE_CODE (args[0]) != VECTOR_CST
   19018                 :          76 :               || TREE_CODE (args[1]) != VECTOR_CST)
   19019                 :             :             break;
   19020                 :          76 :           mask = HOST_WIDE_INT_M1U;
   19021                 :          76 :           if (n_args > 2)
   19022                 :             :             {
   19023                 :          36 :               gcc_assert (n_args >= 4);
   19024                 :             :               /* This is masked minmax.  */
   19025                 :          36 :               if (TREE_CODE (args[3]) != INTEGER_CST
   19026                 :          36 :                   || TREE_SIDE_EFFECTS (args[2]))
   19027                 :             :                 break;
   19028                 :          36 :               mask = TREE_INT_CST_LOW (args[3]);
   19029                 :          36 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19030                 :          36 :               mask |= HOST_WIDE_INT_M1U << elems;
   19031                 :          36 :               if (mask != HOST_WIDE_INT_M1U
   19032                 :          32 :                   && TREE_CODE (args[2]) != VECTOR_CST)
   19033                 :             :                 break;
   19034                 :          36 :               if (n_args >= 5)
   19035                 :             :                 {
   19036                 :          20 :                   if (!tree_fits_uhwi_p (args[4]))
   19037                 :             :                     break;
   19038                 :          20 :                   if (tree_to_uhwi (args[4]) != 4
   19039                 :           0 :                       && tree_to_uhwi (args[4]) != 8)
   19040                 :             :                     break;
   19041                 :             :                 }
   19042                 :          36 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   19043                 :             :                 return args[2];
   19044                 :             :             }
   19045                 :             :           /* Punt on NaNs, unless exceptions are disabled.  */
   19046                 :          76 :           if (HONOR_NANS (args[0])
   19047                 :          76 :               && (n_args < 5 || tree_to_uhwi (args[4]) != 8))
   19048                 :         184 :             for (int i = 0; i < 2; ++i)
   19049                 :             :               {
   19050                 :         134 :                 unsigned count = vector_cst_encoded_nelts (args[i]);
   19051                 :         957 :                 for (unsigned j = 0; j < count; ++j)
   19052                 :         849 :                   if (tree_expr_nan_p (VECTOR_CST_ENCODED_ELT (args[i], j)))
   19053                 :             :                     return NULL_TREE;
   19054                 :             :               }
   19055                 :          50 :           {
   19056                 :          50 :             tree res = const_binop (tcode,
   19057                 :          50 :                                     truth_type_for (TREE_TYPE (args[0])),
   19058                 :             :                                     args[0], args[1]);
   19059                 :          50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19060                 :             :               break;
   19061                 :          50 :             res = fold_ternary (VEC_COND_EXPR, TREE_TYPE (args[0]), res,
   19062                 :             :                                 args[0], args[1]);
   19063                 :          50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19064                 :             :               break;
   19065                 :          50 :             if (mask != HOST_WIDE_INT_M1U)
   19066                 :             :               {
   19067                 :          32 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19068                 :          32 :                 vec_perm_builder sel (nelts, nelts, 1);
   19069                 :         328 :                 for (unsigned int i = 0; i < nelts; i++)
   19070                 :         296 :                   if (mask & (HOST_WIDE_INT_1U << i))
   19071                 :         160 :                     sel.quick_push (i);
   19072                 :             :                   else
   19073                 :         136 :                     sel.quick_push (nelts + i);
   19074                 :          32 :                 vec_perm_indices indices (sel, 2, nelts);
   19075                 :          32 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[2],
   19076                 :             :                                      indices);
   19077                 :          32 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19078                 :             :                   break;
   19079                 :          32 :               }
   19080                 :          50 :             if (is_scalar)
   19081                 :             :               {
   19082                 :          10 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19083                 :          10 :                 vec_perm_builder sel (nelts, nelts, 1);
   19084                 :          10 :                 sel.quick_push (0);
   19085                 :          40 :                 for (unsigned int i = 1; i < nelts; i++)
   19086                 :          30 :                   sel.quick_push (nelts + i);
   19087                 :          10 :                 vec_perm_indices indices (sel, 2, nelts);
   19088                 :          10 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[0],
   19089                 :             :                                      indices);
   19090                 :          10 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19091                 :             :                   break;
   19092                 :          10 :               }
   19093                 :          50 :             return res;
   19094                 :             :           }
   19095                 :             : 
   19096                 :             :         default:
   19097                 :             :           break;
   19098                 :             :         }
   19099                 :             :     }
   19100                 :             : 
   19101                 :             : #ifdef SUBTARGET_FOLD_BUILTIN
   19102                 :             :   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
   19103                 :             : #endif
   19104                 :             : 
   19105                 :             :   return NULL_TREE;
   19106                 :             : }
   19107                 :             : 
   19108                 :             : /* Fold a MD builtin (use ix86_fold_builtin for folding into
   19109                 :             :    constant) in GIMPLE.  */
   19110                 :             : 
   19111                 :             : bool
   19112                 :     1100276 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   19113                 :             : {
   19114                 :     1100276 :   gimple *stmt = gsi_stmt (*gsi), *g;
   19115                 :     1100276 :   gimple_seq stmts = NULL;
   19116                 :     1100276 :   tree fndecl = gimple_call_fndecl (stmt);
   19117                 :     1100276 :   gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
   19118                 :     1100276 :   int n_args = gimple_call_num_args (stmt);
   19119                 :     1100276 :   enum ix86_builtins fn_code
   19120                 :     1100276 :     = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19121                 :     1100276 :   tree decl = NULL_TREE;
   19122                 :     1100276 :   tree arg0, arg1, arg2;
   19123                 :     1100276 :   enum rtx_code rcode;
   19124                 :     1100276 :   enum tree_code tcode;
   19125                 :     1100276 :   unsigned HOST_WIDE_INT count;
   19126                 :     1100276 :   bool is_vshift;
   19127                 :     1100276 :   unsigned HOST_WIDE_INT elems;
   19128                 :     1100276 :   location_t loc;
   19129                 :             : 
   19130                 :             :   /* Don't fold when there's isa mismatch.  */
   19131                 :     1100276 :   if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
   19132                 :             :     return false;
   19133                 :             : 
   19134                 :     1100149 :   switch (fn_code)
   19135                 :             :     {
   19136                 :         278 :     case IX86_BUILTIN_TZCNT32:
   19137                 :         278 :       decl = builtin_decl_implicit (BUILT_IN_CTZ);
   19138                 :         278 :       goto fold_tzcnt_lzcnt;
   19139                 :             : 
   19140                 :         237 :     case IX86_BUILTIN_TZCNT64:
   19141                 :         237 :       decl = builtin_decl_implicit (BUILT_IN_CTZLL);
   19142                 :         237 :       goto fold_tzcnt_lzcnt;
   19143                 :             : 
   19144                 :         215 :     case IX86_BUILTIN_LZCNT32:
   19145                 :         215 :       decl = builtin_decl_implicit (BUILT_IN_CLZ);
   19146                 :         215 :       goto fold_tzcnt_lzcnt;
   19147                 :             : 
   19148                 :         224 :     case IX86_BUILTIN_LZCNT64:
   19149                 :         224 :       decl = builtin_decl_implicit (BUILT_IN_CLZLL);
   19150                 :         224 :       goto fold_tzcnt_lzcnt;
   19151                 :             : 
   19152                 :         954 :     fold_tzcnt_lzcnt:
   19153                 :         954 :       gcc_assert (n_args == 1);
   19154                 :         954 :       arg0 = gimple_call_arg (stmt, 0);
   19155                 :         954 :       if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
   19156                 :             :         {
   19157                 :         790 :           int prec = TYPE_PRECISION (TREE_TYPE (arg0));
   19158                 :             :           /* If arg0 is provably non-zero, optimize into generic
   19159                 :             :              __builtin_c[tl]z{,ll} function the middle-end handles
   19160                 :             :              better.  */
   19161                 :         790 :           if (!expr_not_equal_to (arg0, wi::zero (prec)))
   19162                 :             :             return false;
   19163                 :             : 
   19164                 :           8 :           loc = gimple_location (stmt);
   19165                 :           8 :           g = gimple_build_call (decl, 1, arg0);
   19166                 :           8 :           gimple_set_location (g, loc);
   19167                 :           8 :           tree lhs = make_ssa_name (integer_type_node);
   19168                 :           8 :           gimple_call_set_lhs (g, lhs);
   19169                 :           8 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
   19170                 :           8 :           g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
   19171                 :           8 :           gimple_set_location (g, loc);
   19172                 :           8 :           gsi_replace (gsi, g, false);
   19173                 :           8 :           return true;
   19174                 :             :         }
   19175                 :             :       break;
   19176                 :             : 
   19177                 :         491 :     case IX86_BUILTIN_BZHI32:
   19178                 :         491 :     case IX86_BUILTIN_BZHI64:
   19179                 :         491 :       gcc_assert (n_args == 2);
   19180                 :         491 :       arg1 = gimple_call_arg (stmt, 1);
   19181                 :         491 :       if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
   19182                 :             :         {
   19183                 :         195 :           unsigned int idx = tree_to_uhwi (arg1) & 0xff;
   19184                 :         195 :           arg0 = gimple_call_arg (stmt, 0);
   19185                 :         195 :           if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
   19186                 :             :             break;
   19187                 :          31 :           loc = gimple_location (stmt);
   19188                 :          31 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19189                 :          31 :           gimple_set_location (g, loc);
   19190                 :          31 :           gsi_replace (gsi, g, false);
   19191                 :          31 :           return true;
   19192                 :             :         }
   19193                 :             :       break;
   19194                 :             : 
   19195                 :         502 :     case IX86_BUILTIN_PDEP32:
   19196                 :         502 :     case IX86_BUILTIN_PDEP64:
   19197                 :         502 :     case IX86_BUILTIN_PEXT32:
   19198                 :         502 :     case IX86_BUILTIN_PEXT64:
   19199                 :         502 :       gcc_assert (n_args == 2);
   19200                 :         502 :       arg1 = gimple_call_arg (stmt, 1);
   19201                 :         502 :       if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
   19202                 :             :         {
   19203                 :           4 :           loc = gimple_location (stmt);
   19204                 :           4 :           arg0 = gimple_call_arg (stmt, 0);
   19205                 :           4 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19206                 :           4 :           gimple_set_location (g, loc);
   19207                 :           4 :           gsi_replace (gsi, g, false);
   19208                 :           4 :           return true;
   19209                 :             :         }
   19210                 :             :       break;
   19211                 :             : 
   19212                 :         145 :     case IX86_BUILTIN_PBLENDVB256:
   19213                 :         145 :     case IX86_BUILTIN_BLENDVPS256:
   19214                 :         145 :     case IX86_BUILTIN_BLENDVPD256:
   19215                 :             :       /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
   19216                 :             :          to scalar operations and not combined back.  */
   19217                 :         145 :       if (!TARGET_AVX2)
   19218                 :             :         break;
   19219                 :             : 
   19220                 :             :       /* FALLTHRU.  */
   19221                 :         112 :     case IX86_BUILTIN_BLENDVPD:
   19222                 :             :       /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
   19223                 :             :          w/o sse4.2, it's veclowered to scalar operations and
   19224                 :             :          not combined back.  */
   19225                 :         112 :       if (!TARGET_SSE4_2)
   19226                 :             :         break;
   19227                 :             :       /* FALLTHRU.  */
   19228                 :         149 :     case IX86_BUILTIN_PBLENDVB128:
   19229                 :         149 :     case IX86_BUILTIN_BLENDVPS:
   19230                 :         149 :       gcc_assert (n_args == 3);
   19231                 :         149 :       arg0 = gimple_call_arg (stmt, 0);
   19232                 :         149 :       arg1 = gimple_call_arg (stmt, 1);
   19233                 :         149 :       arg2 = gimple_call_arg (stmt, 2);
   19234                 :         149 :       if (gimple_call_lhs (stmt))
   19235                 :             :         {
   19236                 :         149 :           loc = gimple_location (stmt);
   19237                 :         149 :           tree type = TREE_TYPE (arg2);
   19238                 :         149 :           if (VECTOR_FLOAT_TYPE_P (type))
   19239                 :             :             {
   19240                 :          71 :               tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
   19241                 :          71 :                 ? intSI_type_node : intDI_type_node;
   19242                 :          71 :               type = get_same_sized_vectype (itype, type);
   19243                 :             :             }
   19244                 :             :           else
   19245                 :          78 :             type = signed_type_for (type);
   19246                 :         149 :           arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
   19247                 :         149 :           tree zero_vec = build_zero_cst (type);
   19248                 :         149 :           tree cmp_type = truth_type_for (type);
   19249                 :         149 :           tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
   19250                 :         149 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19251                 :         149 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19252                 :             :                                    VEC_COND_EXPR, cmp,
   19253                 :             :                                    arg1, arg0);
   19254                 :         149 :           gimple_set_location (g, loc);
   19255                 :         149 :           gsi_replace (gsi, g, false);
   19256                 :             :         }
   19257                 :             :       else
   19258                 :           0 :         gsi_replace (gsi, gimple_build_nop (), false);
   19259                 :             :       return true;
   19260                 :             : 
   19261                 :             : 
   19262                 :          16 :     case IX86_BUILTIN_PCMPEQB128:
   19263                 :          16 :     case IX86_BUILTIN_PCMPEQW128:
   19264                 :          16 :     case IX86_BUILTIN_PCMPEQD128:
   19265                 :          16 :     case IX86_BUILTIN_PCMPEQQ:
   19266                 :          16 :     case IX86_BUILTIN_PCMPEQB256:
   19267                 :          16 :     case IX86_BUILTIN_PCMPEQW256:
   19268                 :          16 :     case IX86_BUILTIN_PCMPEQD256:
   19269                 :          16 :     case IX86_BUILTIN_PCMPEQQ256:
   19270                 :          16 :       tcode = EQ_EXPR;
   19271                 :          16 :       goto do_cmp;
   19272                 :             : 
   19273                 :             :     case IX86_BUILTIN_PCMPGTB128:
   19274                 :             :     case IX86_BUILTIN_PCMPGTW128:
   19275                 :             :     case IX86_BUILTIN_PCMPGTD128:
   19276                 :             :     case IX86_BUILTIN_PCMPGTQ:
   19277                 :             :     case IX86_BUILTIN_PCMPGTB256:
   19278                 :             :     case IX86_BUILTIN_PCMPGTW256:
   19279                 :             :     case IX86_BUILTIN_PCMPGTD256:
   19280                 :             :     case IX86_BUILTIN_PCMPGTQ256:
   19281                 :             :       tcode = GT_EXPR;
   19282                 :             : 
   19283                 :          33 :     do_cmp:
   19284                 :          33 :       gcc_assert (n_args == 2);
   19285                 :          33 :       arg0 = gimple_call_arg (stmt, 0);
   19286                 :          33 :       arg1 = gimple_call_arg (stmt, 1);
   19287                 :          33 :       if (gimple_call_lhs (stmt))
   19288                 :             :         {
   19289                 :          32 :           loc = gimple_location (stmt);
   19290                 :          32 :           tree type = TREE_TYPE (arg0);
   19291                 :          32 :           tree zero_vec = build_zero_cst (type);
   19292                 :          32 :           tree minus_one_vec = build_minus_one_cst (type);
   19293                 :          32 :           tree cmp_type = truth_type_for (type);
   19294                 :          32 :           tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
   19295                 :          32 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19296                 :          32 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19297                 :             :                                    VEC_COND_EXPR, cmp,
   19298                 :             :                                    minus_one_vec, zero_vec);
   19299                 :          32 :           gimple_set_location (g, loc);
   19300                 :          32 :           gsi_replace (gsi, g, false);
   19301                 :             :         }
   19302                 :             :       else
   19303                 :           1 :         gsi_replace (gsi, gimple_build_nop (), false);
   19304                 :             :       return true;
   19305                 :             : 
   19306                 :        9240 :     case IX86_BUILTIN_PSLLD:
   19307                 :        9240 :     case IX86_BUILTIN_PSLLD128:
   19308                 :        9240 :     case IX86_BUILTIN_PSLLD128_MASK:
   19309                 :        9240 :     case IX86_BUILTIN_PSLLD256:
   19310                 :        9240 :     case IX86_BUILTIN_PSLLD256_MASK:
   19311                 :        9240 :     case IX86_BUILTIN_PSLLD512:
   19312                 :        9240 :     case IX86_BUILTIN_PSLLDI:
   19313                 :        9240 :     case IX86_BUILTIN_PSLLDI128:
   19314                 :        9240 :     case IX86_BUILTIN_PSLLDI128_MASK:
   19315                 :        9240 :     case IX86_BUILTIN_PSLLDI256:
   19316                 :        9240 :     case IX86_BUILTIN_PSLLDI256_MASK:
   19317                 :        9240 :     case IX86_BUILTIN_PSLLDI512:
   19318                 :        9240 :     case IX86_BUILTIN_PSLLQ:
   19319                 :        9240 :     case IX86_BUILTIN_PSLLQ128:
   19320                 :        9240 :     case IX86_BUILTIN_PSLLQ128_MASK:
   19321                 :        9240 :     case IX86_BUILTIN_PSLLQ256:
   19322                 :        9240 :     case IX86_BUILTIN_PSLLQ256_MASK:
   19323                 :        9240 :     case IX86_BUILTIN_PSLLQ512:
   19324                 :        9240 :     case IX86_BUILTIN_PSLLQI:
   19325                 :        9240 :     case IX86_BUILTIN_PSLLQI128:
   19326                 :        9240 :     case IX86_BUILTIN_PSLLQI128_MASK:
   19327                 :        9240 :     case IX86_BUILTIN_PSLLQI256:
   19328                 :        9240 :     case IX86_BUILTIN_PSLLQI256_MASK:
   19329                 :        9240 :     case IX86_BUILTIN_PSLLQI512:
   19330                 :        9240 :     case IX86_BUILTIN_PSLLW:
   19331                 :        9240 :     case IX86_BUILTIN_PSLLW128:
   19332                 :        9240 :     case IX86_BUILTIN_PSLLW128_MASK:
   19333                 :        9240 :     case IX86_BUILTIN_PSLLW256:
   19334                 :        9240 :     case IX86_BUILTIN_PSLLW256_MASK:
   19335                 :        9240 :     case IX86_BUILTIN_PSLLW512_MASK:
   19336                 :        9240 :     case IX86_BUILTIN_PSLLWI:
   19337                 :        9240 :     case IX86_BUILTIN_PSLLWI128:
   19338                 :        9240 :     case IX86_BUILTIN_PSLLWI128_MASK:
   19339                 :        9240 :     case IX86_BUILTIN_PSLLWI256:
   19340                 :        9240 :     case IX86_BUILTIN_PSLLWI256_MASK:
   19341                 :        9240 :     case IX86_BUILTIN_PSLLWI512_MASK:
   19342                 :        9240 :       rcode = ASHIFT;
   19343                 :        9240 :       is_vshift = false;
   19344                 :        9240 :       goto do_shift;
   19345                 :        6503 :     case IX86_BUILTIN_PSRAD:
   19346                 :        6503 :     case IX86_BUILTIN_PSRAD128:
   19347                 :        6503 :     case IX86_BUILTIN_PSRAD128_MASK:
   19348                 :        6503 :     case IX86_BUILTIN_PSRAD256:
   19349                 :        6503 :     case IX86_BUILTIN_PSRAD256_MASK:
   19350                 :        6503 :     case IX86_BUILTIN_PSRAD512:
   19351                 :        6503 :     case IX86_BUILTIN_PSRADI:
   19352                 :        6503 :     case IX86_BUILTIN_PSRADI128:
   19353                 :        6503 :     case IX86_BUILTIN_PSRADI128_MASK:
   19354                 :        6503 :     case IX86_BUILTIN_PSRADI256:
   19355                 :        6503 :     case IX86_BUILTIN_PSRADI256_MASK:
   19356                 :        6503 :     case IX86_BUILTIN_PSRADI512:
   19357                 :        6503 :     case IX86_BUILTIN_PSRAQ128_MASK:
   19358                 :        6503 :     case IX86_BUILTIN_PSRAQ256_MASK:
   19359                 :        6503 :     case IX86_BUILTIN_PSRAQ512:
   19360                 :        6503 :     case IX86_BUILTIN_PSRAQI128_MASK:
   19361                 :        6503 :     case IX86_BUILTIN_PSRAQI256_MASK:
   19362                 :        6503 :     case IX86_BUILTIN_PSRAQI512:
   19363                 :        6503 :     case IX86_BUILTIN_PSRAW:
   19364                 :        6503 :     case IX86_BUILTIN_PSRAW128:
   19365                 :        6503 :     case IX86_BUILTIN_PSRAW128_MASK:
   19366                 :        6503 :     case IX86_BUILTIN_PSRAW256:
   19367                 :        6503 :     case IX86_BUILTIN_PSRAW256_MASK:
   19368                 :        6503 :     case IX86_BUILTIN_PSRAW512:
   19369                 :        6503 :     case IX86_BUILTIN_PSRAWI:
   19370                 :        6503 :     case IX86_BUILTIN_PSRAWI128:
   19371                 :        6503 :     case IX86_BUILTIN_PSRAWI128_MASK:
   19372                 :        6503 :     case IX86_BUILTIN_PSRAWI256:
   19373                 :        6503 :     case IX86_BUILTIN_PSRAWI256_MASK:
   19374                 :        6503 :     case IX86_BUILTIN_PSRAWI512:
   19375                 :        6503 :       rcode = ASHIFTRT;
   19376                 :        6503 :       is_vshift = false;
   19377                 :        6503 :       goto do_shift;
   19378                 :        7898 :     case IX86_BUILTIN_PSRLD:
   19379                 :        7898 :     case IX86_BUILTIN_PSRLD128:
   19380                 :        7898 :     case IX86_BUILTIN_PSRLD128_MASK:
   19381                 :        7898 :     case IX86_BUILTIN_PSRLD256:
   19382                 :        7898 :     case IX86_BUILTIN_PSRLD256_MASK:
   19383                 :        7898 :     case IX86_BUILTIN_PSRLD512:
   19384                 :        7898 :     case IX86_BUILTIN_PSRLDI:
   19385                 :        7898 :     case IX86_BUILTIN_PSRLDI128:
   19386                 :        7898 :     case IX86_BUILTIN_PSRLDI128_MASK:
   19387                 :        7898 :     case IX86_BUILTIN_PSRLDI256:
   19388                 :        7898 :     case IX86_BUILTIN_PSRLDI256_MASK:
   19389                 :        7898 :     case IX86_BUILTIN_PSRLDI512:
   19390                 :        7898 :     case IX86_BUILTIN_PSRLQ:
   19391                 :        7898 :     case IX86_BUILTIN_PSRLQ128:
   19392                 :        7898 :     case IX86_BUILTIN_PSRLQ128_MASK:
   19393                 :        7898 :     case IX86_BUILTIN_PSRLQ256:
   19394                 :        7898 :     case IX86_BUILTIN_PSRLQ256_MASK:
   19395                 :        7898 :     case IX86_BUILTIN_PSRLQ512:
   19396                 :        7898 :     case IX86_BUILTIN_PSRLQI:
   19397                 :        7898 :     case IX86_BUILTIN_PSRLQI128:
   19398                 :        7898 :     case IX86_BUILTIN_PSRLQI128_MASK:
   19399                 :        7898 :     case IX86_BUILTIN_PSRLQI256:
   19400                 :        7898 :     case IX86_BUILTIN_PSRLQI256_MASK:
   19401                 :        7898 :     case IX86_BUILTIN_PSRLQI512:
   19402                 :        7898 :     case IX86_BUILTIN_PSRLW:
   19403                 :        7898 :     case IX86_BUILTIN_PSRLW128:
   19404                 :        7898 :     case IX86_BUILTIN_PSRLW128_MASK:
   19405                 :        7898 :     case IX86_BUILTIN_PSRLW256:
   19406                 :        7898 :     case IX86_BUILTIN_PSRLW256_MASK:
   19407                 :        7898 :     case IX86_BUILTIN_PSRLW512:
   19408                 :        7898 :     case IX86_BUILTIN_PSRLWI:
   19409                 :        7898 :     case IX86_BUILTIN_PSRLWI128:
   19410                 :        7898 :     case IX86_BUILTIN_PSRLWI128_MASK:
   19411                 :        7898 :     case IX86_BUILTIN_PSRLWI256:
   19412                 :        7898 :     case IX86_BUILTIN_PSRLWI256_MASK:
   19413                 :        7898 :     case IX86_BUILTIN_PSRLWI512:
   19414                 :        7898 :       rcode = LSHIFTRT;
   19415                 :        7898 :       is_vshift = false;
   19416                 :        7898 :       goto do_shift;
   19417                 :        2384 :     case IX86_BUILTIN_PSLLVV16HI:
   19418                 :        2384 :     case IX86_BUILTIN_PSLLVV16SI:
   19419                 :        2384 :     case IX86_BUILTIN_PSLLVV2DI:
   19420                 :        2384 :     case IX86_BUILTIN_PSLLVV2DI_MASK:
   19421                 :        2384 :     case IX86_BUILTIN_PSLLVV32HI:
   19422                 :        2384 :     case IX86_BUILTIN_PSLLVV4DI:
   19423                 :        2384 :     case IX86_BUILTIN_PSLLVV4DI_MASK:
   19424                 :        2384 :     case IX86_BUILTIN_PSLLVV4SI:
   19425                 :        2384 :     case IX86_BUILTIN_PSLLVV4SI_MASK:
   19426                 :        2384 :     case IX86_BUILTIN_PSLLVV8DI:
   19427                 :        2384 :     case IX86_BUILTIN_PSLLVV8HI:
   19428                 :        2384 :     case IX86_BUILTIN_PSLLVV8SI:
   19429                 :        2384 :     case IX86_BUILTIN_PSLLVV8SI_MASK:
   19430                 :        2384 :       rcode = ASHIFT;
   19431                 :        2384 :       is_vshift = true;
   19432                 :        2384 :       goto do_shift;
   19433                 :        2341 :     case IX86_BUILTIN_PSRAVQ128:
   19434                 :        2341 :     case IX86_BUILTIN_PSRAVQ256:
   19435                 :        2341 :     case IX86_BUILTIN_PSRAVV16HI:
   19436                 :        2341 :     case IX86_BUILTIN_PSRAVV16SI:
   19437                 :        2341 :     case IX86_BUILTIN_PSRAVV32HI:
   19438                 :        2341 :     case IX86_BUILTIN_PSRAVV4SI:
   19439                 :        2341 :     case IX86_BUILTIN_PSRAVV4SI_MASK:
   19440                 :        2341 :     case IX86_BUILTIN_PSRAVV8DI:
   19441                 :        2341 :     case IX86_BUILTIN_PSRAVV8HI:
   19442                 :        2341 :     case IX86_BUILTIN_PSRAVV8SI:
   19443                 :        2341 :     case IX86_BUILTIN_PSRAVV8SI_MASK:
   19444                 :        2341 :       rcode = ASHIFTRT;
   19445                 :        2341 :       is_vshift = true;
   19446                 :        2341 :       goto do_shift;
   19447                 :        2380 :     case IX86_BUILTIN_PSRLVV16HI:
   19448                 :        2380 :     case IX86_BUILTIN_PSRLVV16SI:
   19449                 :        2380 :     case IX86_BUILTIN_PSRLVV2DI:
   19450                 :        2380 :     case IX86_BUILTIN_PSRLVV2DI_MASK:
   19451                 :        2380 :     case IX86_BUILTIN_PSRLVV32HI:
   19452                 :        2380 :     case IX86_BUILTIN_PSRLVV4DI:
   19453                 :        2380 :     case IX86_BUILTIN_PSRLVV4DI_MASK:
   19454                 :        2380 :     case IX86_BUILTIN_PSRLVV4SI:
   19455                 :        2380 :     case IX86_BUILTIN_PSRLVV4SI_MASK:
   19456                 :        2380 :     case IX86_BUILTIN_PSRLVV8DI:
   19457                 :        2380 :     case IX86_BUILTIN_PSRLVV8HI:
   19458                 :        2380 :     case IX86_BUILTIN_PSRLVV8SI:
   19459                 :        2380 :     case IX86_BUILTIN_PSRLVV8SI_MASK:
   19460                 :        2380 :       rcode = LSHIFTRT;
   19461                 :        2380 :       is_vshift = true;
   19462                 :        2380 :       goto do_shift;
   19463                 :             : 
   19464                 :       30746 :     do_shift:
   19465                 :       30746 :       gcc_assert (n_args >= 2);
   19466                 :       30746 :       if (!gimple_call_lhs (stmt))
   19467                 :             :         {
   19468                 :           1 :           gsi_replace (gsi, gimple_build_nop (), false);
   19469                 :           1 :           return true;
   19470                 :             :         }
   19471                 :       30745 :       arg0 = gimple_call_arg (stmt, 0);
   19472                 :       30745 :       arg1 = gimple_call_arg (stmt, 1);
   19473                 :       30745 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19474                 :             :       /* For masked shift, only optimize if the mask is all ones.  */
   19475                 :       30745 :       if (n_args > 2
   19476                 :       30745 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   19477                 :             :         break;
   19478                 :       15960 :       if (is_vshift)
   19479                 :             :         {
   19480                 :        2640 :           if (TREE_CODE (arg1) != VECTOR_CST)
   19481                 :             :             break;
   19482                 :          69 :           count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
   19483                 :          69 :           if (integer_zerop (arg1))
   19484                 :          27 :             count = 0;
   19485                 :          42 :           else if (rcode == ASHIFTRT)
   19486                 :             :             break;
   19487                 :             :           else
   19488                 :         230 :             for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
   19489                 :             :               {
   19490                 :         212 :                 tree elt = VECTOR_CST_ELT (arg1, i);
   19491                 :         212 :                 if (!wi::neg_p (wi::to_wide (elt))
   19492                 :         375 :                     && wi::to_widest (elt) < count)
   19493                 :          16 :                   return false;
   19494                 :             :               }
   19495                 :             :         }
   19496                 :             :       else
   19497                 :             :         {
   19498                 :       13320 :           arg1 = ix86_vector_shift_count (arg1);
   19499                 :       13320 :           if (!arg1)
   19500                 :             :             break;
   19501                 :        5506 :           count = tree_to_uhwi (arg1);
   19502                 :             :         }
   19503                 :        5551 :       if (count == 0)
   19504                 :             :         {
   19505                 :             :           /* Just return the first argument for shift by 0.  */
   19506                 :          93 :           loc = gimple_location (stmt);
   19507                 :          93 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19508                 :          93 :           gimple_set_location (g, loc);
   19509                 :          93 :           gsi_replace (gsi, g, false);
   19510                 :          93 :           return true;
   19511                 :             :         }
   19512                 :        5458 :       if (rcode != ASHIFTRT
   19513                 :        5458 :           && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
   19514                 :             :         {
   19515                 :             :           /* For shift counts equal or greater than precision, except for
   19516                 :             :              arithmetic right shift the result is zero.  */
   19517                 :          78 :           loc = gimple_location (stmt);
   19518                 :          78 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19519                 :          78 :                                    build_zero_cst (TREE_TYPE (arg0)));
   19520                 :          78 :           gimple_set_location (g, loc);
   19521                 :          78 :           gsi_replace (gsi, g, false);
   19522                 :          78 :           return true;
   19523                 :             :         }
   19524                 :             :       break;
   19525                 :             : 
   19526                 :         535 :     case IX86_BUILTIN_SHUFPD512:
   19527                 :         535 :     case IX86_BUILTIN_SHUFPS512:
   19528                 :         535 :     case IX86_BUILTIN_SHUFPD:
   19529                 :         535 :     case IX86_BUILTIN_SHUFPD256:
   19530                 :         535 :     case IX86_BUILTIN_SHUFPS:
   19531                 :         535 :     case IX86_BUILTIN_SHUFPS256:
   19532                 :         535 :       arg0 = gimple_call_arg (stmt, 0);
   19533                 :         535 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19534                 :             :       /* This is masked shuffle.  Only optimize if the mask is all ones.  */
   19535                 :         535 :       if (n_args > 3
   19536                 :         903 :           && !ix86_masked_all_ones (elems,
   19537                 :         368 :                                     gimple_call_arg (stmt, n_args - 1)))
   19538                 :             :         break;
   19539                 :         203 :       arg2 = gimple_call_arg (stmt, 2);
   19540                 :         203 :       if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
   19541                 :             :         {
   19542                 :         146 :           unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
   19543                 :             :           /* Check valid imm, refer to gcc.target/i386/testimm-10.c.  */
   19544                 :         146 :           if (shuffle_mask > 255)
   19545                 :             :             return false;
   19546                 :             : 
   19547                 :         144 :           machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
   19548                 :         144 :           loc = gimple_location (stmt);
   19549                 :         288 :           tree itype = (imode == E_DFmode
   19550                 :         144 :                         ? long_long_integer_type_node : integer_type_node);
   19551                 :         144 :           tree vtype = build_vector_type (itype, elems);
   19552                 :         144 :           tree_vector_builder elts (vtype, elems, 1);
   19553                 :             : 
   19554                 :             : 
   19555                 :             :           /* Transform integer shuffle_mask to vector perm_mask which
   19556                 :             :              is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md.  */
   19557                 :         840 :           for (unsigned i = 0; i != elems; i++)
   19558                 :             :             {
   19559                 :         696 :               unsigned sel_idx;
   19560                 :             :               /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
   19561                 :             :                  provide 2 select constrols for each element of the
   19562                 :             :                  destination.  */
   19563                 :         696 :               if (imode == E_DFmode)
   19564                 :         240 :                 sel_idx = (i & 1) * elems + (i & ~1)
   19565                 :         240 :                           + ((shuffle_mask >> i) & 1);
   19566                 :             :               else
   19567                 :             :                 {
   19568                 :             :                   /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
   19569                 :             :                      controls for each element of the destination.  */
   19570                 :         456 :                   unsigned j = i % 4;
   19571                 :         456 :                   sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
   19572                 :         456 :                             + ((shuffle_mask >> 2 * j) & 3);
   19573                 :             :                 }
   19574                 :         696 :               elts.quick_push (build_int_cst (itype, sel_idx));
   19575                 :             :             }
   19576                 :             : 
   19577                 :         144 :           tree perm_mask = elts.build ();
   19578                 :         144 :           arg1 = gimple_call_arg (stmt, 1);
   19579                 :         144 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19580                 :             :                                    VEC_PERM_EXPR,
   19581                 :             :                                    arg0, arg1, perm_mask);
   19582                 :         144 :           gimple_set_location (g, loc);
   19583                 :         144 :           gsi_replace (gsi, g, false);
   19584                 :         144 :           return true;
   19585                 :         144 :         }
   19586                 :             :       // Do not error yet, the constant could be propagated later?
   19587                 :             :       break;
   19588                 :             : 
   19589                 :          48 :     case IX86_BUILTIN_PABSB:
   19590                 :          48 :     case IX86_BUILTIN_PABSW:
   19591                 :          48 :     case IX86_BUILTIN_PABSD:
   19592                 :             :       /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE.  */
   19593                 :          48 :       if (!TARGET_MMX_WITH_SSE)
   19594                 :             :         break;
   19595                 :             :       /* FALLTHRU.  */
   19596                 :        2201 :     case IX86_BUILTIN_PABSB128:
   19597                 :        2201 :     case IX86_BUILTIN_PABSB256:
   19598                 :        2201 :     case IX86_BUILTIN_PABSB512:
   19599                 :        2201 :     case IX86_BUILTIN_PABSW128:
   19600                 :        2201 :     case IX86_BUILTIN_PABSW256:
   19601                 :        2201 :     case IX86_BUILTIN_PABSW512:
   19602                 :        2201 :     case IX86_BUILTIN_PABSD128:
   19603                 :        2201 :     case IX86_BUILTIN_PABSD256:
   19604                 :        2201 :     case IX86_BUILTIN_PABSD512:
   19605                 :        2201 :     case IX86_BUILTIN_PABSQ128:
   19606                 :        2201 :     case IX86_BUILTIN_PABSQ256:
   19607                 :        2201 :     case IX86_BUILTIN_PABSQ512:
   19608                 :        2201 :     case IX86_BUILTIN_PABSB128_MASK:
   19609                 :        2201 :     case IX86_BUILTIN_PABSB256_MASK:
   19610                 :        2201 :     case IX86_BUILTIN_PABSW128_MASK:
   19611                 :        2201 :     case IX86_BUILTIN_PABSW256_MASK:
   19612                 :        2201 :     case IX86_BUILTIN_PABSD128_MASK:
   19613                 :        2201 :     case IX86_BUILTIN_PABSD256_MASK:
   19614                 :        2201 :       gcc_assert (n_args >= 1);
   19615                 :        2201 :       if (!gimple_call_lhs (stmt))
   19616                 :             :         {
   19617                 :           1 :           gsi_replace (gsi, gimple_build_nop (), false);
   19618                 :           1 :           return true;
   19619                 :             :         }
   19620                 :        2200 :       arg0 = gimple_call_arg (stmt, 0);
   19621                 :        2200 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19622                 :             :       /* For masked ABS, only optimize if the mask is all ones.  */
   19623                 :        2200 :       if (n_args > 1
   19624                 :        2200 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   19625                 :             :         break;
   19626                 :         228 :       {
   19627                 :         228 :         tree utype, ures, vce;
   19628                 :         228 :         utype = unsigned_type_for (TREE_TYPE (arg0));
   19629                 :             :         /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
   19630                 :             :            instead of ABS_EXPR to hanlde overflow case(TYPE_MIN).  */
   19631                 :         228 :         ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
   19632                 :         228 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19633                 :         228 :         loc = gimple_location (stmt);
   19634                 :         228 :         vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
   19635                 :         228 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   19636                 :             :                                  VIEW_CONVERT_EXPR, vce);
   19637                 :         228 :         gsi_replace (gsi, g, false);
   19638                 :             :       }
   19639                 :         228 :       return true;
   19640                 :             : 
   19641                 :        2229 :     case IX86_BUILTIN_MINPS:
   19642                 :        2229 :     case IX86_BUILTIN_MINPD:
   19643                 :        2229 :     case IX86_BUILTIN_MINPS256:
   19644                 :        2229 :     case IX86_BUILTIN_MINPD256:
   19645                 :        2229 :     case IX86_BUILTIN_MINPS512:
   19646                 :        2229 :     case IX86_BUILTIN_MINPD512:
   19647                 :        2229 :     case IX86_BUILTIN_MINPS128_MASK:
   19648                 :        2229 :     case IX86_BUILTIN_MINPD128_MASK:
   19649                 :        2229 :     case IX86_BUILTIN_MINPS256_MASK:
   19650                 :        2229 :     case IX86_BUILTIN_MINPD256_MASK:
   19651                 :        2229 :     case IX86_BUILTIN_MINPH128_MASK:
   19652                 :        2229 :     case IX86_BUILTIN_MINPH256_MASK:
   19653                 :        2229 :     case IX86_BUILTIN_MINPH512_MASK:
   19654                 :        2229 :       tcode = LT_EXPR;
   19655                 :        2229 :       goto do_minmax;
   19656                 :             : 
   19657                 :             :     case IX86_BUILTIN_MAXPS:
   19658                 :             :     case IX86_BUILTIN_MAXPD:
   19659                 :             :     case IX86_BUILTIN_MAXPS256:
   19660                 :             :     case IX86_BUILTIN_MAXPD256:
   19661                 :             :     case IX86_BUILTIN_MAXPS512:
   19662                 :             :     case IX86_BUILTIN_MAXPD512:
   19663                 :             :     case IX86_BUILTIN_MAXPS128_MASK:
   19664                 :             :     case IX86_BUILTIN_MAXPD128_MASK:
   19665                 :             :     case IX86_BUILTIN_MAXPS256_MASK:
   19666                 :             :     case IX86_BUILTIN_MAXPD256_MASK:
   19667                 :             :     case IX86_BUILTIN_MAXPH128_MASK:
   19668                 :             :     case IX86_BUILTIN_MAXPH256_MASK:
   19669                 :             :     case IX86_BUILTIN_MAXPH512_MASK:
   19670                 :             :       tcode = GT_EXPR;
   19671                 :        4443 :     do_minmax:
   19672                 :        4443 :       gcc_assert (n_args >= 2);
   19673                 :             :       /* Without SSE4.1 we often aren't able to pattern match it back to the
   19674                 :             :          desired instruction.  */
   19675                 :        4443 :       if (!gimple_call_lhs (stmt) || !optimize || !TARGET_SSE4_1)
   19676                 :             :         break;
   19677                 :        3873 :       arg0 = gimple_call_arg (stmt, 0);
   19678                 :        3873 :       arg1 = gimple_call_arg (stmt, 1);
   19679                 :        3873 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19680                 :             :       /* For masked minmax, only optimize if the mask is all ones.  */
   19681                 :        3873 :       if (n_args > 2
   19682                 :        3873 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, 3)))
   19683                 :             :         break;
   19684                 :         647 :       if (n_args >= 5)
   19685                 :             :         {
   19686                 :         436 :           tree arg4 = gimple_call_arg (stmt, 4);
   19687                 :         436 :           if (!tree_fits_uhwi_p (arg4))
   19688                 :             :             break;
   19689                 :         424 :           if (tree_to_uhwi (arg4) == 4)
   19690                 :             :             /* Ok.  */;
   19691                 :         416 :           else if (tree_to_uhwi (arg4) != 8)
   19692                 :             :             /* Invalid round argument.  */
   19693                 :             :             break;
   19694                 :         416 :           else if (HONOR_NANS (arg0))
   19695                 :             :             /* Lowering to comparison would raise exceptions which
   19696                 :             :                shouldn't be raised.  */
   19697                 :             :             break;
   19698                 :             :         }
   19699                 :         219 :       {
   19700                 :         219 :         tree type = truth_type_for (TREE_TYPE (arg0));
   19701                 :         219 :         tree cmpres = gimple_build (&stmts, tcode, type, arg0, arg1);
   19702                 :         219 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19703                 :         219 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   19704                 :             :                                  VEC_COND_EXPR, cmpres, arg0, arg1);
   19705                 :         219 :         gsi_replace (gsi, g, false);
   19706                 :             :       }
   19707                 :         219 :       return true;
   19708                 :             : 
   19709                 :             :     default:
   19710                 :             :       break;
   19711                 :             :     }
   19712                 :             : 
   19713                 :             :   return false;
   19714                 :             : }
   19715                 :             : 
   19716                 :             : /* Handler for an SVML-style interface to
   19717                 :             :    a library with vectorized intrinsics.  */
   19718                 :             : 
   19719                 :             : tree
   19720                 :          12 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
   19721                 :             : {
   19722                 :          12 :   char name[20];
   19723                 :          12 :   tree fntype, new_fndecl, args;
   19724                 :          12 :   unsigned arity;
   19725                 :          12 :   const char *bname;
   19726                 :          12 :   machine_mode el_mode, in_mode;
   19727                 :          12 :   int n, in_n;
   19728                 :             : 
   19729                 :             :   /* The SVML is suitable for unsafe math only.  */
   19730                 :          12 :   if (!flag_unsafe_math_optimizations)
   19731                 :             :     return NULL_TREE;
   19732                 :             : 
   19733                 :          12 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   19734                 :          12 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   19735                 :          12 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   19736                 :          12 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   19737                 :          12 :   if (el_mode != in_mode
   19738                 :          12 :       || n != in_n)
   19739                 :             :     return NULL_TREE;
   19740                 :             : 
   19741                 :          12 :   switch (fn)
   19742                 :             :     {
   19743                 :          12 :     CASE_CFN_EXP:
   19744                 :          12 :     CASE_CFN_LOG:
   19745                 :          12 :     CASE_CFN_LOG10:
   19746                 :          12 :     CASE_CFN_POW:
   19747                 :          12 :     CASE_CFN_TANH:
   19748                 :          12 :     CASE_CFN_TAN:
   19749                 :          12 :     CASE_CFN_ATAN:
   19750                 :          12 :     CASE_CFN_ATAN2:
   19751                 :          12 :     CASE_CFN_ATANH:
   19752                 :          12 :     CASE_CFN_CBRT:
   19753                 :          12 :     CASE_CFN_SINH:
   19754                 :          12 :     CASE_CFN_SIN:
   19755                 :          12 :     CASE_CFN_ASINH:
   19756                 :          12 :     CASE_CFN_ASIN:
   19757                 :          12 :     CASE_CFN_COSH:
   19758                 :          12 :     CASE_CFN_COS:
   19759                 :          12 :     CASE_CFN_ACOSH:
   19760                 :          12 :     CASE_CFN_ACOS:
   19761                 :          12 :       if ((el_mode != DFmode || n != 2)
   19762                 :          10 :           && (el_mode != SFmode || n != 4))
   19763                 :             :         return NULL_TREE;
   19764                 :           6 :       break;
   19765                 :             : 
   19766                 :             :     default:
   19767                 :             :       return NULL_TREE;
   19768                 :             :     }
   19769                 :             : 
   19770                 :           6 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   19771                 :             :                                  ? double_type_node : float_type_node, fn);
   19772                 :           6 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   19773                 :             : 
   19774                 :           6 :   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
   19775                 :           2 :     strcpy (name, "vmlsLn4");
   19776                 :           4 :   else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
   19777                 :           0 :     strcpy (name, "vmldLn2");
   19778                 :           4 :   else if (n == 4)
   19779                 :             :     {
   19780                 :           2 :       sprintf (name, "vmls%s", bname+10);
   19781                 :           2 :       name[strlen (name)-1] = '4';
   19782                 :             :     }
   19783                 :             :   else
   19784                 :           2 :     sprintf (name, "vmld%s2", bname+10);
   19785                 :             : 
   19786                 :             :   /* Convert to uppercase. */
   19787                 :           6 :   name[4] &= ~0x20;
   19788                 :             : 
   19789                 :           6 :   arity = 0;
   19790                 :           6 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   19791                 :           0 :     arity++;
   19792                 :             : 
   19793                 :           6 :   if (arity == 1)
   19794                 :           0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   19795                 :             :   else
   19796                 :           6 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   19797                 :             : 
   19798                 :             :   /* Build a function declaration for the vectorized function.  */
   19799                 :           6 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   19800                 :             :                            FUNCTION_DECL, get_identifier (name), fntype);
   19801                 :           6 :   TREE_PUBLIC (new_fndecl) = 1;
   19802                 :           6 :   DECL_EXTERNAL (new_fndecl) = 1;
   19803                 :           6 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   19804                 :           6 :   TREE_READONLY (new_fndecl) = 1;
   19805                 :             : 
   19806                 :           6 :   return new_fndecl;
   19807                 :             : }
   19808                 :             : 
   19809                 :             : /* Handler for an ACML-style interface to
   19810                 :             :    a library with vectorized intrinsics.  */
   19811                 :             : 
   19812                 :             : tree
   19813                 :           3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
   19814                 :             : {
   19815                 :           3 :   char name[20] = "__vr.._";
   19816                 :           3 :   tree fntype, new_fndecl, args;
   19817                 :           3 :   unsigned arity;
   19818                 :           3 :   const char *bname;
   19819                 :           3 :   machine_mode el_mode, in_mode;
   19820                 :           3 :   int n, in_n;
   19821                 :             : 
   19822                 :             :   /* The ACML is 64bits only and suitable for unsafe math only as
   19823                 :             :      it does not correctly support parts of IEEE with the required
   19824                 :             :      precision such as denormals.  */
   19825                 :           3 :   if (!TARGET_64BIT
   19826                 :           3 :       || !flag_unsafe_math_optimizations)
   19827                 :             :     return NULL_TREE;
   19828                 :             : 
   19829                 :           3 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   19830                 :           3 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   19831                 :           3 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   19832                 :           3 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   19833                 :           3 :   if (el_mode != in_mode
   19834                 :           3 :       || n != in_n)
   19835                 :             :     return NULL_TREE;
   19836                 :             : 
   19837                 :           3 :   switch (fn)
   19838                 :             :     {
   19839                 :           3 :     CASE_CFN_SIN:
   19840                 :           3 :     CASE_CFN_COS:
   19841                 :           3 :     CASE_CFN_EXP:
   19842                 :           3 :     CASE_CFN_LOG:
   19843                 :           3 :     CASE_CFN_LOG2:
   19844                 :           3 :     CASE_CFN_LOG10:
   19845                 :           3 :       if (el_mode == DFmode && n == 2)
   19846                 :             :         {
   19847                 :           3 :           name[4] = 'd';
   19848                 :           3 :           name[5] = '2';
   19849                 :             :         }
   19850                 :           0 :       else if (el_mode == SFmode && n == 4)
   19851                 :             :         {
   19852                 :           0 :           name[4] = 's';
   19853                 :           0 :           name[5] = '4';
   19854                 :             :         }
   19855                 :             :       else
   19856                 :             :         return NULL_TREE;
   19857                 :           3 :       break;
   19858                 :             : 
   19859                 :             :     default:
   19860                 :             :       return NULL_TREE;
   19861                 :             :     }
   19862                 :             : 
   19863                 :           3 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   19864                 :             :                                  ? double_type_node : float_type_node, fn);
   19865                 :           3 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   19866                 :           3 :   sprintf (name + 7, "%s", bname+10);
   19867                 :             : 
   19868                 :           3 :   arity = 0;
   19869                 :           3 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   19870                 :           0 :     arity++;
   19871                 :             : 
   19872                 :           3 :   if (arity == 1)
   19873                 :           0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   19874                 :             :   else
   19875                 :           3 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   19876                 :             : 
   19877                 :             :   /* Build a function declaration for the vectorized function.  */
   19878                 :           3 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   19879                 :             :                            FUNCTION_DECL, get_identifier (name), fntype);
   19880                 :           3 :   TREE_PUBLIC (new_fndecl) = 1;
   19881                 :           3 :   DECL_EXTERNAL (new_fndecl) = 1;
   19882                 :           3 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   19883                 :           3 :   TREE_READONLY (new_fndecl) = 1;
   19884                 :             : 
   19885                 :           3 :   return new_fndecl;
   19886                 :             : }
   19887                 :             : 
   19888                 :             : /* Handler for an AOCL-LibM-style interface to
   19889                 :             :    a library with vectorized intrinsics.  */
   19890                 :             : 
   19891                 :             : tree
   19892                 :         220 : ix86_veclibabi_aocl (combined_fn fn, tree type_out, tree type_in)
   19893                 :             : {
   19894                 :         220 :   char name[20] = "amd_vr";
   19895                 :         220 :   int name_len = 6;
   19896                 :         220 :   tree fntype, new_fndecl, args;
   19897                 :         220 :   unsigned arity;
   19898                 :         220 :   const char *bname;
   19899                 :         220 :   machine_mode el_mode, in_mode;
   19900                 :         220 :   int n, in_n;
   19901                 :             : 
   19902                 :             :   /* AOCL-LibM is 64bits only.  It is also only suitable for unsafe math only
   19903                 :             :      as it trades off some accuracy for increased performance.  */
   19904                 :         220 :   if (!TARGET_64BIT
   19905                 :         220 :       || !flag_unsafe_math_optimizations)
   19906                 :             :     return NULL_TREE;
   19907                 :             : 
   19908                 :         220 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   19909                 :         220 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   19910                 :         220 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   19911                 :         220 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   19912                 :         220 :   if (el_mode != in_mode
   19913                 :         220 :       || n != in_n)
   19914                 :             :     return NULL_TREE;
   19915                 :             : 
   19916                 :         220 :   gcc_checking_assert (n > 0);
   19917                 :             : 
   19918                 :             :   /* Decide whether there exists a function for the combination of FN, the mode
   19919                 :             :      and the vector width.  Return early if it doesn't.  */
   19920                 :             : 
   19921                 :         220 :   if (el_mode != DFmode && el_mode != SFmode)
   19922                 :             :     return NULL_TREE;
   19923                 :             : 
   19924                 :             :   /* Supported vector widths for given FN and single/double precision.  Zeros
   19925                 :             :      are used to fill out unused positions in the arrays.  */
   19926                 :         220 :   static const int supported_n[][2][3] = {
   19927                 :             :   /*   Single prec. ,  Double prec.  */
   19928                 :             :     { { 16,  0,  0 }, {  2,  4,  8 } }, /* TAN.  */
   19929                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP.  */
   19930                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP2.  */
   19931                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG.  */
   19932                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG2.  */
   19933                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* COS.  */
   19934                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* SIN.  */
   19935                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* POW.  */
   19936                 :             :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* ERF.  */
   19937                 :             :     { {  4,  8, 16 }, {  2,  8,  0 } }, /* ATAN.  */
   19938                 :             :     { {  4,  8, 16 }, {  2,  0,  0 } }, /* LOG10.  */
   19939                 :             :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* EXP10.  */
   19940                 :             :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* LOG1P.  */
   19941                 :             :     { {  4,  8, 16 }, {  8,  0,  0 } }, /* ASIN.  */
   19942                 :             :     { {  4, 16,  0 }, {  0,  0,  0 } }, /* ACOS.  */
   19943                 :             :     { {  4,  8, 16 }, {  0,  0,  0 } }, /* TANH.  */
   19944                 :             :     { {  4,  0,  0 }, {  0,  0,  0 } }, /* EXPM1.  */
   19945                 :             :     { {  4,  8,  0 }, {  0,  0,  0 } }, /* COSH.  */
   19946                 :             :   };
   19947                 :             : 
   19948                 :             :   /* We cannot simply index the supported_n array with FN since multiple FNs
   19949                 :             :      may correspond to a single operation (see the definitions of these
   19950                 :             :      CASE_CFN_* macros).  */
   19951                 :         220 :   int i;
   19952                 :         220 :   switch (fn)
   19953                 :             :     {
   19954                 :             :     CASE_CFN_TAN   :  i = 0; break;
   19955                 :          16 :     CASE_CFN_EXP   :  i = 1; break;
   19956                 :          16 :     CASE_CFN_EXP2  :  i = 2; break;
   19957                 :          16 :     CASE_CFN_LOG   :  i = 3; break;
   19958                 :          16 :     CASE_CFN_LOG2  :  i = 4; break;
   19959                 :          16 :     CASE_CFN_COS   :  i = 5; break;
   19960                 :          16 :     CASE_CFN_SIN   :  i = 6; break;
   19961                 :          16 :     CASE_CFN_POW   :  i = 7; break;
   19962                 :          16 :     CASE_CFN_ERF   :  i = 8; break;
   19963                 :          13 :     CASE_CFN_ATAN  :  i = 9; break;
   19964                 :          11 :     CASE_CFN_LOG10 : i = 10; break;
   19965                 :           8 :     CASE_CFN_EXP10 : i = 11; break;
   19966                 :           8 :     CASE_CFN_LOG1P : i = 12; break;
   19967                 :          11 :     CASE_CFN_ASIN  : i = 13; break;
   19968                 :           7 :     CASE_CFN_ACOS  : i = 14; break;
   19969                 :           9 :     CASE_CFN_TANH  : i = 15; break;
   19970                 :           7 :     CASE_CFN_EXPM1 : i = 16; break;
   19971                 :           9 :     CASE_CFN_COSH  : i = 17; break;
   19972                 :             :     default: return NULL_TREE;
   19973                 :             :     }
   19974                 :             : 
   19975                 :         220 :   int j = el_mode == DFmode;
   19976                 :         220 :   bool n_is_supported = false;
   19977                 :         489 :   for (unsigned k = 0; k < 3; k++)
   19978                 :         470 :     if (supported_n[i][j][k] == n)
   19979                 :             :       {
   19980                 :             :         n_is_supported = true;
   19981                 :             :         break;
   19982                 :             :       }
   19983                 :         220 :   if (!n_is_supported)
   19984                 :             :     return NULL_TREE;
   19985                 :             : 
   19986                 :             :   /* Append the precision and the vector width to the function name we are
   19987                 :             :      constructing.  */
   19988                 :         201 :   name[name_len++] = el_mode == DFmode ? 'd' : 's';
   19989                 :         201 :   switch (n)
   19990                 :             :     {
   19991                 :         148 :       case 2:
   19992                 :         148 :       case 4:
   19993                 :         148 :       case 8:
   19994                 :         148 :         name[name_len++] = '0' + n;
   19995                 :         148 :         break;
   19996                 :          53 :       case 16:
   19997                 :          53 :         name[name_len++] = '1';
   19998                 :          53 :         name[name_len++] = '6';
   19999                 :          53 :         break;
   20000                 :           0 :       default:
   20001                 :           0 :         gcc_unreachable ();
   20002                 :             :     }
   20003                 :         201 :   name[name_len++] = '_';
   20004                 :             : 
   20005                 :             :   /* Append the operation name (steal it from the name of a builtin).  */
   20006                 :         201 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20007                 :             :                                  ? double_type_node : float_type_node, fn);
   20008                 :         201 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20009                 :         201 :   sprintf (name + name_len, "%s", bname + 10);
   20010                 :             : 
   20011                 :         201 :   arity = 0;
   20012                 :         201 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20013                 :           0 :     arity++;
   20014                 :             : 
   20015                 :         201 :   if (arity == 1)
   20016                 :           0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20017                 :             :   else
   20018                 :         201 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20019                 :             : 
   20020                 :             :   /* Build a function declaration for the vectorized function.  */
   20021                 :         201 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20022                 :             :                            FUNCTION_DECL, get_identifier (name), fntype);
   20023                 :         201 :   TREE_PUBLIC (new_fndecl) = 1;
   20024                 :         201 :   DECL_EXTERNAL (new_fndecl) = 1;
   20025                 :         201 :   TREE_READONLY (new_fndecl) = 1;
   20026                 :             : 
   20027                 :         201 :   return new_fndecl;
   20028                 :             : }
   20029                 :             : 
   20030                 :             : /* Returns a decl of a function that implements scatter store with
   20031                 :             :    register type VECTYPE and index type INDEX_TYPE and SCALE.
   20032                 :             :    Return NULL_TREE if it is not available.  */
   20033                 :             : 
   20034                 :             : static tree
   20035                 :       98995 : ix86_vectorize_builtin_scatter (const_tree vectype,
   20036                 :             :                                 const_tree index_type, int scale)
   20037                 :             : {
   20038                 :       98995 :   bool si;
   20039                 :       98995 :   enum ix86_builtins code;
   20040                 :       98995 :   const machine_mode mode = TYPE_MODE (TREE_TYPE (vectype));
   20041                 :             : 
   20042                 :       98995 :   if (!TARGET_AVX512F)
   20043                 :             :     return NULL_TREE;
   20044                 :             : 
   20045                 :        3911 :   if (!TARGET_EVEX512 && GET_MODE_SIZE (mode) == 64)
   20046                 :             :     return NULL_TREE;
   20047                 :             : 
   20048                 :        3911 :   if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
   20049                 :        7070 :       ? !TARGET_USE_SCATTER_2PARTS
   20050                 :        7070 :       : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
   20051                 :        3159 :          ? !TARGET_USE_SCATTER_4PARTS
   20052                 :        2183 :          : !TARGET_USE_SCATTER_8PARTS))
   20053                 :             :     return NULL_TREE;
   20054                 :             : 
   20055                 :        3911 :   if ((TREE_CODE (index_type) != INTEGER_TYPE
   20056                 :         486 :        && !POINTER_TYPE_P (index_type))
   20057                 :        4397 :       || (TYPE_MODE (index_type) != SImode
   20058                 :        1586 :           && TYPE_MODE (index_type) != DImode))
   20059                 :           0 :     return NULL_TREE;
   20060                 :             : 
   20061                 :        4133 :   if (TYPE_PRECISION (index_type) > POINTER_SIZE)
   20062                 :             :     return NULL_TREE;
   20063                 :             : 
   20064                 :             :   /* v*scatter* insn sign extends index to pointer mode.  */
   20065                 :        3911 :   if (TYPE_PRECISION (index_type) < POINTER_SIZE
   20066                 :        3911 :       && TYPE_UNSIGNED (index_type))
   20067                 :             :     return NULL_TREE;
   20068                 :             : 
   20069                 :             :   /* Scale can be 1, 2, 4 or 8.  */
   20070                 :        3911 :   if (scale <= 0
   20071                 :        3911 :       || scale > 8
   20072                 :        3877 :       || (scale & (scale - 1)) != 0)
   20073                 :             :     return NULL_TREE;
   20074                 :             : 
   20075                 :        3877 :   si = TYPE_MODE (index_type) == SImode;
   20076                 :        3877 :   switch (TYPE_MODE (vectype))
   20077                 :             :     {
   20078                 :         245 :     case E_V8DFmode:
   20079                 :         245 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
   20080                 :             :       break;
   20081                 :         159 :     case E_V8DImode:
   20082                 :         159 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
   20083                 :             :       break;
   20084                 :         250 :     case E_V16SFmode:
   20085                 :         250 :       code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
   20086                 :             :       break;
   20087                 :         282 :     case E_V16SImode:
   20088                 :         282 :       code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
   20089                 :             :       break;
   20090                 :         171 :     case E_V4DFmode:
   20091                 :         171 :       if (TARGET_AVX512VL)
   20092                 :          72 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
   20093                 :             :       else
   20094                 :             :         return NULL_TREE;
   20095                 :             :       break;
   20096                 :         157 :     case E_V4DImode:
   20097                 :         157 :       if (TARGET_AVX512VL)
   20098                 :          72 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
   20099                 :             :       else
   20100                 :             :         return NULL_TREE;
   20101                 :             :       break;
   20102                 :         178 :     case E_V8SFmode:
   20103                 :         178 :       if (TARGET_AVX512VL)
   20104                 :          78 :         code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
   20105                 :             :       else
   20106                 :             :         return NULL_TREE;
   20107                 :             :       break;
   20108                 :         286 :     case E_V8SImode:
   20109                 :         286 :       if (TARGET_AVX512VL)
   20110                 :         158 :         code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
   20111                 :             :       else
   20112                 :             :         return NULL_TREE;
   20113                 :             :       break;
   20114                 :         203 :     case E_V2DFmode:
   20115                 :         203 :       if (TARGET_AVX512VL)
   20116                 :         110 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
   20117                 :             :       else
   20118                 :             :         return NULL_TREE;
   20119                 :             :       break;
   20120                 :         189 :     case E_V2DImode:
   20121                 :         189 :       if (TARGET_AVX512VL)
   20122                 :         110 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
   20123                 :             :       else
   20124                 :             :         return NULL_TREE;
   20125                 :             :       break;
   20126                 :         206 :     case E_V4SFmode:
   20127                 :         206 :       if (TARGET_AVX512VL)
   20128                 :         114 :         code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
   20129                 :             :       else
   20130                 :             :         return NULL_TREE;
   20131                 :             :       break;
   20132                 :         290 :     case E_V4SImode:
   20133                 :         290 :       if (TARGET_AVX512VL)
   20134                 :         166 :         code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
   20135                 :             :       else
   20136                 :             :         return NULL_TREE;
   20137                 :             :       break;
   20138                 :             :     default:
   20139                 :             :       return NULL_TREE;
   20140                 :             :     }
   20141                 :             : 
   20142                 :        1816 :   return get_ix86_builtin (code);
   20143                 :             : }
   20144                 :             : 
   20145                 :             : /* Return true if it is safe to use the rsqrt optabs to optimize
   20146                 :             :    1.0/sqrt.  */
   20147                 :             : 
   20148                 :             : static bool
   20149                 :          82 : use_rsqrt_p (machine_mode mode)
   20150                 :             : {
   20151                 :          82 :   return ((mode == HFmode
   20152                 :          34 :            || (TARGET_SSE && TARGET_SSE_MATH))
   20153                 :          82 :           && flag_finite_math_only
   20154                 :          81 :           && !flag_trapping_math
   20155                 :         145 :           && flag_unsafe_math_optimizations);
   20156                 :             : }
   20157                 :             : 
   20158                 :             : /* Helper for avx_vpermilps256_operand et al.  This is also used by
   20159                 :             :    the expansion functions to turn the parallel back into a mask.
   20160                 :             :    The return value is 0 for no match and the imm8+1 for a match.  */
   20161                 :             : 
   20162                 :             : int
   20163                 :       29848 : avx_vpermilp_parallel (rtx par, machine_mode mode)
   20164                 :             : {
   20165                 :       29848 :   unsigned i, nelt = GET_MODE_NUNITS (mode);
   20166                 :       29848 :   unsigned mask = 0;
   20167                 :       29848 :   unsigned char ipar[16] = {};  /* Silence -Wuninitialized warning.  */
   20168                 :             : 
   20169                 :       29848 :   if (XVECLEN (par, 0) != (int) nelt)
   20170                 :             :     return 0;
   20171                 :             : 
   20172                 :             :   /* Validate that all of the elements are constants, and not totally
   20173                 :             :      out of range.  Copy the data into an integral array to make the
   20174                 :             :      subsequent checks easier.  */
   20175                 :      180430 :   for (i = 0; i < nelt; ++i)
   20176                 :             :     {
   20177                 :      150582 :       rtx er = XVECEXP (par, 0, i);
   20178                 :      150582 :       unsigned HOST_WIDE_INT ei;
   20179                 :             : 
   20180                 :      150582 :       if (!CONST_INT_P (er))
   20181                 :             :         return 0;
   20182                 :      150582 :       ei = INTVAL (er);
   20183                 :      150582 :       if (ei >= nelt)
   20184                 :             :         return 0;
   20185                 :      150582 :       ipar[i] = ei;
   20186                 :             :     }
   20187                 :             : 
   20188                 :       29848 :   switch (mode)
   20189                 :             :     {
   20190                 :             :     case E_V8DFmode:
   20191                 :             :       /* In the 512-bit DFmode case, we can only move elements within
   20192                 :             :          a 128-bit lane.  First fill the second part of the mask,
   20193                 :             :          then fallthru.  */
   20194                 :        2150 :       for (i = 4; i < 6; ++i)
   20195                 :             :         {
   20196                 :        1494 :           if (ipar[i] < 4 || ipar[i] >= 6)
   20197                 :             :             return 0;
   20198                 :        1384 :           mask |= (ipar[i] - 4) << i;
   20199                 :             :         }
   20200                 :        1518 :       for (i = 6; i < 8; ++i)
   20201                 :             :         {
   20202                 :        1087 :           if (ipar[i] < 6)
   20203                 :             :             return 0;
   20204                 :         862 :           mask |= (ipar[i] - 6) << i;
   20205                 :             :         }
   20206                 :             :       /* FALLTHRU */
   20207                 :             : 
   20208                 :             :     case E_V4DFmode:
   20209                 :             :       /* In the 256-bit DFmode case, we can only move elements within
   20210                 :             :          a 128-bit lane.  */
   20211                 :       20536 :       for (i = 0; i < 2; ++i)
   20212                 :             :         {
   20213                 :       17413 :           if (ipar[i] >= 2)
   20214                 :             :             return 0;
   20215                 :       11648 :           mask |= ipar[i] << i;
   20216                 :             :         }
   20217                 :        7891 :       for (i = 2; i < 4; ++i)
   20218                 :             :         {
   20219                 :        5507 :           if (ipar[i] < 2)
   20220                 :             :             return 0;
   20221                 :        4768 :           mask |= (ipar[i] - 2) << i;
   20222                 :             :         }
   20223                 :             :       break;
   20224                 :             : 
   20225                 :             :     case E_V16SFmode:
   20226                 :             :       /* In 512 bit SFmode case, permutation in the upper 256 bits
   20227                 :             :          must mirror the permutation in the lower 256-bits.  */
   20228                 :        3849 :       for (i = 0; i < 8; ++i)
   20229                 :        3423 :         if (ipar[i] + 8 != ipar[i + 8])
   20230                 :             :           return 0;
   20231                 :             :       /* FALLTHRU */
   20232                 :             : 
   20233                 :             :     case E_V8SFmode:
   20234                 :             :       /* In 256 bit SFmode case, we have full freedom of
   20235                 :             :          movement within the low 128-bit lane, but the high 128-bit
   20236                 :             :          lane must mirror the exact same pattern.  */
   20237                 :       30426 :       for (i = 0; i < 4; ++i)
   20238                 :       26669 :         if (ipar[i] + 4 != ipar[i + 4])
   20239                 :             :           return 0;
   20240                 :             :       nelt = 4;
   20241                 :             :       /* FALLTHRU */
   20242                 :             : 
   20243                 :       14688 :     case E_V2DFmode:
   20244                 :       14688 :     case E_V4SFmode:
   20245                 :             :       /* In the 128-bit case, we've full freedom in the placement of
   20246                 :             :          the elements from the source operand.  */
   20247                 :       59262 :       for (i = 0; i < nelt; ++i)
   20248                 :       44574 :         mask |= ipar[i] << (i * (nelt / 2));
   20249                 :             :       break;
   20250                 :             : 
   20251                 :           0 :     default:
   20252                 :           0 :       gcc_unreachable ();
   20253                 :             :     }
   20254                 :             : 
   20255                 :             :   /* Make sure success has a non-zero value by adding one.  */
   20256                 :       17072 :   return mask + 1;
   20257                 :             : }
   20258                 :             : 
   20259                 :             : /* Helper for avx_vperm2f128_v4df_operand et al.  This is also used by
   20260                 :             :    the expansion functions to turn the parallel back into a mask.
   20261                 :             :    The return value is 0 for no match and the imm8+1 for a match.  */
   20262                 :             : 
   20263                 :             : int
   20264                 :       56258 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
   20265                 :             : {
   20266                 :       56258 :   unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
   20267                 :       56258 :   unsigned mask = 0;
   20268                 :       56258 :   unsigned char ipar[8] = {};  /* Silence -Wuninitialized warning.  */
   20269                 :             : 
   20270                 :       56258 :   if (XVECLEN (par, 0) != (int) nelt)
   20271                 :             :     return 0;
   20272                 :             : 
   20273                 :             :   /* Validate that all of the elements are constants, and not totally
   20274                 :             :      out of range.  Copy the data into an integral array to make the
   20275                 :             :      subsequent checks easier.  */
   20276                 :      454982 :   for (i = 0; i < nelt; ++i)
   20277                 :             :     {
   20278                 :      398724 :       rtx er = XVECEXP (par, 0, i);
   20279                 :      398724 :       unsigned HOST_WIDE_INT ei;
   20280                 :             : 
   20281                 :      398724 :       if (!CONST_INT_P (er))
   20282                 :             :         return 0;
   20283                 :      398724 :       ei = INTVAL (er);
   20284                 :      398724 :       if (ei >= 2 * nelt)
   20285                 :             :         return 0;
   20286                 :      398724 :       ipar[i] = ei;
   20287                 :             :     }
   20288                 :             : 
   20289                 :             :   /* Validate that the halves of the permute are halves.  */
   20290                 :      104297 :   for (i = 0; i < nelt2 - 1; ++i)
   20291                 :       86126 :     if (ipar[i] + 1 != ipar[i + 1])
   20292                 :             :       return 0;
   20293                 :       54573 :   for (i = nelt2; i < nelt - 1; ++i)
   20294                 :       38170 :     if (ipar[i] + 1 != ipar[i + 1])
   20295                 :             :       return 0;
   20296                 :             : 
   20297                 :             :   /* Reconstruct the mask.  */
   20298                 :       49167 :   for (i = 0; i < 2; ++i)
   20299                 :             :     {
   20300                 :       32787 :       unsigned e = ipar[i * nelt2];
   20301                 :       32787 :       if (e % nelt2)
   20302                 :             :         return 0;
   20303                 :       32764 :       e /= nelt2;
   20304                 :       32764 :       mask |= e << (i * 4);
   20305                 :             :     }
   20306                 :             : 
   20307                 :             :   /* Make sure success has a non-zero value by adding one.  */
   20308                 :       16380 :   return mask + 1;
   20309                 :             : }
   20310                 :             : 
   20311                 :             : /* Return a mask of VPTERNLOG operands that do not affect output.  */
   20312                 :             : 
   20313                 :             : int
   20314                 :        2420 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
   20315                 :             : {
   20316                 :        2420 :   int mask = 0;
   20317                 :        2420 :   int imm8 = INTVAL (pternlog_imm);
   20318                 :             : 
   20319                 :        2420 :   if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
   20320                 :           6 :     mask |= 1;
   20321                 :        2420 :   if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
   20322                 :           6 :     mask |= 2;
   20323                 :        2420 :   if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
   20324                 :         149 :     mask |= 4;
   20325                 :             : 
   20326                 :        2420 :   return mask;
   20327                 :             : }
   20328                 :             : 
   20329                 :             : /* Eliminate false dependencies on operands that do not affect output
   20330                 :             :    by substituting other operands of a VPTERNLOG.  */
   20331                 :             : 
   20332                 :             : void
   20333                 :          78 : substitute_vpternlog_operands (rtx *operands)
   20334                 :             : {
   20335                 :          78 :   int mask = vpternlog_redundant_operand_mask (operands[4]);
   20336                 :             : 
   20337                 :          78 :   if (mask & 1) /* The first operand is redundant.  */
   20338                 :           2 :     operands[1] = operands[2];
   20339                 :             : 
   20340                 :          78 :   if (mask & 2) /* The second operand is redundant.  */
   20341                 :           2 :     operands[2] = operands[1];
   20342                 :             : 
   20343                 :          78 :   if (mask & 4) /* The third operand is redundant.  */
   20344                 :          74 :     operands[3] = operands[1];
   20345                 :           4 :   else if (REG_P (operands[3]))
   20346                 :             :     {
   20347                 :           0 :       if (mask & 1)
   20348                 :           0 :         operands[1] = operands[3];
   20349                 :           0 :       if (mask & 2)
   20350                 :           0 :         operands[2] = operands[3];
   20351                 :             :     }
   20352                 :          78 : }
   20353                 :             : 
   20354                 :             : /* Return a register priority for hard reg REGNO.  */
   20355                 :             : static int
   20356                 :    55114280 : ix86_register_priority (int hard_regno)
   20357                 :             : {
   20358                 :             :   /* ebp and r13 as the base always wants a displacement, r12 as the
   20359                 :             :      base always wants an index.  So discourage their usage in an
   20360                 :             :      address.  */
   20361                 :    55114280 :   if (hard_regno == R12_REG || hard_regno == R13_REG)
   20362                 :             :     return 0;
   20363                 :    50884615 :   if (hard_regno == BP_REG)
   20364                 :             :     return 1;
   20365                 :             :   /* New x86-64 int registers result in bigger code size.  Discourage them.  */
   20366                 :    49084761 :   if (REX_INT_REGNO_P (hard_regno))
   20367                 :             :     return 2;
   20368                 :    33462323 :   if (REX2_INT_REGNO_P (hard_regno))
   20369                 :             :     return 2;
   20370                 :             :   /* New x86-64 SSE registers result in bigger code size.  Discourage them.  */
   20371                 :    33460178 :   if (REX_SSE_REGNO_P (hard_regno))
   20372                 :             :     return 2;
   20373                 :    27867250 :   if (EXT_REX_SSE_REGNO_P (hard_regno))
   20374                 :             :     return 1;
   20375                 :             :   /* Usage of AX register results in smaller code.  Prefer it.  */
   20376                 :    27631313 :   if (hard_regno == AX_REG)
   20377                 :     3660158 :     return 4;
   20378                 :             :   return 3;
   20379                 :             : }
   20380                 :             : 
   20381                 :             : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
   20382                 :             : 
   20383                 :             :    Put float CONST_DOUBLE in the constant pool instead of fp regs.
   20384                 :             :    QImode must go into class Q_REGS.
   20385                 :             :    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
   20386                 :             :    movdf to do mem-to-mem moves through integer regs.  */
   20387                 :             : 
   20388                 :             : static reg_class_t
   20389                 :   521389407 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
   20390                 :             : {
   20391                 :   521389407 :   machine_mode mode = GET_MODE (x);
   20392                 :             : 
   20393                 :             :   /* We're only allowed to return a subclass of CLASS.  Many of the
   20394                 :             :      following checks fail for NO_REGS, so eliminate that early.  */
   20395                 :   521389407 :   if (regclass == NO_REGS)
   20396                 :             :     return NO_REGS;
   20397                 :             : 
   20398                 :             :   /* All classes can load zeros.  */
   20399                 :   520605781 :   if (x == CONST0_RTX (mode))
   20400                 :             :     return regclass;
   20401                 :             : 
   20402                 :             :   /* Force constants into memory if we are loading a (nonzero) constant into
   20403                 :             :      an MMX, SSE or MASK register.  This is because there are no MMX/SSE/MASK
   20404                 :             :      instructions to load from a constant.  */
   20405                 :   495992100 :   if (CONSTANT_P (x)
   20406                 :   495992100 :       && (MAYBE_MMX_CLASS_P (regclass)
   20407                 :   146697846 :           || MAYBE_SSE_CLASS_P (regclass)
   20408                 :   117993321 :           || MAYBE_MASK_CLASS_P (regclass)))
   20409                 :    28854448 :     return NO_REGS;
   20410                 :             : 
   20411                 :             :   /* Floating-point constants need more complex checks.  */
   20412                 :   467137652 :   if (CONST_DOUBLE_P (x))
   20413                 :             :     {
   20414                 :             :       /* General regs can load everything.  */
   20415                 :      280678 :       if (INTEGER_CLASS_P (regclass))
   20416                 :             :         return regclass;
   20417                 :             : 
   20418                 :             :       /* Floats can load 0 and 1 plus some others.  Note that we eliminated
   20419                 :             :          zero above.  We only want to wind up preferring 80387 registers if
   20420                 :             :          we plan on doing computation with them.  */
   20421                 :      174169 :       if (IS_STACK_MODE (mode)
   20422                 :      232901 :           && standard_80387_constant_p (x) > 0)
   20423                 :             :         {
   20424                 :             :           /* Limit class to FP regs.  */
   20425                 :       40675 :           if (FLOAT_CLASS_P (regclass))
   20426                 :             :             return FLOAT_REGS;
   20427                 :             :         }
   20428                 :             : 
   20429                 :      133494 :       return NO_REGS;
   20430                 :             :     }
   20431                 :             : 
   20432                 :             :   /* Prefer SSE if we can use them for math.  Also allow integer regs
   20433                 :             :      when moves between register units are cheap.  */
   20434                 :   466856974 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   20435                 :             :     {
   20436                 :    30950466 :       if (TARGET_INTER_UNIT_MOVES_FROM_VEC
   20437                 :    30935522 :           && TARGET_INTER_UNIT_MOVES_TO_VEC
   20438                 :    92810350 :           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
   20439                 :    30716363 :         return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   20440                 :             :       else
   20441                 :      234103 :         return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   20442                 :             :     }
   20443                 :             : 
   20444                 :             :   /* Generally when we see PLUS here, it's the function invariant
   20445                 :             :      (plus soft-fp const_int).  Which can only be computed into general
   20446                 :             :      regs.  */
   20447                 :   435906508 :   if (GET_CODE (x) == PLUS)
   20448                 :     1686911 :     return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
   20449                 :             : 
   20450                 :             :   /* QImode constants are easy to load, but non-constant QImode data
   20451                 :             :      must go into Q_REGS or ALL_MASK_REGS.  */
   20452                 :   434219597 :   if (GET_MODE (x) == QImode && !CONSTANT_P (x))
   20453                 :             :     {
   20454                 :    22968442 :       if (Q_CLASS_P (regclass))
   20455                 :             :         return regclass;
   20456                 :    18222966 :       else if (reg_class_subset_p (Q_REGS, regclass))
   20457                 :             :         return Q_REGS;
   20458                 :       37580 :       else if (MASK_CLASS_P (regclass))
   20459                 :             :         return regclass;
   20460                 :             :       else
   20461                 :             :         return NO_REGS;
   20462                 :             :     }
   20463                 :             : 
   20464                 :             :   return regclass;
   20465                 :             : }
   20466                 :             : 
   20467                 :             : /* Discourage putting floating-point values in SSE registers unless
   20468                 :             :    SSE math is being used, and likewise for the 387 registers.  */
   20469                 :             : static reg_class_t
   20470                 :    69988819 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
   20471                 :             : {
   20472                 :             :   /* Restrict the output reload class to the register bank that we are doing
   20473                 :             :      math on.  If we would like not to return a subset of CLASS, reject this
   20474                 :             :      alternative: if reload cannot do this, it will still use its choice.  */
   20475                 :    69988819 :   machine_mode mode = GET_MODE (x);
   20476                 :    69988819 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   20477                 :     7123344 :     return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
   20478                 :             : 
   20479                 :    62865475 :   if (IS_STACK_MODE (mode))
   20480                 :      200080 :     return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
   20481                 :             : 
   20482                 :             :   return regclass;
   20483                 :             : }
   20484                 :             : 
   20485                 :             : static reg_class_t
   20486                 :   366318255 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
   20487                 :             :                        machine_mode mode, secondary_reload_info *sri)
   20488                 :             : {
   20489                 :             :   /* Double-word spills from general registers to non-offsettable memory
   20490                 :             :      references (zero-extended addresses) require special handling.  */
   20491                 :   366318255 :   if (TARGET_64BIT
   20492                 :   313861762 :       && MEM_P (x)
   20493                 :   169314611 :       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
   20494                 :    16698868 :       && INTEGER_CLASS_P (rclass)
   20495                 :   368983011 :       && !offsettable_memref_p (x))
   20496                 :             :     {
   20497                 :     2439094 :       sri->icode = (in_p
   20498                 :     1219547 :                     ? CODE_FOR_reload_noff_load
   20499                 :             :                     : CODE_FOR_reload_noff_store);
   20500                 :             :       /* Add the cost of moving address to a temporary.  */
   20501                 :     1219547 :       sri->extra_cost = 1;
   20502                 :             : 
   20503                 :     1219547 :       return NO_REGS;
   20504                 :             :     }
   20505                 :             : 
   20506                 :             :   /* QImode spills from non-QI registers require
   20507                 :             :      intermediate register on 32bit targets.  */
   20508                 :   365098708 :   if (mode == QImode
   20509                 :   365098708 :       && ((!TARGET_64BIT && !in_p
   20510                 :      557946 :            && INTEGER_CLASS_P (rclass)
   20511                 :      557894 :            && MAYBE_NON_Q_CLASS_P (rclass))
   20512                 :    21908244 :           || (!TARGET_AVX512DQ
   20513                 :    21751720 :               && MAYBE_MASK_CLASS_P (rclass))))
   20514                 :             :     {
   20515                 :        7899 :       int regno = true_regnum (x);
   20516                 :             : 
   20517                 :             :       /* Return Q_REGS if the operand is in memory.  */
   20518                 :        7899 :       if (regno == -1)
   20519                 :             :         return Q_REGS;
   20520                 :             : 
   20521                 :             :       return NO_REGS;
   20522                 :             :     }
   20523                 :             : 
   20524                 :             :   /* Require movement to gpr, and then store to memory.  */
   20525                 :   365090809 :   if ((mode == HFmode || mode == HImode || mode == V2QImode
   20526                 :             :        || mode == BFmode)
   20527                 :     3482791 :       && !TARGET_SSE4_1
   20528                 :     2880873 :       && SSE_CLASS_P (rclass)
   20529                 :      179634 :       && !in_p && MEM_P (x))
   20530                 :             :     {
   20531                 :       82612 :       sri->extra_cost = 1;
   20532                 :       82612 :       return GENERAL_REGS;
   20533                 :             :     }
   20534                 :             : 
   20535                 :             :   /* This condition handles corner case where an expression involving
   20536                 :             :      pointers gets vectorized.  We're trying to use the address of a
   20537                 :             :      stack slot as a vector initializer.
   20538                 :             : 
   20539                 :             :      (set (reg:V2DI 74 [ vect_cst_.2 ])
   20540                 :             :           (vec_duplicate:V2DI (reg/f:DI 20 frame)))
   20541                 :             : 
   20542                 :             :      Eventually frame gets turned into sp+offset like this:
   20543                 :             : 
   20544                 :             :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20545                 :             :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   20546                 :             :                                        (const_int 392 [0x188]))))
   20547                 :             : 
   20548                 :             :      That later gets turned into:
   20549                 :             : 
   20550                 :             :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20551                 :             :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   20552                 :             :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
   20553                 :             : 
   20554                 :             :      We'll have the following reload recorded:
   20555                 :             : 
   20556                 :             :      Reload 0: reload_in (DI) =
   20557                 :             :            (plus:DI (reg/f:DI 7 sp)
   20558                 :             :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
   20559                 :             :      reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20560                 :             :      SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
   20561                 :             :      reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
   20562                 :             :      reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20563                 :             :      reload_reg_rtx: (reg:V2DI 22 xmm1)
   20564                 :             : 
   20565                 :             :      Which isn't going to work since SSE instructions can't handle scalar
   20566                 :             :      additions.  Returning GENERAL_REGS forces the addition into integer
   20567                 :             :      register and reload can handle subsequent reloads without problems.  */
   20568                 :             : 
   20569                 :   214039788 :   if (in_p && GET_CODE (x) == PLUS
   20570                 :           2 :       && SSE_CLASS_P (rclass)
   20571                 :   365008197 :       && SCALAR_INT_MODE_P (mode))
   20572                 :             :     return GENERAL_REGS;
   20573                 :             : 
   20574                 :             :   return NO_REGS;
   20575                 :             : }
   20576                 :             : 
   20577                 :             : /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
   20578                 :             : 
   20579                 :             : static bool
   20580                 :   684960813 : ix86_class_likely_spilled_p (reg_class_t rclass)
   20581                 :             : {
   20582                 :   675597930 :   switch (rclass)
   20583                 :             :     {
   20584                 :             :       case AREG:
   20585                 :             :       case DREG:
   20586                 :             :       case CREG:
   20587                 :             :       case BREG:
   20588                 :             :       case AD_REGS:
   20589                 :             :       case SIREG:
   20590                 :             :       case DIREG:
   20591                 :             :       case SSE_FIRST_REG:
   20592                 :             :       case FP_TOP_REG:
   20593                 :             :       case FP_SECOND_REG:
   20594                 :             :         return true;
   20595                 :             : 
   20596                 :   654837452 :       default:
   20597                 :   654837452 :         break;
   20598                 :             :     }
   20599                 :             : 
   20600                 :   654837452 :   return false;
   20601                 :             : }
   20602                 :             : 
   20603                 :             : /* Implement TARGET_CALLEE_SAVE_COST.  */
   20604                 :             : 
   20605                 :             : static int
   20606                 :    79189446 : ix86_callee_save_cost (spill_cost_type, unsigned int hard_regno, machine_mode,
   20607                 :             :                        unsigned int, int mem_cost, const HARD_REG_SET &, bool)
   20608                 :             : {
   20609                 :             :   /* Account for the fact that push and pop are shorter and do their
   20610                 :             :      own allocation and deallocation.  */
   20611                 :    79189446 :   if (GENERAL_REGNO_P (hard_regno))
   20612                 :             :     {
   20613                 :             :       /* push is 1 byte while typical spill is 4-5 bytes.
   20614                 :             :          ??? We probably should adjust size costs accordingly.
   20615                 :             :          Costs are relative to reg-reg move that has 2 bytes for 32bit
   20616                 :             :          and 3 bytes otherwise.  Be sure that no cost table sets cost
   20617                 :             :          to 2, so we end up with 0.  */
   20618                 :    79180248 :       if (mem_cost <= 2 || optimize_function_for_size_p (cfun))
   20619                 :     3571222 :         return 1;
   20620                 :    75609026 :       return mem_cost - 2;
   20621                 :             :     }
   20622                 :             :   return mem_cost;
   20623                 :             : }
   20624                 :             : 
   20625                 :             : /* Return true if a set of DST by the expression SRC should be allowed.
   20626                 :             :    This prevents complex sets of likely_spilled hard regs before split1.  */
   20627                 :             : 
   20628                 :             : bool
   20629                 :   592973269 : ix86_hardreg_mov_ok (rtx dst, rtx src)
   20630                 :             : {
   20631                 :             :   /* Avoid complex sets of likely_spilled hard registers before reload.  */
   20632                 :   486306933 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   20633                 :   285145763 :       && !REG_P (src) && !MEM_P (src)
   20634                 :    91921115 :       && !(VECTOR_MODE_P (GET_MODE (dst))
   20635                 :    91921115 :            ? standard_sse_constant_p (src, GET_MODE (dst))
   20636                 :    45734671 :            : x86_64_immediate_operand (src, GET_MODE (dst)))
   20637                 :     9362883 :       && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
   20638                 :   601158676 :       && ix86_pre_reload_split ())
   20639                 :             :     return false;
   20640                 :             :   return true;
   20641                 :             : }
   20642                 :             : 
   20643                 :             : /* If we are copying between registers from different register sets
   20644                 :             :    (e.g. FP and integer), we may need a memory location.
   20645                 :             : 
   20646                 :             :    The function can't work reliably when one of the CLASSES is a class
   20647                 :             :    containing registers from multiple sets.  We avoid this by never combining
   20648                 :             :    different sets in a single alternative in the machine description.
   20649                 :             :    Ensure that this constraint holds to avoid unexpected surprises.
   20650                 :             : 
   20651                 :             :    When STRICT is false, we are being called from REGISTER_MOVE_COST,
   20652                 :             :    so do not enforce these sanity checks.
   20653                 :             : 
   20654                 :             :    To optimize register_move_cost performance, define inline variant.  */
   20655                 :             : 
   20656                 :             : static inline bool
   20657                 :  5530894275 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   20658                 :             :                                 reg_class_t class2, int strict)
   20659                 :             : {
   20660                 :  5530894275 :   if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
   20661                 :             :     return false;
   20662                 :             : 
   20663                 :  5500218169 :   if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
   20664                 :  4687173694 :       || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
   20665                 :  4002657264 :       || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
   20666                 :  3818967412 :       || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
   20667                 :  3645134918 :       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
   20668                 :  3645134918 :       || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
   20669                 :  3645134918 :       || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
   20670                 :  8979721121 :       || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
   20671                 :             :     {
   20672                 :  2178543653 :       gcc_assert (!strict || lra_in_progress);
   20673                 :             :       return true;
   20674                 :             :     }
   20675                 :             : 
   20676                 :  3321674516 :   if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
   20677                 :             :     return true;
   20678                 :             : 
   20679                 :             :   /* ??? This is a lie.  We do have moves between mmx/general, and for
   20680                 :             :      mmx/sse2.  But by saying we need secondary memory we discourage the
   20681                 :             :      register allocator from using the mmx registers unless needed.  */
   20682                 :  3176381267 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   20683                 :             :     return true;
   20684                 :             : 
   20685                 :             :   /* Between mask and general, we have moves no larger than word size.  */
   20686                 :  3082290189 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   20687                 :             :     {
   20688                 :     2612998 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
   20689                 :     3312088 :           || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   20690                 :      223983 :         return true;
   20691                 :             :     }
   20692                 :             : 
   20693                 :  3082066206 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   20694                 :             :     {
   20695                 :             :       /* SSE1 doesn't have any direct moves from other classes.  */
   20696                 :   669967781 :       if (!TARGET_SSE2)
   20697                 :             :         return true;
   20698                 :             : 
   20699                 :   667438550 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
   20700                 :             :         return true;
   20701                 :             : 
   20702                 :             :       /* If the target says that inter-unit moves are more expensive
   20703                 :             :          than moving through memory, then don't generate them.  */
   20704                 :  1000353449 :       if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
   20705                 :   999669210 :           || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
   20706                 :     1726429 :         return true;
   20707                 :             : 
   20708                 :             :       /* With SSE4.1, *mov{ti,di}_internal supports moves between
   20709                 :             :          SSE_REGS and GENERAL_REGS using pinsr{q,d} or pextr{q,d}.  */
   20710                 :   665712121 :       if (TARGET_SSE4_1
   20711                 :    36042469 :           && (TARGET_64BIT ? mode == TImode : mode == DImode))
   20712                 :             :         return false;
   20713                 :             : 
   20714                 :   664148857 :       int msize = GET_MODE_SIZE (mode);
   20715                 :             : 
   20716                 :             :       /* Between SSE and general, we have moves no larger than word size.  */
   20717                 :   680444723 :       if (msize > UNITS_PER_WORD)
   20718                 :             :         return true;
   20719                 :             : 
   20720                 :             :       /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
   20721                 :             :          Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16.  */
   20722                 :   574438240 :       int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
   20723                 :             : 
   20724                 :   574438240 :       if (msize < minsize)
   20725                 :             :         return true;
   20726                 :             :     }
   20727                 :             : 
   20728                 :             :   return false;
   20729                 :             : }
   20730                 :             : 
   20731                 :             : /* Implement TARGET_SECONDARY_MEMORY_NEEDED.  */
   20732                 :             : 
   20733                 :             : static bool
   20734                 :    69322448 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   20735                 :             :                               reg_class_t class2)
   20736                 :             : {
   20737                 :    69322448 :   return inline_secondary_memory_needed (mode, class1, class2, true);
   20738                 :             : }
   20739                 :             : 
   20740                 :             : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
   20741                 :             : 
   20742                 :             :    get_secondary_mem widens integral modes to BITS_PER_WORD.
   20743                 :             :    There is no need to emit full 64 bit move on 64 bit targets
   20744                 :             :    for integral modes that can be moved using 32 bit move.  */
   20745                 :             : 
   20746                 :             : static machine_mode
   20747                 :       13136 : ix86_secondary_memory_needed_mode (machine_mode mode)
   20748                 :             : {
   20749                 :       26272 :   if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
   20750                 :           9 :     return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
   20751                 :             :   return mode;
   20752                 :             : }
   20753                 :             : 
   20754                 :             : /* Implement the TARGET_CLASS_MAX_NREGS hook.
   20755                 :             : 
   20756                 :             :    On the 80386, this is the size of MODE in words,
   20757                 :             :    except in the FP regs, where a single reg is always enough.  */
   20758                 :             : 
   20759                 :             : static unsigned char
   20760                 :  6315579680 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
   20761                 :             : {
   20762                 :  6315579680 :   if (MAYBE_INTEGER_CLASS_P (rclass))
   20763                 :             :     {
   20764                 :  4235092821 :       if (mode == XFmode)
   20765                 :   143580647 :         return (TARGET_64BIT ? 2 : 3);
   20766                 :  4091512174 :       else if (mode == XCmode)
   20767                 :   143580286 :         return (TARGET_64BIT ? 4 : 6);
   20768                 :             :       else
   20769                 :  8004575045 :         return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   20770                 :             :     }
   20771                 :             :   else
   20772                 :             :     {
   20773                 :  2080486859 :       if (COMPLEX_MODE_P (mode))
   20774                 :             :         return 2;
   20775                 :             :       else
   20776                 :  1790135988 :         return 1;
   20777                 :             :     }
   20778                 :             : }
   20779                 :             : 
   20780                 :             : /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   20781                 :             : 
   20782                 :             : static bool
   20783                 :    39580101 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
   20784                 :             :                             reg_class_t regclass)
   20785                 :             : {
   20786                 :    39580101 :   if (from == to)
   20787                 :             :     return true;
   20788                 :             : 
   20789                 :             :   /* x87 registers can't do subreg at all, as all values are reformatted
   20790                 :             :      to extended precision.  */
   20791                 :    38115221 :   if (MAYBE_FLOAT_CLASS_P (regclass))
   20792                 :             :     return false;
   20793                 :             : 
   20794                 :    33774491 :   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
   20795                 :             :     {
   20796                 :             :       /* Vector registers do not support QI or HImode loads.  If we don't
   20797                 :             :          disallow a change to these modes, reload will assume it's ok to
   20798                 :             :          drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
   20799                 :             :          the vec_dupv4hi pattern.
   20800                 :             :          NB: SSE2 can load 16bit data to sse register via pinsrw.  */
   20801                 :    16314508 :       int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
   20802                 :    16314508 :       if (GET_MODE_SIZE (from) < mov_size
   20803                 :    32628731 :           || GET_MODE_SIZE (to) < mov_size)
   20804                 :             :         return false;
   20805                 :             :     }
   20806                 :             : 
   20807                 :             :   return true;
   20808                 :             : }
   20809                 :             : 
   20810                 :             : /* Return index of MODE in the sse load/store tables.  */
   20811                 :             : 
   20812                 :             : static inline int
   20813                 :   763597499 : sse_store_index (machine_mode mode)
   20814                 :             : {
   20815                 :             :   /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
   20816                 :             :      costs to processor_costs, which requires changes to all entries in
   20817                 :             :      processor cost table.  */
   20818                 :   763597499 :   if (mode == E_HFmode)
   20819                 :   133516180 :     mode = E_SFmode;
   20820                 :             : 
   20821                 :  1527194998 :   switch (GET_MODE_SIZE (mode))
   20822                 :             :     {
   20823                 :             :     case 4:
   20824                 :             :       return 0;
   20825                 :   148222039 :     case 8:
   20826                 :   148222039 :       return 1;
   20827                 :   207490612 :     case 16:
   20828                 :   207490612 :       return 2;
   20829                 :    28470040 :     case 32:
   20830                 :    28470040 :       return 3;
   20831                 :    23738993 :     case 64:
   20832                 :    23738993 :       return 4;
   20833                 :    92205032 :     default:
   20834                 :    92205032 :       return -1;
   20835                 :             :     }
   20836                 :             : }
   20837                 :             : 
   20838                 :             : /* Return the cost of moving data of mode M between a
   20839                 :             :    register and memory.  A value of 2 is the default; this cost is
   20840                 :             :    relative to those in `REGISTER_MOVE_COST'.
   20841                 :             : 
   20842                 :             :    This function is used extensively by register_move_cost that is used to
   20843                 :             :    build tables at startup.  Make it inline in this case.
   20844                 :             :    When IN is 2, return maximum of in and out move cost.
   20845                 :             : 
   20846                 :             :    If moving between registers and memory is more expensive than
   20847                 :             :    between two registers, you should define this macro to express the
   20848                 :             :    relative cost.
   20849                 :             : 
   20850                 :             :    Model also increased moving costs of QImode registers in non
   20851                 :             :    Q_REGS classes.
   20852                 :             :  */
   20853                 :             : static inline int
   20854                 :  6816164369 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
   20855                 :             : {
   20856                 :  6816164369 :   int cost;
   20857                 :             : 
   20858                 :  6816164369 :   if (FLOAT_CLASS_P (regclass))
   20859                 :             :     {
   20860                 :   351382718 :       int index;
   20861                 :   351382718 :       switch (mode)
   20862                 :             :         {
   20863                 :             :           case E_SFmode:
   20864                 :             :             index = 0;
   20865                 :             :             break;
   20866                 :             :           case E_DFmode:
   20867                 :             :             index = 1;
   20868                 :             :             break;
   20869                 :             :           case E_XFmode:
   20870                 :             :             index = 2;
   20871                 :             :             break;
   20872                 :             :           default:
   20873                 :             :             return 100;
   20874                 :             :         }
   20875                 :   102759112 :       if (in == 2)
   20876                 :    98923161 :         return MAX (ix86_cost->hard_register.fp_load [index],
   20877                 :             :                     ix86_cost->hard_register.fp_store [index]);
   20878                 :     3835951 :       return in ? ix86_cost->hard_register.fp_load [index]
   20879                 :     3835951 :                 : ix86_cost->hard_register.fp_store [index];
   20880                 :             :     }
   20881                 :  6464781651 :   if (SSE_CLASS_P (regclass))
   20882                 :             :     {
   20883                 :   638356091 :       int index = sse_store_index (mode);
   20884                 :   638356091 :       if (index == -1)
   20885                 :             :         return 100;
   20886                 :   546343630 :       if (in == 2)
   20887                 :   387307470 :         return MAX (ix86_cost->hard_register.sse_load [index],
   20888                 :             :                     ix86_cost->hard_register.sse_store [index]);
   20889                 :   159036160 :       return in ? ix86_cost->hard_register.sse_load [index]
   20890                 :   159036160 :                 : ix86_cost->hard_register.sse_store [index];
   20891                 :             :     }
   20892                 :  5826425560 :   if (MASK_CLASS_P (regclass))
   20893                 :             :     {
   20894                 :   110507108 :       int index;
   20895                 :   221014216 :       switch (GET_MODE_SIZE (mode))
   20896                 :             :         {
   20897                 :             :         case 1:
   20898                 :             :           index = 0;
   20899                 :             :           break;
   20900                 :     8708406 :         case 2:
   20901                 :     8708406 :           index = 1;
   20902                 :     8708406 :           break;
   20903                 :             :         /* DImode loads and stores assumed to cost the same as SImode.  */
   20904                 :    39127522 :         case 4:
   20905                 :    39127522 :         case 8:
   20906                 :    39127522 :           index = 2;
   20907                 :    39127522 :           break;
   20908                 :             :         default:
   20909                 :             :           return 100;
   20910                 :             :         }
   20911                 :             : 
   20912                 :    51323508 :       if (in == 2)
   20913                 :      594672 :         return MAX (ix86_cost->hard_register.mask_load[index],
   20914                 :             :                     ix86_cost->hard_register.mask_store[index]);
   20915                 :    50728836 :       return in ? ix86_cost->hard_register.mask_load[2]
   20916                 :    50728836 :                 : ix86_cost->hard_register.mask_store[2];
   20917                 :             :     }
   20918                 :  5715918452 :   if (MMX_CLASS_P (regclass))
   20919                 :             :     {
   20920                 :   170381939 :       int index;
   20921                 :   340763878 :       switch (GET_MODE_SIZE (mode))
   20922                 :             :         {
   20923                 :             :           case 4:
   20924                 :             :             index = 0;
   20925                 :             :             break;
   20926                 :    98507359 :           case 8:
   20927                 :    98507359 :             index = 1;
   20928                 :    98507359 :             break;
   20929                 :             :           default:
   20930                 :             :             return 100;
   20931                 :             :         }
   20932                 :   134871779 :       if (in == 2)
   20933                 :   115425717 :         return MAX (ix86_cost->hard_register.mmx_load [index],
   20934                 :             :                     ix86_cost->hard_register.mmx_store [index]);
   20935                 :    19446062 :       return in ? ix86_cost->hard_register.mmx_load [index]
   20936                 :    19446062 :                 : ix86_cost->hard_register.mmx_store [index];
   20937                 :             :     }
   20938                 : 11091073026 :   switch (GET_MODE_SIZE (mode))
   20939                 :             :     {
   20940                 :   121462228 :       case 1:
   20941                 :   121462228 :         if (Q_CLASS_P (regclass) || TARGET_64BIT)
   20942                 :             :           {
   20943                 :   118873424 :             if (!in)
   20944                 :    19068368 :               return ix86_cost->hard_register.int_store[0];
   20945                 :    99805056 :             if (TARGET_PARTIAL_REG_DEPENDENCY
   20946                 :    99805056 :                 && optimize_function_for_speed_p (cfun))
   20947                 :    93151468 :               cost = ix86_cost->hard_register.movzbl_load;
   20948                 :             :             else
   20949                 :     6653588 :               cost = ix86_cost->hard_register.int_load[0];
   20950                 :    99805056 :             if (in == 2)
   20951                 :    80706640 :               return MAX (cost, ix86_cost->hard_register.int_store[0]);
   20952                 :             :             return cost;
   20953                 :             :           }
   20954                 :             :         else
   20955                 :             :           {
   20956                 :     2588804 :            if (in == 2)
   20957                 :     1833320 :              return MAX (ix86_cost->hard_register.movzbl_load,
   20958                 :             :                          ix86_cost->hard_register.int_store[0] + 4);
   20959                 :      755484 :            if (in)
   20960                 :      377812 :              return ix86_cost->hard_register.movzbl_load;
   20961                 :             :            else
   20962                 :      377672 :              return ix86_cost->hard_register.int_store[0] + 4;
   20963                 :             :           }
   20964                 :   627012755 :         break;
   20965                 :   627012755 :       case 2:
   20966                 :   627012755 :         {
   20967                 :   627012755 :           int cost;
   20968                 :   627012755 :           if (in == 2)
   20969                 :   529760829 :             cost = MAX (ix86_cost->hard_register.int_load[1],
   20970                 :             :                         ix86_cost->hard_register.int_store[1]);
   20971                 :             :           else
   20972                 :    97251926 :             cost = in ? ix86_cost->hard_register.int_load[1]
   20973                 :             :                       : ix86_cost->hard_register.int_store[1];
   20974                 :             : 
   20975                 :   627012755 :           if (mode == E_HFmode)
   20976                 :             :             {
   20977                 :             :               /* Prefer SSE over GPR for HFmode.  */
   20978                 :   121501852 :               int sse_cost;
   20979                 :   121501852 :               int index = sse_store_index (mode);
   20980                 :   121501852 :               if (in == 2)
   20981                 :   111778800 :                 sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
   20982                 :             :                                 ix86_cost->hard_register.sse_store[index]);
   20983                 :             :               else
   20984                 :     9723052 :                 sse_cost = (in
   20985                 :     9723052 :                             ? ix86_cost->hard_register.sse_load [index]
   20986                 :             :                             : ix86_cost->hard_register.sse_store [index]);
   20987                 :   121501852 :               if (sse_cost >= cost)
   20988                 :   121501852 :                 cost = sse_cost + 1;
   20989                 :             :             }
   20990                 :             :           return cost;
   20991                 :             :         }
   20992                 :  4797061530 :       default:
   20993                 :  4797061530 :         if (in == 2)
   20994                 :  3668823846 :           cost = MAX (ix86_cost->hard_register.int_load[2],
   20995                 :             :                       ix86_cost->hard_register.int_store[2]);
   20996                 :  1128237684 :         else if (in)
   20997                 :   564302524 :           cost = ix86_cost->hard_register.int_load[2];
   20998                 :             :         else
   20999                 :   563935160 :           cost = ix86_cost->hard_register.int_store[2];
   21000                 :             :         /* Multiply with the number of GPR moves needed.  */
   21001                 :  9712801253 :         return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21002                 :             :     }
   21003                 :             : }
   21004                 :             : 
   21005                 :             : static int
   21006                 :  1814180911 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
   21007                 :             : {
   21008                 :  2720958211 :   return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
   21009                 :             : }
   21010                 :             : 
   21011                 :             : 
   21012                 :             : /* Return the cost of moving data from a register in class CLASS1 to
   21013                 :             :    one in class CLASS2.
   21014                 :             : 
   21015                 :             :    It is not required that the cost always equal 2 when FROM is the same as TO;
   21016                 :             :    on some machines it is expensive to move between registers if they are not
   21017                 :             :    general registers.  */
   21018                 :             : 
   21019                 :             : static int
   21020                 :  5461571827 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
   21021                 :             :                          reg_class_t class2_i)
   21022                 :             : {
   21023                 :  5461571827 :   enum reg_class class1 = (enum reg_class) class1_i;
   21024                 :  5461571827 :   enum reg_class class2 = (enum reg_class) class2_i;
   21025                 :             : 
   21026                 :             :   /* In case we require secondary memory, compute cost of the store followed
   21027                 :             :      by load.  In order to avoid bad register allocation choices, we need
   21028                 :             :      for this to be *at least* as high as the symmetric MEMORY_MOVE_COST.  */
   21029                 :             : 
   21030                 :  5461571827 :   if (inline_secondary_memory_needed (mode, class1, class2, false))
   21031                 :             :     {
   21032                 :  2500991729 :       int cost = 1;
   21033                 :             : 
   21034                 :  2500991729 :       cost += inline_memory_move_cost (mode, class1, 2);
   21035                 :  2500991729 :       cost += inline_memory_move_cost (mode, class2, 2);
   21036                 :             : 
   21037                 :             :       /* In case of copying from general_purpose_register we may emit multiple
   21038                 :             :          stores followed by single load causing memory size mismatch stall.
   21039                 :             :          Count this as arbitrarily high cost of 20.  */
   21040                 :  5001983458 :       if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
   21041                 :   748981563 :           && TARGET_MEMORY_MISMATCH_STALL
   21042                 :  3998954855 :           && targetm.class_max_nregs (class1, mode)
   21043                 :   748981563 :              > targetm.class_max_nregs (class2, mode))
   21044                 :   142556227 :         cost += 20;
   21045                 :             : 
   21046                 :             :       /* In the case of FP/MMX moves, the registers actually overlap, and we
   21047                 :             :          have to switch modes in order to treat them differently.  */
   21048                 :    57712895 :       if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
   21049                 :  2549615714 :           || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
   21050                 :    18177820 :         cost += 20;
   21051                 :             : 
   21052                 :  2500991729 :       return cost;
   21053                 :             :     }
   21054                 :             : 
   21055                 :             :   /* Moves between MMX and non-MMX units require secondary memory.  */
   21056                 :  2960580098 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   21057                 :           0 :     gcc_unreachable ();
   21058                 :             : 
   21059                 :  2960580098 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   21060                 :   566469846 :     return (SSE_CLASS_P (class1)
   21061                 :   566469846 :             ? ix86_cost->hard_register.sse_to_integer
   21062                 :             :             : ix86_cost->hard_register.integer_to_sse);
   21063                 :             : 
   21064                 :             :   /* Moves between mask register and GPR.  */
   21065                 :  2394110252 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   21066                 :             :     {
   21067                 :     1050891 :       return (MASK_CLASS_P (class1)
   21068                 :     1050891 :               ? ix86_cost->hard_register.mask_to_integer
   21069                 :             :               : ix86_cost->hard_register.integer_to_mask);
   21070                 :             :     }
   21071                 :             :   /* Moving between mask registers.  */
   21072                 :  2393059361 :   if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
   21073                 :      102888 :     return ix86_cost->hard_register.mask_move;
   21074                 :             : 
   21075                 :  2392956473 :   if (MAYBE_FLOAT_CLASS_P (class1))
   21076                 :    11491695 :     return ix86_cost->hard_register.fp_move;
   21077                 :  2381464778 :   if (MAYBE_SSE_CLASS_P (class1))
   21078                 :             :     {
   21079                 :   223700548 :       if (GET_MODE_BITSIZE (mode) <= 128)
   21080                 :   109364926 :         return ix86_cost->hard_register.xmm_move;
   21081                 :     4970696 :       if (GET_MODE_BITSIZE (mode) <= 256)
   21082                 :     1582714 :         return ix86_cost->hard_register.ymm_move;
   21083                 :      902634 :       return ix86_cost->hard_register.zmm_move;
   21084                 :             :     }
   21085                 :  2269614504 :   if (MAYBE_MMX_CLASS_P (class1))
   21086                 :     2113753 :     return ix86_cost->hard_register.mmx_move;
   21087                 :             :   return 2;
   21088                 :             : }
   21089                 :             : 
   21090                 :             : /* Implement TARGET_HARD_REGNO_NREGS.  This is ordinarily the length in
   21091                 :             :    words of a value of mode MODE but can be less for certain modes in
   21092                 :             :    special long registers.
   21093                 :             : 
   21094                 :             :    Actually there are no two word move instructions for consecutive
   21095                 :             :    registers.  And only registers 0-3 may have mov byte instructions
   21096                 :             :    applied to them.  */
   21097                 :             : 
   21098                 :             : static unsigned int
   21099                 :  9944787840 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
   21100                 :             : {
   21101                 :  9944787840 :   if (GENERAL_REGNO_P (regno))
   21102                 :             :     {
   21103                 :  3459056640 :       if (mode == XFmode)
   21104                 :    27098624 :         return TARGET_64BIT ? 2 : 3;
   21105                 :  3432448512 :       if (mode == XCmode)
   21106                 :    27098624 :         return TARGET_64BIT ? 4 : 6;
   21107                 :  6874464256 :       return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21108                 :             :     }
   21109                 :  6485731200 :   if (COMPLEX_MODE_P (mode))
   21110                 :             :     return 2;
   21111                 :             :   /* Register pair for mask registers.  */
   21112                 :  5687487360 :   if (mode == P2QImode || mode == P2HImode)
   21113                 :             :     return 2;
   21114                 :  5587706880 :   if (mode == V64SFmode || mode == V64SImode)
   21115                 :    99780480 :     return 4;
   21116                 :             :   return 1;
   21117                 :             : }
   21118                 :             : 
   21119                 :             : /* Implement REGMODE_NATURAL_SIZE(MODE).  */
   21120                 :             : unsigned int
   21121                 :   104679073 : ix86_regmode_natural_size (machine_mode mode)
   21122                 :             : {
   21123                 :   104679073 :   if (mode == P2HImode || mode == P2QImode)
   21124                 :        2450 :     return GET_MODE_SIZE (mode) / 2;
   21125                 :   104677848 :   return UNITS_PER_WORD;
   21126                 :             : }
   21127                 :             : 
   21128                 :             : /* Implement TARGET_HARD_REGNO_MODE_OK.  */
   21129                 :             : 
   21130                 :             : static bool
   21131                 : 58809994417 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   21132                 :             : {
   21133                 :             :   /* Flags and only flags can only hold CCmode values.  */
   21134                 : 58809994417 :   if (CC_REGNO_P (regno))
   21135                 :   472573511 :     return GET_MODE_CLASS (mode) == MODE_CC;
   21136                 : 58337420906 :   if (GET_MODE_CLASS (mode) == MODE_CC
   21137                 :             :       || GET_MODE_CLASS (mode) == MODE_RANDOM)
   21138                 :             :     return false;
   21139                 : 52616152638 :   if (STACK_REGNO_P (regno))
   21140                 :  5122549502 :     return VALID_FP_MODE_P (mode);
   21141                 : 47493603136 :   if (MASK_REGNO_P (regno))
   21142                 :             :     {
   21143                 :             :       /* Register pair only starts at even register number.  */
   21144                 :  4065534156 :       if ((mode == P2QImode || mode == P2HImode))
   21145                 :    54140026 :         return MASK_PAIR_REGNO_P(regno);
   21146                 :             : 
   21147                 :  1283995034 :       return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
   21148                 :  5270755650 :               || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
   21149                 :             :     }
   21150                 :             : 
   21151                 : 43428068980 :   if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
   21152                 :             :     return false;
   21153                 :             : 
   21154                 : 42417169831 :   if (SSE_REGNO_P (regno))
   21155                 :             :     {
   21156                 :             :       /* We implement the move patterns for all vector modes into and
   21157                 :             :          out of SSE registers, even when no operation instructions
   21158                 :             :          are available.  */
   21159                 :             : 
   21160                 :             :       /* For AVX-512 we allow, regardless of regno:
   21161                 :             :           - XI mode
   21162                 :             :           - any of 512-bit wide vector mode
   21163                 :             :           - any scalar mode.  */
   21164                 : 18473081710 :       if (TARGET_AVX512F
   21165                 :  5131861868 :           && ((VALID_AVX512F_REG_OR_XI_MODE (mode) && TARGET_EVEX512)
   21166                 :  4774768251 :               || VALID_AVX512F_SCALAR_MODE (mode)))
   21167                 :             :         return true;
   21168                 :             : 
   21169                 :             :       /* TODO check for QI/HI scalars.  */
   21170                 :             :       /* AVX512VL allows sse regs16+ for 128/256 bit modes.  */
   21171                 : 17767259521 :       if (TARGET_AVX512VL
   21172                 :  2378495918 :           && (VALID_AVX256_REG_OR_OI_MODE (mode)
   21173                 :  2120109121 :               || VALID_AVX512VL_128_REG_MODE (mode)))
   21174                 :             :         return true;
   21175                 :             : 
   21176                 :             :       /* xmm16-xmm31 are only available for AVX-512.  */
   21177                 : 17223873617 :       if (EXT_REX_SSE_REGNO_P (regno))
   21178                 :             :         return false;
   21179                 :             : 
   21180                 :             :       /* OImode and AVX modes are available only when AVX is enabled.  */
   21181                 :  9880013844 :       return ((TARGET_AVX
   21182                 :  2512687641 :                && VALID_AVX256_REG_OR_OI_MODE (mode))
   21183                 :             :               || VALID_SSE_REG_MODE (mode)
   21184                 :             :               || VALID_SSE2_REG_MODE (mode)
   21185                 :             :               || VALID_MMX_REG_MODE (mode)
   21186                 :  9880013844 :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21187                 :             :     }
   21188                 : 23944088121 :   if (MMX_REGNO_P (regno))
   21189                 :             :     {
   21190                 :             :       /* We implement the move patterns for 3DNOW modes even in MMX mode,
   21191                 :             :          so if the register is available at all, then we can move data of
   21192                 :             :          the given mode into or out of it.  */
   21193                 :  4339080526 :       return (VALID_MMX_REG_MODE (mode)
   21194                 :             :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21195                 :             :     }
   21196                 :             : 
   21197                 : 19605007595 :   if (mode == QImode)
   21198                 :             :     {
   21199                 :             :       /* Take care for QImode values - they can be in non-QI regs,
   21200                 :             :          but then they do cause partial register stalls.  */
   21201                 :   210951861 :       if (ANY_QI_REGNO_P (regno))
   21202                 :             :         return true;
   21203                 :    14872471 :       if (!TARGET_PARTIAL_REG_STALL)
   21204                 :             :         return true;
   21205                 :             :       /* LRA checks if the hard register is OK for the given mode.
   21206                 :             :          QImode values can live in non-QI regs, so we allow all
   21207                 :             :          registers here.  */
   21208                 :           0 :       if (lra_in_progress)
   21209                 :             :        return true;
   21210                 :           0 :       return !can_create_pseudo_p ();
   21211                 :             :     }
   21212                 :             :   /* We handle both integer and floats in the general purpose registers.  */
   21213                 : 19394055734 :   else if (VALID_INT_MODE_P (mode)
   21214                 : 14458772333 :            || VALID_FP_MODE_P (mode))
   21215                 :             :     return true;
   21216                 :             :   /* Lots of MMX code casts 8 byte vector modes to DImode.  If we then go
   21217                 :             :      on to use that value in smaller contexts, this can easily force a
   21218                 :             :      pseudo to be allocated to GENERAL_REGS.  Since this is no worse than
   21219                 :             :      supporting DImode, allow it.  */
   21220                 : 13373171925 :   else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
   21221                 :             :     return true;
   21222                 :             : 
   21223                 :             :   return false;
   21224                 :             : }
   21225                 :             : 
   21226                 :             : /* Implement TARGET_INSN_CALLEE_ABI.  */
   21227                 :             : 
   21228                 :             : const predefined_function_abi &
   21229                 :   245820664 : ix86_insn_callee_abi (const rtx_insn *insn)
   21230                 :             : {
   21231                 :   245820664 :   unsigned int abi_id = 0;
   21232                 :   245820664 :   rtx pat = PATTERN (insn);
   21233                 :   245820664 :   if (vzeroupper_pattern (pat, VOIDmode))
   21234                 :      247527 :     abi_id = ABI_VZEROUPPER;
   21235                 :             : 
   21236                 :   245820664 :   return function_abis[abi_id];
   21237                 :             : }
   21238                 :             : 
   21239                 :             : /* Initialize function_abis with corresponding abi_id,
   21240                 :             :    currently only handle vzeroupper.  */
   21241                 :             : void
   21242                 :       17367 : ix86_initialize_callee_abi (unsigned int abi_id)
   21243                 :             : {
   21244                 :       17367 :   gcc_assert (abi_id == ABI_VZEROUPPER);
   21245                 :       17367 :   predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
   21246                 :       17367 :   if (!vzeroupper_abi.initialized_p ())
   21247                 :             :     {
   21248                 :             :       HARD_REG_SET full_reg_clobbers;
   21249                 :        4006 :       CLEAR_HARD_REG_SET (full_reg_clobbers);
   21250                 :        4006 :       vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
   21251                 :             :     }
   21252                 :       17367 : }
   21253                 :             : 
   21254                 :             : void
   21255                 :       17367 : ix86_expand_avx_vzeroupper (void)
   21256                 :             : {
   21257                 :             :   /* Initialize vzeroupper_abi here.  */
   21258                 :       17367 :   ix86_initialize_callee_abi (ABI_VZEROUPPER);
   21259                 :       17367 :   rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
   21260                 :             :   /* Return false for non-local goto in can_nonlocal_goto.  */
   21261                 :       17367 :   make_reg_eh_region_note (insn, 0, INT_MIN);
   21262                 :             :   /* Flag used for call_insn indicates it's a fake call.  */
   21263                 :       17367 :   RTX_FLAG (insn, used) = 1;
   21264                 :       17367 : }
   21265                 :             : 
   21266                 :             : 
   21267                 :             : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The only ABI that
   21268                 :             :    saves SSE registers across calls is Win64 (thus no need to check the
   21269                 :             :    current ABI here), and with AVX enabled Win64 only guarantees that
   21270                 :             :    the low 16 bytes are saved.  */
   21271                 :             : 
   21272                 :             : static bool
   21273                 :  2158252684 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
   21274                 :             :                                      machine_mode mode)
   21275                 :             : {
   21276                 :             :   /* Special ABI for vzeroupper which only clobber higher part of sse regs.  */
   21277                 :  2158252684 :   if (abi_id == ABI_VZEROUPPER)
   21278                 :    28898044 :       return (GET_MODE_SIZE (mode) > 16
   21279                 :    28898044 :               && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
   21280                 :     4401556 :                   || LEGACY_SSE_REGNO_P (regno)));
   21281                 :             : 
   21282                 :  2804601752 :   return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
   21283                 :             : }
   21284                 :             : 
   21285                 :             : /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a
   21286                 :             :    tieable integer mode.  */
   21287                 :             : 
   21288                 :             : static bool
   21289                 :    50149067 : ix86_tieable_integer_mode_p (machine_mode mode)
   21290                 :             : {
   21291                 :    50149067 :   switch (mode)
   21292                 :             :     {
   21293                 :             :     case E_HImode:
   21294                 :             :     case E_SImode:
   21295                 :             :       return true;
   21296                 :             : 
   21297                 :     5511648 :     case E_QImode:
   21298                 :     5511648 :       return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
   21299                 :             : 
   21300                 :     9510419 :     case E_DImode:
   21301                 :     9510419 :       return TARGET_64BIT;
   21302                 :             : 
   21303                 :             :     default:
   21304                 :             :       return false;
   21305                 :             :     }
   21306                 :             : }
   21307                 :             : 
   21308                 :             : /* Implement TARGET_MODES_TIEABLE_P.
   21309                 :             : 
   21310                 :             :    Return true if MODE1 is accessible in a register that can hold MODE2
   21311                 :             :    without copying.  That is, all register classes that can hold MODE2
   21312                 :             :    can also hold MODE1.  */
   21313                 :             : 
   21314                 :             : static bool
   21315                 :    32189757 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   21316                 :             : {
   21317                 :    32189757 :   if (mode1 == mode2)
   21318                 :             :     return true;
   21319                 :             : 
   21320                 :    32100777 :   if (ix86_tieable_integer_mode_p (mode1)
   21321                 :    32100777 :       && ix86_tieable_integer_mode_p (mode2))
   21322                 :             :     return true;
   21323                 :             : 
   21324                 :             :   /* MODE2 being XFmode implies fp stack or general regs, which means we
   21325                 :             :      can tie any smaller floating point modes to it.  Note that we do not
   21326                 :             :      tie this with TFmode.  */
   21327                 :    23242366 :   if (mode2 == XFmode)
   21328                 :        4346 :     return mode1 == SFmode || mode1 == DFmode;
   21329                 :             : 
   21330                 :             :   /* MODE2 being DFmode implies fp stack, general or sse regs, which means
   21331                 :             :      that we can tie it with SFmode.  */
   21332                 :    23238020 :   if (mode2 == DFmode)
   21333                 :      257422 :     return mode1 == SFmode;
   21334                 :             : 
   21335                 :             :   /* If MODE2 is only appropriate for an SSE register, then tie with
   21336                 :             :      any other mode acceptable to SSE registers.  */
   21337                 :    22980598 :   if (GET_MODE_SIZE (mode2) == 64
   21338                 :    22980598 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21339                 :      311395 :     return (GET_MODE_SIZE (mode1) == 64
   21340                 :      311395 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21341                 :    22669203 :   if (GET_MODE_SIZE (mode2) == 32
   21342                 :    22669203 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21343                 :      454988 :     return (GET_MODE_SIZE (mode1) == 32
   21344                 :      454988 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21345                 :    22214215 :   if (GET_MODE_SIZE (mode2) == 16
   21346                 :    22214215 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21347                 :     9296954 :     return (GET_MODE_SIZE (mode1) == 16
   21348                 :     9296954 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21349                 :             : 
   21350                 :             :   /* If MODE2 is appropriate for an MMX register, then tie
   21351                 :             :      with any other mode acceptable to MMX registers.  */
   21352                 :    12917261 :   if (GET_MODE_SIZE (mode2) == 8
   21353                 :    12917261 :       && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
   21354                 :     3229655 :     return (GET_MODE_SIZE (mode1) == 8
   21355                 :     3229655 :             && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
   21356                 :             : 
   21357                 :             :   /* SCmode and DImode can be tied.  */
   21358                 :     9687606 :   if ((mode1 == E_SCmode && mode2 == E_DImode)
   21359                 :     9687606 :       || (mode1 == E_DImode && mode2 == E_SCmode))
   21360                 :         108 :     return TARGET_64BIT;
   21361                 :             : 
   21362                 :             :   /* [SD]Cmode and V2[SD]Fmode modes can be tied.  */
   21363                 :     9687498 :   if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
   21364                 :     9687498 :       || (mode1 == E_V2SFmode && mode2 == E_SCmode)
   21365                 :     9687498 :       || (mode1 == E_DCmode && mode2 == E_V2DFmode)
   21366                 :     9687498 :       || (mode1 == E_V2DFmode && mode2 == E_DCmode))
   21367                 :           0 :     return true;
   21368                 :             : 
   21369                 :             :   return false;
   21370                 :             : }
   21371                 :             : 
   21372                 :             : /* Return the cost of moving between two registers of mode MODE.  */
   21373                 :             : 
   21374                 :             : static int
   21375                 :    31018638 : ix86_set_reg_reg_cost (machine_mode mode)
   21376                 :             : {
   21377                 :    31018638 :   unsigned int units = UNITS_PER_WORD;
   21378                 :             : 
   21379                 :    31018638 :   switch (GET_MODE_CLASS (mode))
   21380                 :             :     {
   21381                 :             :     default:
   21382                 :             :       break;
   21383                 :             : 
   21384                 :             :     case MODE_CC:
   21385                 :    31018638 :       units = GET_MODE_SIZE (CCmode);
   21386                 :             :       break;
   21387                 :             : 
   21388                 :     1144793 :     case MODE_FLOAT:
   21389                 :     1144793 :       if ((TARGET_SSE && mode == TFmode)
   21390                 :      673469 :           || (TARGET_80387 && mode == XFmode)
   21391                 :      212079 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
   21392                 :      145099 :           || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
   21393                 :     2260346 :         units = GET_MODE_SIZE (mode);
   21394                 :             :       break;
   21395                 :             : 
   21396                 :     1272890 :     case MODE_COMPLEX_FLOAT:
   21397                 :     1272890 :       if ((TARGET_SSE && mode == TCmode)
   21398                 :      853414 :           || (TARGET_80387 && mode == XCmode)
   21399                 :      433834 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
   21400                 :       14240 :           || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
   21401                 :     2539516 :         units = GET_MODE_SIZE (mode);
   21402                 :             :       break;
   21403                 :             : 
   21404                 :    20740865 :     case MODE_VECTOR_INT:
   21405                 :    20740865 :     case MODE_VECTOR_FLOAT:
   21406                 :    20740865 :       if ((TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
   21407                 :    20644439 :           || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   21408                 :    20470664 :           || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   21409                 :    17910899 :           || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   21410                 :    16638055 :           || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   21411                 :    16587471 :               && VALID_MMX_REG_MODE (mode)))
   21412                 :     8309952 :         units = GET_MODE_SIZE (mode);
   21413                 :             :     }
   21414                 :             : 
   21415                 :             :   /* Return the cost of moving between two registers of mode MODE,
   21416                 :             :      assuming that the move will be in pieces of at most UNITS bytes.  */
   21417                 :    31018638 :   return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
   21418                 :             : }
   21419                 :             : 
   21420                 :             : /* Return cost of vector operation in MODE given that scalar version has
   21421                 :             :    COST.  */
   21422                 :             : 
   21423                 :             : static int
   21424                 :  2849627609 : ix86_vec_cost (machine_mode mode, int cost)
   21425                 :             : {
   21426                 :  2849627609 :   if (!VECTOR_MODE_P (mode))
   21427                 :             :     return cost;
   21428                 :             : 
   21429                 :  2848521968 :   if (GET_MODE_BITSIZE (mode) == 128
   21430                 :  2848521968 :       && TARGET_SSE_SPLIT_REGS)
   21431                 :     3474814 :     return cost * GET_MODE_BITSIZE (mode) / 64;
   21432                 :  2846784561 :   else if (GET_MODE_BITSIZE (mode) > 128
   21433                 :  2846784561 :       && TARGET_AVX256_SPLIT_REGS)
   21434                 :     1676004 :     return cost * GET_MODE_BITSIZE (mode) / 128;
   21435                 :  2845946559 :   else if (GET_MODE_BITSIZE (mode) > 256
   21436                 :  2845946559 :       && TARGET_AVX512_SPLIT_REGS)
   21437                 :      165870 :     return cost * GET_MODE_BITSIZE (mode) / 256;
   21438                 :             :   return cost;
   21439                 :             : }
   21440                 :             : 
   21441                 :             : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
   21442                 :             :    vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2.  */
   21443                 :             : static int
   21444                 :        1856 : ix86_widen_mult_cost (const struct processor_costs *cost,
   21445                 :             :                       enum machine_mode mode, bool uns_p)
   21446                 :             : {
   21447                 :        1856 :   gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
   21448                 :        1856 :   int extra_cost = 0;
   21449                 :        1856 :   int basic_cost = 0;
   21450                 :        1856 :   switch (mode)
   21451                 :             :     {
   21452                 :         207 :     case V8HImode:
   21453                 :         207 :     case V16HImode:
   21454                 :         207 :       if (!uns_p || mode == V16HImode)
   21455                 :          47 :         extra_cost = cost->sse_op * 2;
   21456                 :         207 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   21457                 :         207 :       break;
   21458                 :         336 :     case V4SImode:
   21459                 :         336 :     case V8SImode:
   21460                 :             :       /* pmulhw/pmullw can be used.  */
   21461                 :         336 :       basic_cost = cost->mulss * 2 + cost->sse_op * 2;
   21462                 :         336 :       break;
   21463                 :        1207 :     case V2DImode:
   21464                 :             :       /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
   21465                 :             :          require extra 4 mul, 4 add, 4 cmp and 2 shift.  */
   21466                 :        1207 :       if (!TARGET_SSE4_1 && !uns_p)
   21467                 :         726 :         extra_cost = (cost->mulss + cost->addss + cost->sse_op) * 4
   21468                 :         726 :                       + cost->sse_op * 2;
   21469                 :             :       /* Fallthru.  */
   21470                 :        1301 :     case V4DImode:
   21471                 :        1301 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   21472                 :        1301 :       break;
   21473                 :             :     default:
   21474                 :             :       /* Not implemented.  */
   21475                 :             :       return 100;
   21476                 :             :     }
   21477                 :        1844 :   return ix86_vec_cost (mode, basic_cost + extra_cost);
   21478                 :             : }
   21479                 :             : 
   21480                 :             : /* Return cost of multiplication in MODE.  */
   21481                 :             : 
   21482                 :             : static int
   21483                 :  1216078462 : ix86_multiplication_cost (const struct processor_costs *cost,
   21484                 :             :                           enum machine_mode mode)
   21485                 :             : {
   21486                 :  1216078462 :   machine_mode inner_mode = mode;
   21487                 :  1216078462 :   if (VECTOR_MODE_P (mode))
   21488                 :  1215109071 :     inner_mode = GET_MODE_INNER (mode);
   21489                 :             : 
   21490                 :  1216078462 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   21491                 :      729520 :     return inner_mode == DFmode ? cost->mulsd : cost->mulss;
   21492                 :  1215348942 :   else if (X87_FLOAT_MODE_P (mode))
   21493                 :      163906 :     return cost->fmul;
   21494                 :  1215185036 :   else if (FLOAT_MODE_P (mode))
   21495                 :      194766 :     return  ix86_vec_cost (mode,
   21496                 :      194766 :                            inner_mode == DFmode ? cost->mulsd : cost->mulss);
   21497                 :  1214990270 :   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21498                 :             :     {
   21499                 :  1214938531 :       int nmults, nops;
   21500                 :             :       /* Cost of reading the memory.  */
   21501                 :  1214938531 :       int extra;
   21502                 :             : 
   21503                 :  1214938531 :       switch (mode)
   21504                 :             :         {
   21505                 :    18508351 :         case V4QImode:
   21506                 :    18508351 :         case V8QImode:
   21507                 :             :           /* Partial V*QImode is emulated with 4-6 insns.  */
   21508                 :    18508351 :           nmults = 1;
   21509                 :    18508351 :           nops = 3;
   21510                 :    18508351 :           extra = 0;
   21511                 :             : 
   21512                 :    18508351 :           if (TARGET_AVX512BW && TARGET_AVX512VL)
   21513                 :             :             ;
   21514                 :    18404834 :           else if (TARGET_AVX2)
   21515                 :             :             nops += 2;
   21516                 :    17890013 :           else if (TARGET_XOP)
   21517                 :        9504 :             extra += cost->sse_load[2];
   21518                 :             :           else
   21519                 :             :             {
   21520                 :    17880509 :               nops += 1;
   21521                 :    17880509 :               extra += cost->sse_load[2];
   21522                 :             :             }
   21523                 :    18508351 :           goto do_qimode;
   21524                 :             : 
   21525                 :     9255729 :         case V16QImode:
   21526                 :             :           /* V*QImode is emulated with 4-11 insns.  */
   21527                 :     9255729 :           nmults = 1;
   21528                 :     9255729 :           nops = 3;
   21529                 :     9255729 :           extra = 0;
   21530                 :             : 
   21531                 :     9255729 :           if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
   21532                 :             :             {
   21533                 :      307617 :               if (!(TARGET_AVX512BW && TARGET_AVX512VL))
   21534                 :      256085 :                 nops += 3;
   21535                 :             :             }
   21536                 :     8948112 :           else if (TARGET_XOP)
   21537                 :             :             {
   21538                 :        5200 :               nmults += 1;
   21539                 :        5200 :               nops += 2;
   21540                 :        5200 :               extra += cost->sse_load[2];
   21541                 :             :             }
   21542                 :             :           else
   21543                 :             :             {
   21544                 :     8942912 :               nmults += 1;
   21545                 :     8942912 :               nops += 4;
   21546                 :     8942912 :               extra += cost->sse_load[2];
   21547                 :             :             }
   21548                 :     9255729 :           goto do_qimode;
   21549                 :             : 
   21550                 :     9254164 :         case V32QImode:
   21551                 :     9254164 :           nmults = 1;
   21552                 :     9254164 :           nops = 3;
   21553                 :     9254164 :           extra = 0;
   21554                 :             : 
   21555                 :     9254164 :           if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
   21556                 :             :             {
   21557                 :     9169927 :               nmults += 1;
   21558                 :     9169927 :               nops += 4;
   21559                 :     9169927 :               extra += cost->sse_load[3] * 2;
   21560                 :             :             }
   21561                 :     9254164 :           goto do_qimode;
   21562                 :             : 
   21563                 :     9253436 :         case V64QImode:
   21564                 :     9253436 :           nmults = 2;
   21565                 :     9253436 :           nops = 9;
   21566                 :     9253436 :           extra = cost->sse_load[3] * 2 + cost->sse_load[4] * 2;
   21567                 :             : 
   21568                 :    46271680 :         do_qimode:
   21569                 :    46271680 :           return ix86_vec_cost (mode, cost->mulss * nmults
   21570                 :    46271680 :                                 + cost->sse_op * nops) + extra;
   21571                 :             : 
   21572                 :    39570683 :         case V4SImode:
   21573                 :             :           /* pmulld is used in this case. No emulation is needed.  */
   21574                 :    39570683 :           if (TARGET_SSE4_1)
   21575                 :     2224044 :             goto do_native;
   21576                 :             :           /* V4SImode is emulated with 7 insns.  */
   21577                 :             :           else
   21578                 :    37346639 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
   21579                 :             : 
   21580                 :   159943187 :         case V2DImode:
   21581                 :   159943187 :         case V4DImode:
   21582                 :             :           /* vpmullq is used in this case. No emulation is needed.  */
   21583                 :   159943187 :           if (TARGET_AVX512DQ && TARGET_AVX512VL)
   21584                 :      564147 :             goto do_native;
   21585                 :             :           /* V*DImode is emulated with 6-8 insns.  */
   21586                 :   159379040 :           else if (TARGET_XOP && mode == V2DImode)
   21587                 :       52494 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
   21588                 :             :           /* FALLTHRU */
   21589                 :   239244290 :         case V8DImode:
   21590                 :             :           /* vpmullq is used in this case. No emulation is needed.  */
   21591                 :   239244290 :           if (TARGET_AVX512DQ && mode == V8DImode)
   21592                 :      377841 :             goto do_native;
   21593                 :             :           else
   21594                 :   238866449 :             return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
   21595                 :             : 
   21596                 :   892401269 :         default:
   21597                 :   892401269 :         do_native:
   21598                 :   892401269 :           return ix86_vec_cost (mode, cost->mulss);
   21599                 :             :         }
   21600                 :             :     }
   21601                 :             :   else
   21602                 :      103477 :     return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
   21603                 :             : }
   21604                 :             : 
   21605                 :             : /* Return cost of multiplication in MODE.  */
   21606                 :             : 
   21607                 :             : static int
   21608                 :    72188583 : ix86_division_cost (const struct processor_costs *cost,
   21609                 :             :                           enum machine_mode mode)
   21610                 :             : {
   21611                 :    72188583 :   machine_mode inner_mode = mode;
   21612                 :    72188583 :   if (VECTOR_MODE_P (mode))
   21613                 :    53850668 :     inner_mode = GET_MODE_INNER (mode);
   21614                 :             : 
   21615                 :    72188583 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   21616                 :      225294 :     return inner_mode == DFmode ? cost->divsd : cost->divss;
   21617                 :    71963289 :   else if (X87_FLOAT_MODE_P (mode))
   21618                 :       46531 :     return cost->fdiv;
   21619                 :    71916758 :   else if (FLOAT_MODE_P (mode))
   21620                 :       16246 :     return ix86_vec_cost (mode,
   21621                 :       16246 :                           inner_mode == DFmode ? cost->divsd : cost->divss);
   21622                 :             :   else
   21623                 :    79870450 :     return cost->divide[MODE_INDEX (mode)];
   21624                 :             : }
   21625                 :             : 
   21626                 :             : /* Return cost of shift in MODE.
   21627                 :             :    If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
   21628                 :             :    AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
   21629                 :             :    if op1 is a result of subreg.
   21630                 :             : 
   21631                 :             :    SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored.  */
   21632                 :             : 
   21633                 :             : static int
   21634                 :   767864808 : ix86_shift_rotate_cost (const struct processor_costs *cost,
   21635                 :             :                         enum rtx_code code,
   21636                 :             :                         enum machine_mode mode, bool constant_op1,
   21637                 :             :                         HOST_WIDE_INT op1_val,
   21638                 :             :                         bool and_in_op1,
   21639                 :             :                         bool shift_and_truncate,
   21640                 :             :                         bool *skip_op0, bool *skip_op1)
   21641                 :             : {
   21642                 :   767864808 :   if (skip_op0)
   21643                 :   767823867 :     *skip_op0 = *skip_op1 = false;
   21644                 :             : 
   21645                 :   767864808 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21646                 :             :     {
   21647                 :   401033695 :       int count;
   21648                 :             :       /* Cost of reading the memory.  */
   21649                 :   401033695 :       int extra;
   21650                 :             : 
   21651                 :   401033695 :       switch (mode)
   21652                 :             :         {
   21653                 :     5888491 :         case V4QImode:
   21654                 :     5888491 :         case V8QImode:
   21655                 :     5888491 :           if (TARGET_AVX2)
   21656                 :             :             /* Use vpbroadcast.  */
   21657                 :      196552 :             extra = cost->sse_op;
   21658                 :             :           else
   21659                 :     5691939 :             extra = cost->sse_load[2];
   21660                 :             : 
   21661                 :     5888491 :           if (constant_op1)
   21662                 :             :             {
   21663                 :     5888479 :               if (code == ASHIFTRT)
   21664                 :             :                 {
   21665                 :          20 :                   count = 4;
   21666                 :          20 :                   extra *= 2;
   21667                 :             :                 }
   21668                 :             :               else
   21669                 :             :                 count = 2;
   21670                 :             :             }
   21671                 :          12 :           else if (TARGET_AVX512BW && TARGET_AVX512VL)
   21672                 :          12 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   21673                 :           0 :           else if (TARGET_SSE4_1)
   21674                 :             :             count = 5;
   21675                 :           0 :           else if (code == ASHIFTRT)
   21676                 :             :             count = 6;
   21677                 :             :           else
   21678                 :           0 :             count = 5;
   21679                 :     5888479 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   21680                 :             : 
   21681                 :     2946440 :         case V16QImode:
   21682                 :     2946440 :           if (TARGET_XOP)
   21683                 :             :             {
   21684                 :             :               /* For XOP we use vpshab, which requires a broadcast of the
   21685                 :             :                  value to the variable shift insn.  For constants this
   21686                 :             :                  means a V16Q const in mem; even when we can perform the
   21687                 :             :                  shift with one insn set the cost to prefer paddb.  */
   21688                 :        4634 :               if (constant_op1)
   21689                 :             :                 {
   21690                 :        3702 :                   extra = cost->sse_load[2];
   21691                 :        3702 :                   return ix86_vec_cost (mode, cost->sse_op) + extra;
   21692                 :             :                 }
   21693                 :             :               else
   21694                 :             :                 {
   21695                 :         932 :                   count = (code == ASHIFT) ? 3 : 4;
   21696                 :         932 :                   return ix86_vec_cost (mode, cost->sse_op * count);
   21697                 :             :                 }
   21698                 :             :             }
   21699                 :             :           /* FALLTHRU */
   21700                 :     5886044 :         case V32QImode:
   21701                 :     5886044 :           if (TARGET_AVX2)
   21702                 :             :             /* Use vpbroadcast.  */
   21703                 :      194743 :             extra = cost->sse_op;
   21704                 :             :           else
   21705                 :     5691301 :             extra = (mode == V16QImode) ? cost->sse_load[2] : cost->sse_load[3];
   21706                 :             : 
   21707                 :     5886044 :           if (constant_op1)
   21708                 :             :             {
   21709                 :     5885984 :               if (code == ASHIFTRT)
   21710                 :             :                 {
   21711                 :         110 :                   count = 4;
   21712                 :         110 :                   extra *= 2;
   21713                 :             :                 }
   21714                 :             :               else
   21715                 :             :                 count = 2;
   21716                 :             :             }
   21717                 :          60 :           else if (TARGET_AVX512BW
   21718                 :          40 :                    && ((mode == V32QImode && !TARGET_PREFER_AVX256)
   21719                 :          20 :                        || (mode == V16QImode && TARGET_AVX512VL
   21720                 :          20 :                            && !TARGET_PREFER_AVX128)))
   21721                 :          40 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   21722                 :          20 :           else if (TARGET_AVX2
   21723                 :           0 :                    && mode == V16QImode && !TARGET_PREFER_AVX128)
   21724                 :             :             count = 6;
   21725                 :          20 :           else if (TARGET_SSE4_1)
   21726                 :             :             count = 9;
   21727                 :          20 :           else if (code == ASHIFTRT)
   21728                 :             :             count = 10;
   21729                 :             :           else
   21730                 :          20 :             count = 9;
   21731                 :     5886004 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   21732                 :             : 
   21733                 :    53080704 :         case V2DImode:
   21734                 :    53080704 :         case V4DImode:
   21735                 :             :           /* V*DImode arithmetic right shift is emulated.  */
   21736                 :    53080704 :           if (code == ASHIFTRT && !TARGET_AVX512VL)
   21737                 :             :             {
   21738                 :        1182 :               if (constant_op1)
   21739                 :             :                 {
   21740                 :         491 :                   if (op1_val == 63)
   21741                 :          98 :                     count = TARGET_SSE4_2 ? 1 : 2;
   21742                 :         393 :                   else if (TARGET_XOP)
   21743                 :             :                     count = 2;
   21744                 :          94 :                   else if (TARGET_SSE4_1)
   21745                 :             :                     count = 3;
   21746                 :             :                   else
   21747                 :          93 :                     count = 4;
   21748                 :             :                 }
   21749                 :         691 :               else if (TARGET_XOP)
   21750                 :             :                 count = 3;
   21751                 :          10 :               else if (TARGET_SSE4_2)
   21752                 :             :                 count = 4;
   21753                 :             :               else
   21754                 :        1182 :                 count = 5;
   21755                 :             : 
   21756                 :        1182 :               return ix86_vec_cost (mode, cost->sse_op * count);
   21757                 :             :             }
   21758                 :             :           /* FALLTHRU */
   21759                 :   389253344 :         default:
   21760                 :   389253344 :           return ix86_vec_cost (mode, cost->sse_op);
   21761                 :             :         }
   21762                 :             :     }
   21763                 :             : 
   21764                 :   742295375 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21765                 :             :     {
   21766                 :   187990091 :       if (constant_op1)
   21767                 :             :         {
   21768                 :   187955407 :           if (op1_val > 32)
   21769                 :   133524173 :             return cost->shift_const + COSTS_N_INSNS (2);
   21770                 :             :           else
   21771                 :    54431234 :             return cost->shift_const * 2;
   21772                 :             :         }
   21773                 :             :       else
   21774                 :             :         {
   21775                 :       34684 :           if (and_in_op1)
   21776                 :          63 :             return cost->shift_var * 2;
   21777                 :             :           else
   21778                 :       34621 :             return cost->shift_var * 6 + COSTS_N_INSNS (2);
   21779                 :             :         }
   21780                 :             :     }
   21781                 :             :   else
   21782                 :             :     {
   21783                 :   178841022 :       if (constant_op1)
   21784                 :   178140593 :         return cost->shift_const;
   21785                 :      700429 :       else if (shift_and_truncate)
   21786                 :             :         {
   21787                 :       22617 :           if (skip_op0)
   21788                 :       22617 :             *skip_op0 = *skip_op1 = true;
   21789                 :             :           /* Return the cost after shift-and truncation.  */
   21790                 :       22617 :           return cost->shift_var;
   21791                 :             :         }
   21792                 :             :       else
   21793                 :      677812 :         return cost->shift_var;
   21794                 :             :     }
   21795                 :             : }
   21796                 :             : 
   21797                 :             : static int
   21798                 :   134949599 : ix86_insn_cost (rtx_insn *insn, bool speed)
   21799                 :             : {
   21800                 :   134949599 :   int insn_cost = 0;
   21801                 :             :   /* Add extra cost to avoid post_reload late_combine revert
   21802                 :             :      the optimization did in pass_rpad.  */
   21803                 :   134949599 :   if (reload_completed
   21804                 :     4188900 :       && ix86_rpad_gate ()
   21805                 :      261000 :       && recog_memoized (insn) >= 0
   21806                 :   135210449 :       && get_attr_avx_partial_xmm_update (insn)
   21807                 :             :       == AVX_PARTIAL_XMM_UPDATE_TRUE)
   21808                 :             :     insn_cost += COSTS_N_INSNS (3);
   21809                 :             : 
   21810                 :   134949599 :   return insn_cost + pattern_cost (PATTERN (insn), speed);
   21811                 :             : }
   21812                 :             : 
   21813                 :             : /* Compute a (partial) cost for rtx X.  Return true if the complete
   21814                 :             :    cost has been computed, and false if subexpressions should be
   21815                 :             :    scanned.  In either case, *TOTAL contains the cost result.  */
   21816                 :             : 
   21817                 :             : static bool
   21818                 :  7617465878 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
   21819                 :             :                 int *total, bool speed)
   21820                 :             : {
   21821                 :  7617465878 :   rtx mask;
   21822                 :  7617465878 :   enum rtx_code code = GET_CODE (x);
   21823                 :  7617465878 :   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   21824                 : 15234931756 :   const struct processor_costs *cost
   21825                 :  7617465878 :     = speed ? ix86_tune_cost : &ix86_size_cost;
   21826                 :  7617465878 :   int src_cost;
   21827                 :             : 
   21828                 :             :   /* Handling different vternlog variants.  */
   21829                 :  7617465878 :   if ((GET_MODE_SIZE (mode) == 64
   21830                 :    29939468 :        ? (TARGET_AVX512F && TARGET_EVEX512)
   21831                 :  6464026041 :        : (TARGET_AVX512VL
   21832                 :  6403045033 :           || (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)))
   21833                 :   183108207 :       && GET_MODE_SIZE (mode) >= 16
   21834                 :   125862463 :       && outer_code_i == SET
   21835                 :  7665914495 :       && ternlog_operand (x, mode))
   21836                 :             :     {
   21837                 :       32699 :       rtx args[3];
   21838                 :             : 
   21839                 :       32699 :       args[0] = NULL_RTX;
   21840                 :       32699 :       args[1] = NULL_RTX;
   21841                 :       32699 :       args[2] = NULL_RTX;
   21842                 :       32699 :       int idx = ix86_ternlog_idx (x, args);
   21843                 :       32699 :       gcc_assert (idx >= 0);
   21844                 :             : 
   21845                 :       32699 :       *total = cost->sse_op;
   21846                 :      130796 :       for (int i = 0; i != 3; i++)
   21847                 :       98097 :         if (args[i])
   21848                 :       69614 :           *total += rtx_cost (args[i], GET_MODE (args[i]), UNSPEC, i, speed);
   21849                 :       32699 :       return true;
   21850                 :             :     }
   21851                 :             : 
   21852                 :             : 
   21853                 :  7617433179 :   switch (code)
   21854                 :             :     {
   21855                 :    48553642 :     case SET:
   21856                 :    48553642 :       if (register_operand (SET_DEST (x), VOIDmode)
   21857                 :    48553642 :           && register_operand (SET_SRC (x), VOIDmode))
   21858                 :             :         {
   21859                 :    31018638 :           *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
   21860                 :    31018638 :           return true;
   21861                 :             :         }
   21862                 :             : 
   21863                 :    17535004 :       if (register_operand (SET_SRC (x), VOIDmode))
   21864                 :             :         /* Avoid potentially incorrect high cost from rtx_costs
   21865                 :             :            for non-tieable SUBREGs.  */
   21866                 :             :         src_cost = 0;
   21867                 :             :       else
   21868                 :             :         {
   21869                 :    15195249 :           src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
   21870                 :             : 
   21871                 :    15195249 :           if (CONSTANT_P (SET_SRC (x)))
   21872                 :             :             /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
   21873                 :             :                a small value, possibly zero for cheap constants.  */
   21874                 :     6719534 :             src_cost += COSTS_N_INSNS (1);
   21875                 :             :         }
   21876                 :             : 
   21877                 :    17535004 :       *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
   21878                 :    17535004 :       return true;
   21879                 :             : 
   21880                 :  2803948758 :     case CONST_INT:
   21881                 :  2803948758 :     case CONST:
   21882                 :  2803948758 :     case LABEL_REF:
   21883                 :  2803948758 :     case SYMBOL_REF:
   21884                 :  2803948758 :       if (x86_64_immediate_operand (x, VOIDmode))
   21885                 :  2214000309 :         *total = 0;
   21886                 :             :      else
   21887                 :             :         /* movabsq is slightly more expensive than a simple instruction. */
   21888                 :   589948449 :         *total = COSTS_N_INSNS (1) + 1;
   21889                 :             :       return true;
   21890                 :             : 
   21891                 :     7421943 :     case CONST_DOUBLE:
   21892                 :     7421943 :       if (IS_STACK_MODE (mode))
   21893                 :     1306441 :         switch (standard_80387_constant_p (x))
   21894                 :             :           {
   21895                 :             :           case -1:
   21896                 :             :           case 0:
   21897                 :             :             break;
   21898                 :      278482 :           case 1: /* 0.0 */
   21899                 :      278482 :             *total = 1;
   21900                 :      278482 :             return true;
   21901                 :      486059 :           default: /* Other constants */
   21902                 :      486059 :             *total = 2;
   21903                 :      486059 :             return true;
   21904                 :             :           }
   21905                 :             :       /* FALLTHRU */
   21906                 :             : 
   21907                 :    13214336 :     case CONST_VECTOR:
   21908                 :    13214336 :       switch (standard_sse_constant_p (x, mode))
   21909                 :             :         {
   21910                 :             :         case 0:
   21911                 :             :           break;
   21912                 :     3455558 :         case 1:  /* 0: xor eliminates false dependency */
   21913                 :     3455558 :           *total = 0;
   21914                 :     3455558 :           return true;
   21915                 :      146699 :         default: /* -1: cmp contains false dependency */
   21916                 :      146699 :           *total = 1;
   21917                 :      146699 :           return true;
   21918                 :             :         }
   21919                 :             :       /* FALLTHRU */
   21920                 :             : 
   21921                 :    10539459 :     case CONST_WIDE_INT:
   21922                 :             :       /* Fall back to (MEM (SYMBOL_REF)), since that's where
   21923                 :             :          it'll probably end up.  Add a penalty for size.  */
   21924                 :    21078918 :       *total = (COSTS_N_INSNS (1)
   21925                 :    20854314 :                 + (!TARGET_64BIT && flag_pic)
   21926                 :    21078918 :                 + (GET_MODE_SIZE (mode) <= 4
   21927                 :    18388694 :                    ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
   21928                 :    10539459 :       return true;
   21929                 :             : 
   21930                 :    21218073 :     case ZERO_EXTEND:
   21931                 :             :       /* The zero extensions is often completely free on x86_64, so make
   21932                 :             :          it as cheap as possible.  */
   21933                 :    21218073 :       if (TARGET_64BIT && mode == DImode
   21934                 :     3993312 :           && GET_MODE (XEXP (x, 0)) == SImode)
   21935                 :     2173332 :         *total = 1;
   21936                 :    19044741 :       else if (TARGET_ZERO_EXTEND_WITH_AND)
   21937                 :           0 :         *total = cost->add;
   21938                 :             :       else
   21939                 :    19044741 :         *total = cost->movzx;
   21940                 :             :       return false;
   21941                 :             : 
   21942                 :     2882092 :     case SIGN_EXTEND:
   21943                 :     2882092 :       *total = cost->movsx;
   21944                 :     2882092 :       return false;
   21945                 :             : 
   21946                 :   634116731 :     case ASHIFT:
   21947                 :   634116731 :       if (SCALAR_INT_MODE_P (mode)
   21948                 :   239969278 :           && GET_MODE_SIZE (mode) < UNITS_PER_WORD
   21949                 :   676065405 :           && CONST_INT_P (XEXP (x, 1)))
   21950                 :             :         {
   21951                 :    41789201 :           HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   21952                 :    41789201 :           if (value == 1)
   21953                 :             :             {
   21954                 :     2398498 :               *total = cost->add;
   21955                 :     2398498 :               return false;
   21956                 :             :             }
   21957                 :    39390703 :           if ((value == 2 || value == 3)
   21958                 :     4394065 :               && cost->lea <= cost->shift_const)
   21959                 :             :             {
   21960                 :     2091570 :               *total = cost->lea;
   21961                 :     2091570 :               return false;
   21962                 :             :             }
   21963                 :             :         }
   21964                 :             :       /* FALLTHRU */
   21965                 :             : 
   21966                 :   767823867 :     case ROTATE:
   21967                 :   767823867 :     case ASHIFTRT:
   21968                 :   767823867 :     case LSHIFTRT:
   21969                 :   767823867 :     case ROTATERT:
   21970                 :   767823867 :       bool skip_op0, skip_op1;
   21971                 :   767823867 :       *total = ix86_shift_rotate_cost (cost, code, mode,
   21972                 :   767823867 :                                        CONSTANT_P (XEXP (x, 1)),
   21973                 :             :                                        CONST_INT_P (XEXP (x, 1))
   21974                 :             :                                          ? INTVAL (XEXP (x, 1)) : -1,
   21975                 :             :                                        GET_CODE (XEXP (x, 1)) == AND,
   21976                 :   767823867 :                                        SUBREG_P (XEXP (x, 1))
   21977                 :   767823867 :                                        && GET_CODE (XEXP (XEXP (x, 1),
   21978                 :             :                                                           0)) == AND,
   21979                 :             :                                        &skip_op0, &skip_op1);
   21980                 :   767823867 :       if (skip_op0 || skip_op1)
   21981                 :             :         {
   21982                 :       22617 :           if (!skip_op0)
   21983                 :           0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   21984                 :       22617 :           if (!skip_op1)
   21985                 :           0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
   21986                 :       22617 :           return true;
   21987                 :             :         }
   21988                 :             :       return false;
   21989                 :             : 
   21990                 :      214244 :     case FMA:
   21991                 :      214244 :       {
   21992                 :      214244 :         rtx sub;
   21993                 :             : 
   21994                 :      214244 :         gcc_assert (FLOAT_MODE_P (mode));
   21995                 :      214244 :         gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
   21996                 :             : 
   21997                 :      428488 :         *total = ix86_vec_cost (mode,
   21998                 :      214244 :                                 GET_MODE_INNER (mode) == SFmode
   21999                 :             :                                 ? cost->fmass : cost->fmasd);
   22000                 :      214244 :         *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
   22001                 :             : 
   22002                 :             :         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
   22003                 :      214244 :         sub = XEXP (x, 0);
   22004                 :      214244 :         if (GET_CODE (sub) == NEG)
   22005                 :       54194 :           sub = XEXP (sub, 0);
   22006                 :      214244 :         *total += rtx_cost (sub, mode, FMA, 0, speed);
   22007                 :             : 
   22008                 :      214244 :         sub = XEXP (x, 2);
   22009                 :      214244 :         if (GET_CODE (sub) == NEG)
   22010                 :       40143 :           sub = XEXP (sub, 0);
   22011                 :      214244 :         *total += rtx_cost (sub, mode, FMA, 2, speed);
   22012                 :      214244 :         return true;
   22013                 :             :       }
   22014                 :             : 
   22015                 :  1752786461 :     case MULT:
   22016                 :  1752786461 :       if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
   22017                 :             :         {
   22018                 :   536881421 :           rtx op0 = XEXP (x, 0);
   22019                 :   536881421 :           rtx op1 = XEXP (x, 1);
   22020                 :   536881421 :           int nbits;
   22021                 :   536881421 :           if (CONST_INT_P (XEXP (x, 1)))
   22022                 :             :             {
   22023                 :   519758576 :               unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   22024                 :  1056121452 :               for (nbits = 0; value != 0; value &= value - 1)
   22025                 :   536362876 :                 nbits++;
   22026                 :             :             }
   22027                 :             :           else
   22028                 :             :             /* This is arbitrary.  */
   22029                 :             :             nbits = 7;
   22030                 :             : 
   22031                 :             :           /* Compute costs correctly for widening multiplication.  */
   22032                 :   536881421 :           if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
   22033                 :   542261861 :               && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
   22034                 :     5380440 :                  == GET_MODE_SIZE (mode))
   22035                 :             :             {
   22036                 :     5376334 :               int is_mulwiden = 0;
   22037                 :     5376334 :               machine_mode inner_mode = GET_MODE (op0);
   22038                 :             : 
   22039                 :     5376334 :               if (GET_CODE (op0) == GET_CODE (op1))
   22040                 :     5291069 :                 is_mulwiden = 1, op1 = XEXP (op1, 0);
   22041                 :       85265 :               else if (CONST_INT_P (op1))
   22042                 :             :                 {
   22043                 :       75194 :                   if (GET_CODE (op0) == SIGN_EXTEND)
   22044                 :       23383 :                     is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
   22045                 :       23383 :                                   == INTVAL (op1);
   22046                 :             :                   else
   22047                 :       51811 :                     is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
   22048                 :             :                 }
   22049                 :             : 
   22050                 :     5366263 :               if (is_mulwiden)
   22051                 :     5366236 :                 op0 = XEXP (op0, 0), mode = GET_MODE (op0);
   22052                 :             :             }
   22053                 :             : 
   22054                 :   536881421 :           int mult_init;
   22055                 :             :           // Double word multiplication requires 3 mults and 2 adds.
   22056                 :  1089165889 :           if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22057                 :             :             {
   22058                 :   323502518 :               mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
   22059                 :   323502518 :                           + 2 * cost->add;
   22060                 :   323502518 :               nbits *= 3;
   22061                 :             :             }
   22062                 :   367874646 :           else mult_init = cost->mult_init[MODE_INDEX (mode)];
   22063                 :             : 
   22064                 :  1073762842 :           *total = (mult_init
   22065                 :   536881421 :                     + nbits * cost->mult_bit
   22066                 :   536881421 :                     + rtx_cost (op0, mode, outer_code, opno, speed)
   22067                 :   536881421 :                     + rtx_cost (op1, mode, outer_code, opno, speed));
   22068                 :             : 
   22069                 :   536881421 :           return true;
   22070                 :             :         }
   22071                 :  1215905040 :       *total = ix86_multiplication_cost (cost, mode);
   22072                 :  1215905040 :       return false;
   22073                 :             : 
   22074                 :    72180532 :     case DIV:
   22075                 :    72180532 :     case UDIV:
   22076                 :    72180532 :     case MOD:
   22077                 :    72180532 :     case UMOD:
   22078                 :    72180532 :       *total = ix86_division_cost (cost, mode);
   22079                 :    72180532 :       return false;
   22080                 :             : 
   22081                 :   680450344 :     case PLUS:
   22082                 :   680450344 :       if (GET_MODE_CLASS (mode) == MODE_INT
   22083                 :   925555042 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   22084                 :             :         {
   22085                 :   134140669 :           if (GET_CODE (XEXP (x, 0)) == PLUS
   22086                 :     2686381 :               && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   22087                 :      802395 :               && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
   22088                 :      802390 :               && CONSTANT_P (XEXP (x, 1)))
   22089                 :             :             {
   22090                 :      802344 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
   22091                 :      802344 :               if (val == 2 || val == 4 || val == 8)
   22092                 :             :                 {
   22093                 :      802240 :                   *total = cost->lea;
   22094                 :      802240 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   22095                 :             :                                       outer_code, opno, speed);
   22096                 :      802240 :                   *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
   22097                 :             :                                       outer_code, opno, speed);
   22098                 :      802240 :                   *total += rtx_cost (XEXP (x, 1), mode,
   22099                 :             :                                       outer_code, opno, speed);
   22100                 :      802240 :                   return true;
   22101                 :             :                 }
   22102                 :             :             }
   22103                 :   133338325 :           else if (GET_CODE (XEXP (x, 0)) == MULT
   22104                 :    50972110 :                    && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   22105                 :             :             {
   22106                 :    50920554 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
   22107                 :    50920554 :               if (val == 2 || val == 4 || val == 8)
   22108                 :             :                 {
   22109                 :     7720539 :                   *total = cost->lea;
   22110                 :     7720539 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22111                 :             :                                       outer_code, opno, speed);
   22112                 :     7720539 :                   *total += rtx_cost (XEXP (x, 1), mode,
   22113                 :             :                                       outer_code, opno, speed);
   22114                 :     7720539 :                   return true;
   22115                 :             :                 }
   22116                 :             :             }
   22117                 :    82417771 :           else if (GET_CODE (XEXP (x, 0)) == PLUS)
   22118                 :             :             {
   22119                 :     1884037 :               rtx op = XEXP (XEXP (x, 0), 0);
   22120                 :             : 
   22121                 :             :               /* Add with carry, ignore the cost of adding a carry flag.  */
   22122                 :     1884037 :               if (ix86_carry_flag_operator (op, mode)
   22123                 :     1884037 :                   || ix86_carry_flag_unset_operator (op, mode))
   22124                 :       76333 :                 *total = cost->add;
   22125                 :             :               else
   22126                 :             :                 {
   22127                 :     1807704 :                   *total = cost->lea;
   22128                 :     1807704 :                   *total += rtx_cost (op, mode,
   22129                 :             :                                       outer_code, opno, speed);
   22130                 :             :                 }
   22131                 :             : 
   22132                 :     1884037 :               *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   22133                 :             :                                   outer_code, opno, speed);
   22134                 :     1884037 :               *total += rtx_cost (XEXP (x, 1), mode,
   22135                 :             :                                   outer_code, opno, speed);
   22136                 :     1884037 :               return true;
   22137                 :             :             }
   22138                 :             :         }
   22139                 :             :       /* FALLTHRU */
   22140                 :             : 
   22141                 :  1824798427 :     case MINUS:
   22142                 :             :       /* Subtract with borrow, ignore the cost of subtracting a carry flag.  */
   22143                 :  1824798427 :       if (GET_MODE_CLASS (mode) == MODE_INT
   22144                 :   502691272 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   22145                 :   224806879 :           && GET_CODE (XEXP (x, 0)) == MINUS
   22146                 :  1824839459 :           && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
   22147                 :       13002 :               || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
   22148                 :             :         {
   22149                 :       28030 :           *total = cost->add;
   22150                 :       28030 :           *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22151                 :             :                               outer_code, opno, speed);
   22152                 :       28030 :           *total += rtx_cost (XEXP (x, 1), mode,
   22153                 :             :                               outer_code, opno, speed);
   22154                 :       28030 :           return true;
   22155                 :             :         }
   22156                 :             : 
   22157                 :  1824770397 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22158                 :     2404152 :         *total = cost->addss;
   22159                 :  1822366245 :       else if (X87_FLOAT_MODE_P (mode))
   22160                 :      218449 :         *total = cost->fadd;
   22161                 :  1822147796 :       else if (FLOAT_MODE_P (mode))
   22162                 :      381854 :         *total = ix86_vec_cost (mode, cost->addss);
   22163                 :  1821765942 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22164                 :  1215509858 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22165                 :  1251398784 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22166                 :   322594075 :         *total = cost->add * 2;
   22167                 :             :       else
   22168                 :   283662009 :         *total = cost->add;
   22169                 :             :       return false;
   22170                 :             : 
   22171                 :     4205876 :     case IOR:
   22172                 :     4205876 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   22173                 :     3971794 :           || SSE_FLOAT_MODE_P (mode))
   22174                 :             :         {
   22175                 :             :           /* (ior (not ...) ...) can be a single insn in AVX512.  */
   22176                 :           0 :           if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
   22177                 :      244475 :               && ((TARGET_EVEX512
   22178                 :           0 :                    && GET_MODE_SIZE (mode) == 64)
   22179                 :           0 :                   || (TARGET_AVX512VL
   22180                 :           0 :                       && (GET_MODE_SIZE (mode) == 32
   22181                 :           0 :                           || GET_MODE_SIZE (mode) == 16))))
   22182                 :             :             {
   22183                 :           0 :               rtx right = GET_CODE (XEXP (x, 1)) != NOT
   22184                 :           0 :                           ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
   22185                 :             : 
   22186                 :           0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   22187                 :           0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22188                 :             :                                    outer_code, opno, speed)
   22189                 :           0 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   22190                 :           0 :               return true;
   22191                 :             :             }
   22192                 :      244475 :           *total = ix86_vec_cost (mode, cost->sse_op);
   22193                 :      244475 :         }
   22194                 :     3961401 :       else if (TARGET_64BIT
   22195                 :     3668323 :                && mode == TImode
   22196                 :     1719270 :                && GET_CODE (XEXP (x, 0)) == ASHIFT
   22197                 :      262724 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
   22198                 :      260738 :                && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
   22199                 :      260737 :                && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   22200                 :      260737 :                && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
   22201                 :      260737 :                && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
   22202                 :      238165 :                && GET_MODE (XEXP (XEXP (x, 1), 0)) == DImode)
   22203                 :             :         {
   22204                 :             :           /* *concatditi3 is cheap.  */
   22205                 :      238165 :           rtx op0 = XEXP (XEXP (XEXP (x, 0), 0), 0);
   22206                 :      238165 :           rtx op1 = XEXP (XEXP (x, 1), 0);
   22207                 :         344 :           *total = (SUBREG_P (op0) && GET_MODE (SUBREG_REG (op0)) == DFmode)
   22208                 :      238165 :                    ? COSTS_N_INSNS (1)    /* movq.  */
   22209                 :      237821 :                    : set_src_cost (op0, DImode, speed);
   22210                 :         570 :           *total += (SUBREG_P (op1) && GET_MODE (SUBREG_REG (op1)) == DFmode)
   22211                 :      238165 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   22212                 :      237607 :                     : set_src_cost (op1, DImode, speed);
   22213                 :      238165 :           return true;
   22214                 :             :         }
   22215                 :     3723236 :       else if (TARGET_64BIT
   22216                 :     3430158 :                && mode == TImode
   22217                 :     1481105 :                && GET_CODE (XEXP (x, 0)) == AND
   22218                 :     1435385 :                && REG_P (XEXP (XEXP (x, 0), 0))
   22219                 :     1430260 :                && CONST_WIDE_INT_P (XEXP (XEXP (x, 0), 1))
   22220                 :     1430260 :                && CONST_WIDE_INT_NUNITS (XEXP (XEXP (x, 0), 1)) == 2
   22221                 :     1430260 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 0) == -1
   22222                 :      986723 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 1) == 0
   22223                 :      986723 :                && GET_CODE (XEXP (x, 1)) == ASHIFT
   22224                 :      985142 :                && GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTEND
   22225                 :      985142 :                && GET_MODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == DImode
   22226                 :      985138 :                && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   22227                 :     4708374 :                && INTVAL (XEXP (XEXP (x, 1), 1)) == 64)
   22228                 :             :         {
   22229                 :             :           /* *insvti_highpart is cheap.  */
   22230                 :      985138 :           rtx op = XEXP (XEXP (XEXP (x, 1), 0), 0);
   22231                 :      985138 :           *total = COSTS_N_INSNS (1) + 1;
   22232                 :        1262 :           *total += (SUBREG_P (op) && GET_MODE (SUBREG_REG (op)) == DFmode)
   22233                 :      985138 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   22234                 :      984314 :                     : set_src_cost (op, DImode, speed);
   22235                 :      985138 :           return true;
   22236                 :             :         }
   22237                 :     5769274 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22238                 :      820040 :         *total = cost->add * 2;
   22239                 :             :       else
   22240                 :     1918058 :         *total = cost->add;
   22241                 :             :       return false;
   22242                 :             : 
   22243                 :      505558 :     case XOR:
   22244                 :      505558 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   22245                 :      426655 :           || SSE_FLOAT_MODE_P (mode))
   22246                 :       78903 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22247                 :      916659 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22248                 :       16389 :         *total = cost->add * 2;
   22249                 :             :       else
   22250                 :      410266 :         *total = cost->add;
   22251                 :             :       return false;
   22252                 :             : 
   22253                 :     6635508 :     case AND:
   22254                 :     6635508 :       if (address_no_seg_operand (x, mode))
   22255                 :             :         {
   22256                 :        9650 :           *total = cost->lea;
   22257                 :        9650 :           return true;
   22258                 :             :         }
   22259                 :     6625858 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   22260                 :     6282300 :                || SSE_FLOAT_MODE_P (mode))
   22261                 :             :         {
   22262                 :             :           /* pandn is a single instruction.  */
   22263                 :      378711 :           if (GET_CODE (XEXP (x, 0)) == NOT)
   22264                 :             :             {
   22265                 :       48597 :               rtx right = XEXP (x, 1);
   22266                 :             : 
   22267                 :             :               /* (and (not ...) (not ...)) can be a single insn in AVX512.  */
   22268                 :         372 :               if (GET_CODE (right) == NOT && TARGET_AVX512F
   22269                 :       48597 :                   && ((TARGET_EVEX512
   22270                 :           0 :                        && GET_MODE_SIZE (mode) == 64)
   22271                 :           0 :                       || (TARGET_AVX512VL
   22272                 :           0 :                           && (GET_MODE_SIZE (mode) == 32
   22273                 :           0 :                               || GET_MODE_SIZE (mode) == 16))))
   22274                 :           0 :                 right = XEXP (right, 0);
   22275                 :             : 
   22276                 :       48597 :               *total = ix86_vec_cost (mode, cost->sse_op)
   22277                 :       48597 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22278                 :             :                                    outer_code, opno, speed)
   22279                 :       48597 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   22280                 :       48597 :               return true;
   22281                 :             :             }
   22282                 :      330114 :           else if (GET_CODE (XEXP (x, 1)) == NOT)
   22283                 :             :             {
   22284                 :         746 :               *total = ix86_vec_cost (mode, cost->sse_op)
   22285                 :         746 :                        + rtx_cost (XEXP (x, 0), mode,
   22286                 :             :                                    outer_code, opno, speed)
   22287                 :         746 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   22288                 :             :                                    outer_code, opno, speed);
   22289                 :         746 :               return true;
   22290                 :             :             }
   22291                 :      329368 :           *total = ix86_vec_cost (mode, cost->sse_op);
   22292                 :      329368 :         }
   22293                 :    13172426 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22294                 :             :         {
   22295                 :      961102 :           if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   22296                 :             :             {
   22297                 :        1748 :               *total = cost->add * 2
   22298                 :         874 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22299                 :             :                                    outer_code, opno, speed)
   22300                 :         874 :                        + rtx_cost (XEXP (x, 1), mode,
   22301                 :             :                                    outer_code, opno, speed);
   22302                 :         874 :               return true;
   22303                 :             :             }
   22304                 :      960228 :           else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
   22305                 :             :             {
   22306                 :           0 :               *total = cost->add * 2
   22307                 :           0 :                        + rtx_cost (XEXP (x, 0), mode,
   22308                 :             :                                    outer_code, opno, speed)
   22309                 :           0 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   22310                 :             :                                    outer_code, opno, speed);
   22311                 :           0 :               return true;
   22312                 :             :             }
   22313                 :      960228 :           *total = cost->add * 2;
   22314                 :             :         }
   22315                 :     5286045 :       else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   22316                 :             :         {
   22317                 :         746 :           *total = cost->add
   22318                 :         373 :                    + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22319                 :             :                                outer_code, opno, speed)
   22320                 :         373 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   22321                 :         373 :           return true;
   22322                 :             :         }
   22323                 :     5285672 :       else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
   22324                 :             :         {
   22325                 :         112 :           *total = cost->add
   22326                 :          56 :                    + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   22327                 :          56 :                    + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   22328                 :             :                                outer_code, opno, speed);
   22329                 :          56 :           return true;
   22330                 :             :         }
   22331                 :             :       else
   22332                 :     5285616 :         *total = cost->add;
   22333                 :             :       return false;
   22334                 :             : 
   22335                 :      487574 :     case NOT:
   22336                 :      487574 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22337                 :             :         {
   22338                 :             :           /* (not (xor ...)) can be a single insn in AVX512.  */
   22339                 :           0 :           if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
   22340                 :        5914 :               && ((TARGET_EVEX512
   22341                 :           0 :                    && GET_MODE_SIZE (mode) == 64)
   22342                 :           0 :                   || (TARGET_AVX512VL
   22343                 :           0 :                       && (GET_MODE_SIZE (mode) == 32
   22344                 :           0 :                           || GET_MODE_SIZE (mode) == 16))))
   22345                 :             :             {
   22346                 :           0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   22347                 :           0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   22348                 :             :                                    outer_code, opno, speed)
   22349                 :           0 :                        + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   22350                 :             :                                    outer_code, opno, speed);
   22351                 :           0 :               return true;
   22352                 :             :             }
   22353                 :             : 
   22354                 :             :           // vnot is pxor -1.
   22355                 :        5914 :           *total = ix86_vec_cost (mode, cost->sse_op) + 1;
   22356                 :             :         }
   22357                 :     1110136 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22358                 :       66755 :         *total = cost->add * 2;
   22359                 :             :       else
   22360                 :      414905 :         *total = cost->add;
   22361                 :             :       return false;
   22362                 :             : 
   22363                 :    18129661 :     case NEG:
   22364                 :    18129661 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22365                 :       52246 :         *total = cost->sse_op;
   22366                 :    18077415 :       else if (X87_FLOAT_MODE_P (mode))
   22367                 :       15312 :         *total = cost->fchs;
   22368                 :    18062103 :       else if (FLOAT_MODE_P (mode))
   22369                 :       27395 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22370                 :    18034708 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22371                 :    13470361 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22372                 :     9274874 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22373                 :     1717413 :         *total = cost->add * 3;
   22374                 :             :       else
   22375                 :     2846934 :         *total = cost->add;
   22376                 :             :       return false;
   22377                 :             : 
   22378                 :    50584213 :     case COMPARE:
   22379                 :    50584213 :       rtx op0, op1;
   22380                 :    50584213 :       op0 = XEXP (x, 0);
   22381                 :    50584213 :       op1 = XEXP (x, 1);
   22382                 :    50584213 :       if (GET_CODE (op0) == ZERO_EXTRACT
   22383                 :      164765 :           && XEXP (op0, 1) == const1_rtx
   22384                 :      139274 :           && CONST_INT_P (XEXP (op0, 2))
   22385                 :      139172 :           && op1 == const0_rtx)
   22386                 :             :         {
   22387                 :             :           /* This kind of construct is implemented using test[bwl].
   22388                 :             :              Treat it as if we had an AND.  */
   22389                 :      139172 :           mode = GET_MODE (XEXP (op0, 0));
   22390                 :      278344 :           *total = (cost->add
   22391                 :      139172 :                     + rtx_cost (XEXP (op0, 0), mode, outer_code,
   22392                 :             :                                 opno, speed)
   22393                 :      139172 :                     + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
   22394                 :      139172 :           return true;
   22395                 :             :         }
   22396                 :             : 
   22397                 :    50445041 :       if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
   22398                 :             :         {
   22399                 :             :           /* This is an overflow detection, count it as a normal compare.  */
   22400                 :      136510 :           *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
   22401                 :      136510 :           return true;
   22402                 :             :         }
   22403                 :             : 
   22404                 :    50308531 :       rtx geu;
   22405                 :             :       /* Match x
   22406                 :             :          (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   22407                 :             :                       (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))  */
   22408                 :    50308531 :       if (mode == CCCmode
   22409                 :      351293 :           && GET_CODE (op0) == NEG
   22410                 :        7902 :           && GET_CODE (geu = XEXP (op0, 0)) == GEU
   22411                 :        7899 :           && REG_P (XEXP (geu, 0))
   22412                 :        7899 :           && (GET_MODE (XEXP (geu, 0)) == CCCmode
   22413                 :         747 :               || GET_MODE (XEXP (geu, 0)) == CCmode)
   22414                 :        7899 :           && REGNO (XEXP (geu, 0)) == FLAGS_REG
   22415                 :        7899 :           && XEXP (geu, 1) == const0_rtx
   22416                 :        7899 :           && GET_CODE (op1) == LTU
   22417                 :        7899 :           && REG_P (XEXP (op1, 0))
   22418                 :        7899 :           && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   22419                 :        7899 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   22420                 :    50316430 :           && XEXP (op1, 1) == const0_rtx)
   22421                 :             :         {
   22422                 :             :           /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop.  */
   22423                 :        7899 :           *total = 0;
   22424                 :        7899 :           return true;
   22425                 :             :         }
   22426                 :             :       /* Match x
   22427                 :             :          (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   22428                 :             :                       (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))  */
   22429                 :    50300632 :       if (mode == CCCmode
   22430                 :      343394 :           && GET_CODE (op0) == NEG
   22431                 :           3 :           && GET_CODE (XEXP (op0, 0)) == LTU
   22432                 :           3 :           && REG_P (XEXP (XEXP (op0, 0), 0))
   22433                 :           3 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   22434                 :           3 :           && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
   22435                 :           3 :           && XEXP (XEXP (op0, 0), 1) == const0_rtx
   22436                 :           3 :           && GET_CODE (op1) == GEU
   22437                 :           3 :           && REG_P (XEXP (op1, 0))
   22438                 :           3 :           && GET_MODE (XEXP (op1, 0)) == CCCmode
   22439                 :           3 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   22440                 :    50300635 :           && XEXP (op1, 1) == const0_rtx)
   22441                 :             :         {
   22442                 :             :           /* This is *x86_cmc.  */
   22443                 :           3 :           if (!speed)
   22444                 :           0 :             *total = COSTS_N_BYTES (1);
   22445                 :           3 :           else if (TARGET_SLOW_STC)
   22446                 :           0 :             *total = COSTS_N_INSNS (2);
   22447                 :             :           else
   22448                 :           3 :             *total = COSTS_N_INSNS (1);
   22449                 :           3 :           return true;
   22450                 :             :         }
   22451                 :             : 
   22452                 :    50300629 :       if (SCALAR_INT_MODE_P (GET_MODE (op0))
   22453                 :   105015658 :           && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
   22454                 :             :         {
   22455                 :      741324 :           if (op1 == const0_rtx)
   22456                 :      230622 :             *total = cost->add
   22457                 :      115311 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
   22458                 :             :           else
   22459                 :     1252026 :             *total = 3*cost->add
   22460                 :      626013 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
   22461                 :      626013 :                      + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
   22462                 :      741324 :           return true;
   22463                 :             :         }
   22464                 :             : 
   22465                 :             :       /* The embedded comparison operand is completely free.  */
   22466                 :    49559305 :       if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
   22467                 :      354949 :         *total = 0;
   22468                 :             : 
   22469                 :             :       return false;
   22470                 :             : 
   22471                 :     1346362 :     case FLOAT_EXTEND:
   22472                 :     1346362 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22473                 :      657858 :         *total = 0;
   22474                 :             :       else
   22475                 :      688504 :         *total = ix86_vec_cost (mode, cost->addss);
   22476                 :             :       return false;
   22477                 :             : 
   22478                 :       81383 :     case FLOAT_TRUNCATE:
   22479                 :       81383 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22480                 :       58750 :         *total = cost->fadd;
   22481                 :             :       else
   22482                 :       22633 :         *total = ix86_vec_cost (mode, cost->addss);
   22483                 :             :       return false;
   22484                 :             : 
   22485                 :      351986 :     case ABS:
   22486                 :             :       /* SSE requires memory load for the constant operand. It may make
   22487                 :             :          sense to account for this.  Of course the constant operand may or
   22488                 :             :          may not be reused. */
   22489                 :      351986 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22490                 :      247761 :         *total = cost->sse_op;
   22491                 :      104225 :       else if (X87_FLOAT_MODE_P (mode))
   22492                 :       33906 :         *total = cost->fabs;
   22493                 :       70319 :       else if (FLOAT_MODE_P (mode))
   22494                 :       28792 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22495                 :       41527 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22496                 :        5451 :         *total = cost->sse_op;
   22497                 :             :       return false;
   22498                 :             : 
   22499                 :       27708 :     case SQRT:
   22500                 :       27708 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22501                 :       18216 :         *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
   22502                 :        9492 :       else if (X87_FLOAT_MODE_P (mode))
   22503                 :        4227 :         *total = cost->fsqrt;
   22504                 :        5265 :       else if (FLOAT_MODE_P (mode))
   22505                 :        5265 :         *total = ix86_vec_cost (mode,
   22506                 :             :                                 mode == SFmode ? cost->sqrtss : cost->sqrtsd);
   22507                 :             :       return false;
   22508                 :             : 
   22509                 :     3786081 :     case UNSPEC:
   22510                 :     3786081 :       if (XINT (x, 1) == UNSPEC_TP)
   22511                 :      115323 :         *total = 0;
   22512                 :     3670758 :       else if (XINT (x, 1) == UNSPEC_VTERNLOG)
   22513                 :             :         {
   22514                 :        5288 :           *total = cost->sse_op;
   22515                 :        5288 :           *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
   22516                 :        5288 :           *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
   22517                 :        5288 :           *total += rtx_cost (XVECEXP (x, 0, 2), mode, code, 2, speed);
   22518                 :        5288 :           return true;
   22519                 :             :         }
   22520                 :     3665470 :       else if (XINT (x, 1) == UNSPEC_PTEST)
   22521                 :             :         {
   22522                 :       39309 :           *total = cost->sse_op;
   22523                 :       39309 :           rtx test_op0 = XVECEXP (x, 0, 0);
   22524                 :       39309 :           if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
   22525                 :             :             return false;
   22526                 :       38634 :           if (GET_CODE (test_op0) == AND)
   22527                 :             :             {
   22528                 :          23 :               rtx and_op0 = XEXP (test_op0, 0);
   22529                 :          23 :               if (GET_CODE (and_op0) == NOT)
   22530                 :           0 :                 and_op0 = XEXP (and_op0, 0);
   22531                 :          23 :               *total += rtx_cost (and_op0, GET_MODE (and_op0),
   22532                 :             :                                   AND, 0, speed)
   22533                 :          23 :                         + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
   22534                 :             :                                     AND, 1, speed);
   22535                 :             :             }
   22536                 :             :           else
   22537                 :       38611 :             *total = rtx_cost (test_op0, GET_MODE (test_op0),
   22538                 :             :                                UNSPEC, 0, speed);
   22539                 :       38634 :           return true;
   22540                 :             :         }
   22541                 :             :       return false;
   22542                 :             : 
   22543                 :     4435527 :     case VEC_SELECT:
   22544                 :     4435527 :     case VEC_CONCAT:
   22545                 :             :       /* ??? Assume all of these vector manipulation patterns are
   22546                 :             :          recognizable.  In which case they all pretty much have the
   22547                 :             :          same cost.  */
   22548                 :     4435527 :      *total = cost->sse_op;
   22549                 :     4435527 :      return true;
   22550                 :     1187730 :     case VEC_DUPLICATE:
   22551                 :     2375460 :       *total = rtx_cost (XEXP (x, 0),
   22552                 :     1187730 :                          GET_MODE (XEXP (x, 0)),
   22553                 :             :                          VEC_DUPLICATE, 0, speed);
   22554                 :             :       /* It's broadcast instruction, not embedded broadcasting.  */
   22555                 :     1187730 :       if (outer_code == SET)
   22556                 :     1187163 :         *total += cost->sse_op;
   22557                 :             : 
   22558                 :             :      return true;
   22559                 :             : 
   22560                 :      627997 :     case VEC_MERGE:
   22561                 :      627997 :       mask = XEXP (x, 2);
   22562                 :             :       /* This is masked instruction, assume the same cost,
   22563                 :             :          as nonmasked variant.  */
   22564                 :      627997 :       if (TARGET_AVX512F && register_operand (mask, GET_MODE (mask)))
   22565                 :      379255 :         *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed);
   22566                 :             :       else
   22567                 :      248742 :         *total = cost->sse_op;
   22568                 :             :       return true;
   22569                 :             : 
   22570                 :    99532463 :     case MEM:
   22571                 :             :       /* CONST_VECTOR_DUPLICATE_P in constant_pool is just broadcast.
   22572                 :             :          or variants in ix86_vector_duplicate_simode_const.  */
   22573                 :             : 
   22574                 :    99532463 :       if (GET_MODE_SIZE (mode) >= 16
   22575                 :    14919433 :           && VECTOR_MODE_P (mode)
   22576                 :     9179116 :           && SYMBOL_REF_P (XEXP (x, 0))
   22577                 :     1948543 :           && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))
   22578                 :   101295730 :           && ix86_broadcast_from_constant (mode, x))
   22579                 :             :         {
   22580                 :      320668 :           *total = COSTS_N_INSNS (2) + speed;
   22581                 :      320668 :           return true;
   22582                 :             :         }
   22583                 :             : 
   22584                 :             :       /* An insn that accesses memory is slightly more expensive
   22585                 :             :          than one that does not.  */
   22586                 :    99211795 :       if (speed)
   22587                 :             :         {
   22588                 :    88722691 :           *total += 1;
   22589                 :    88722691 :           rtx addr = XEXP (x, 0);
   22590                 :             :           /* For MEM, rtx_cost iterates each subrtx, and adds up the costs,
   22591                 :             :              so for MEM (reg) and MEM (reg + 4), the former costs 5,
   22592                 :             :              the latter costs 9, it is not accurate for x86. Ideally
   22593                 :             :              address_cost should be used, but it reduce cost too much.
   22594                 :             :              So current solution is make constant disp as cheap as possible.  */
   22595                 :    88722691 :           if (GET_CODE (addr) == PLUS
   22596                 :    58591186 :               && x86_64_immediate_operand (XEXP (addr, 1), Pmode)
   22597                 :             :               /* Only hanlde (reg + disp) since other forms of addr are mostly LEA,
   22598                 :             :                  there's no additional cost for the plus of disp.  */
   22599                 :   143165425 :               && register_operand (XEXP (addr, 0), Pmode))
   22600                 :             :             {
   22601                 :    52478620 :               *total += 1;
   22602                 :    52478620 :               *total += rtx_cost (XEXP (addr, 0), Pmode, PLUS, 0, speed);
   22603                 :    52478620 :               return true;
   22604                 :             :             }
   22605                 :             :         }
   22606                 :             : 
   22607                 :             :       return false;
   22608                 :             : 
   22609                 :       63211 :     case ZERO_EXTRACT:
   22610                 :       63211 :       if (XEXP (x, 1) == const1_rtx
   22611                 :       11912 :           && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
   22612                 :       11912 :           && GET_MODE (XEXP (x, 2)) == SImode
   22613                 :           0 :           && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
   22614                 :             :         {
   22615                 :             :           /* Ignore cost of zero extension and masking of last argument.  */
   22616                 :           0 :           *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22617                 :           0 :           *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22618                 :           0 :           *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
   22619                 :           0 :           return true;
   22620                 :             :         }
   22621                 :             :       return false;
   22622                 :             : 
   22623                 :    25509866 :     case IF_THEN_ELSE:
   22624                 :    25509866 :       if (TARGET_XOP
   22625                 :       17127 :           && VECTOR_MODE_P (mode)
   22626                 :    25515541 :           && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
   22627                 :             :         {
   22628                 :             :           /* vpcmov.  */
   22629                 :        4999 :           *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
   22630                 :        4999 :           if (!REG_P (XEXP (x, 0)))
   22631                 :        4810 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22632                 :        4999 :           if (!REG_P (XEXP (x, 1)))
   22633                 :        4778 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22634                 :        4999 :           if (!REG_P (XEXP (x, 2)))
   22635                 :        4778 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   22636                 :        4999 :           return true;
   22637                 :             :         }
   22638                 :           0 :       else if (TARGET_CMOVE
   22639                 :    25504867 :                && SCALAR_INT_MODE_P (mode)
   22640                 :    27865370 :                && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   22641                 :             :         {
   22642                 :             :           /* cmov.  */
   22643                 :     2177728 :           *total = COSTS_N_INSNS (1);
   22644                 :     2177728 :           if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
   22645                 :           0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22646                 :     2177728 :           if (!REG_P (XEXP (x, 1)))
   22647                 :      118415 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22648                 :     2177728 :           if (!REG_P (XEXP (x, 2)))
   22649                 :      658612 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   22650                 :     2177728 :           return true;
   22651                 :             :         }
   22652                 :             :       return false;
   22653                 :             : 
   22654                 :             :     default:
   22655                 :             :       return false;
   22656                 :             :     }
   22657                 :             : }
   22658                 :             : 
   22659                 :             : #if TARGET_MACHO
   22660                 :             : 
   22661                 :             : static int current_machopic_label_num;
   22662                 :             : 
   22663                 :             : /* Given a symbol name and its associated stub, write out the
   22664                 :             :    definition of the stub.  */
   22665                 :             : 
   22666                 :             : void
   22667                 :             : machopic_output_stub (FILE *file, const char *symb, const char *stub)
   22668                 :             : {
   22669                 :             :   unsigned int length;
   22670                 :             :   char *binder_name, *symbol_name, lazy_ptr_name[32];
   22671                 :             :   int label = ++current_machopic_label_num;
   22672                 :             : 
   22673                 :             :   /* For 64-bit we shouldn't get here.  */
   22674                 :             :   gcc_assert (!TARGET_64BIT);
   22675                 :             : 
   22676                 :             :   /* Lose our funky encoding stuff so it doesn't contaminate the stub.  */
   22677                 :             :   symb = targetm.strip_name_encoding (symb);
   22678                 :             : 
   22679                 :             :   length = strlen (stub);
   22680                 :             :   binder_name = XALLOCAVEC (char, length + 32);
   22681                 :             :   GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
   22682                 :             : 
   22683                 :             :   length = strlen (symb);
   22684                 :             :   symbol_name = XALLOCAVEC (char, length + 32);
   22685                 :             :   GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
   22686                 :             : 
   22687                 :             :   sprintf (lazy_ptr_name, "L%d$lz", label);
   22688                 :             : 
   22689                 :             :   if (MACHOPIC_ATT_STUB)
   22690                 :             :     switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
   22691                 :             :   else if (MACHOPIC_PURE)
   22692                 :             :     switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
   22693                 :             :   else
   22694                 :             :     switch_to_section (darwin_sections[machopic_symbol_stub_section]);
   22695                 :             : 
   22696                 :             :   fprintf (file, "%s:\n", stub);
   22697                 :             :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   22698                 :             : 
   22699                 :             :   if (MACHOPIC_ATT_STUB)
   22700                 :             :     {
   22701                 :             :       fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
   22702                 :             :     }
   22703                 :             :   else if (MACHOPIC_PURE)
   22704                 :             :     {
   22705                 :             :       /* PIC stub.  */
   22706                 :             :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   22707                 :             :       rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
   22708                 :             :       output_set_got (tmp, NULL_RTX);   /* "CALL ___<cpu>.get_pc_thunk.cx".  */
   22709                 :             :       fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
   22710                 :             :                label, lazy_ptr_name, label);
   22711                 :             :       fprintf (file, "\tjmp\t*%%ecx\n");
   22712                 :             :     }
   22713                 :             :   else
   22714                 :             :     fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
   22715                 :             : 
   22716                 :             :   /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
   22717                 :             :      it needs no stub-binding-helper.  */
   22718                 :             :   if (MACHOPIC_ATT_STUB)
   22719                 :             :     return;
   22720                 :             : 
   22721                 :             :   fprintf (file, "%s:\n", binder_name);
   22722                 :             : 
   22723                 :             :   if (MACHOPIC_PURE)
   22724                 :             :     {
   22725                 :             :       fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
   22726                 :             :       fprintf (file, "\tpushl\t%%ecx\n");
   22727                 :             :     }
   22728                 :             :   else
   22729                 :             :     fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
   22730                 :             : 
   22731                 :             :   fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
   22732                 :             : 
   22733                 :             :   /* N.B. Keep the correspondence of these
   22734                 :             :      'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
   22735                 :             :      old-pic/new-pic/non-pic stubs; altering this will break
   22736                 :             :      compatibility with existing dylibs.  */
   22737                 :             :   if (MACHOPIC_PURE)
   22738                 :             :     {
   22739                 :             :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   22740                 :             :       switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
   22741                 :             :     }
   22742                 :             :   else
   22743                 :             :     /* 16-byte -mdynamic-no-pic stub.  */
   22744                 :             :     switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
   22745                 :             : 
   22746                 :             :   fprintf (file, "%s:\n", lazy_ptr_name);
   22747                 :             :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   22748                 :             :   fprintf (file, ASM_LONG "%s\n", binder_name);
   22749                 :             : }
   22750                 :             : #endif /* TARGET_MACHO */
   22751                 :             : 
   22752                 :             : /* Order the registers for register allocator.  */
   22753                 :             : 
   22754                 :             : void
   22755                 :      211370 : x86_order_regs_for_local_alloc (void)
   22756                 :             : {
   22757                 :      211370 :    int pos = 0;
   22758                 :      211370 :    int i;
   22759                 :             : 
   22760                 :             :    /* First allocate the local general purpose registers.  */
   22761                 :    19657410 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22762                 :    26209880 :      if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i))
   22763                 :     5505021 :         reg_alloc_order [pos++] = i;
   22764                 :             : 
   22765                 :             :    /* Global general purpose registers.  */
   22766                 :    19657410 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22767                 :    22572970 :      if (GENERAL_REGNO_P (i) && !call_used_or_fixed_reg_p (i))
   22768                 :     1258819 :         reg_alloc_order [pos++] = i;
   22769                 :             : 
   22770                 :             :    /* x87 registers come first in case we are doing FP math
   22771                 :             :       using them.  */
   22772                 :      211370 :    if (!TARGET_SSE_MATH)
   22773                 :       56538 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   22774                 :       50256 :        reg_alloc_order [pos++] = i;
   22775                 :             : 
   22776                 :             :    /* SSE registers.  */
   22777                 :     1902330 :    for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
   22778                 :     1690960 :      reg_alloc_order [pos++] = i;
   22779                 :     1902330 :    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
   22780                 :     1690960 :      reg_alloc_order [pos++] = i;
   22781                 :             : 
   22782                 :             :    /* Extended REX SSE registers.  */
   22783                 :     3593290 :    for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
   22784                 :     3381920 :      reg_alloc_order [pos++] = i;
   22785                 :             : 
   22786                 :             :    /* Mask register.  */
   22787                 :     1902330 :    for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
   22788                 :     1690960 :      reg_alloc_order [pos++] = i;
   22789                 :             : 
   22790                 :             :    /* x87 registers.  */
   22791                 :      211370 :    if (TARGET_SSE_MATH)
   22792                 :     1845792 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   22793                 :     1640704 :        reg_alloc_order [pos++] = i;
   22794                 :             : 
   22795                 :     1902330 :    for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
   22796                 :     1690960 :      reg_alloc_order [pos++] = i;
   22797                 :             : 
   22798                 :             :    /* Initialize the rest of array as we do not allocate some registers
   22799                 :             :       at all.  */
   22800                 :     1056850 :    while (pos < FIRST_PSEUDO_REGISTER)
   22801                 :      845480 :      reg_alloc_order [pos++] = 0;
   22802                 :      211370 : }
   22803                 :             : 
   22804                 :             : static bool
   22805                 :   198945554 : ix86_ms_bitfield_layout_p (const_tree record_type)
   22806                 :             : {
   22807                 :   198945554 :   return ((TARGET_MS_BITFIELD_LAYOUT
   22808                 :         215 :            && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
   22809                 :   198945554 :           || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
   22810                 :             : }
   22811                 :             : 
   22812                 :             : /* Returns an expression indicating where the this parameter is
   22813                 :             :    located on entry to the FUNCTION.  */
   22814                 :             : 
   22815                 :             : static rtx
   22816                 :        1752 : x86_this_parameter (tree function)
   22817                 :             : {
   22818                 :        1752 :   tree type = TREE_TYPE (function);
   22819                 :        1752 :   bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
   22820                 :        1752 :   int nregs;
   22821                 :             : 
   22822                 :        1752 :   if (TARGET_64BIT)
   22823                 :             :     {
   22824                 :        1750 :       const int *parm_regs;
   22825                 :             : 
   22826                 :        1750 :       if (ix86_function_type_abi (type) == MS_ABI)
   22827                 :             :         parm_regs = x86_64_ms_abi_int_parameter_registers;
   22828                 :             :       else
   22829                 :        1750 :         parm_regs = x86_64_int_parameter_registers;
   22830                 :        1750 :       return gen_rtx_REG (Pmode, parm_regs[aggr]);
   22831                 :             :     }
   22832                 :             : 
   22833                 :           2 :   nregs = ix86_function_regparm (type, function);
   22834                 :             : 
   22835                 :           2 :   if (nregs > 0 && !stdarg_p (type))
   22836                 :             :     {
   22837                 :           0 :       int regno;
   22838                 :           0 :       unsigned int ccvt = ix86_get_callcvt (type);
   22839                 :             : 
   22840                 :           0 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   22841                 :           0 :         regno = aggr ? DX_REG : CX_REG;
   22842                 :           0 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   22843                 :             :         {
   22844                 :           0 :           regno = CX_REG;
   22845                 :           0 :           if (aggr)
   22846                 :           0 :             return gen_rtx_MEM (SImode,
   22847                 :           0 :                                 plus_constant (Pmode, stack_pointer_rtx, 4));
   22848                 :             :         }
   22849                 :             :       else
   22850                 :             :         {
   22851                 :           0 :           regno = AX_REG;
   22852                 :           0 :           if (aggr)
   22853                 :             :             {
   22854                 :           0 :               regno = DX_REG;
   22855                 :           0 :               if (nregs == 1)
   22856                 :           0 :                 return gen_rtx_MEM (SImode,
   22857                 :           0 :                                     plus_constant (Pmode,
   22858                 :           0 :                                                    stack_pointer_rtx, 4));
   22859                 :             :             }
   22860                 :             :         }
   22861                 :           0 :       return gen_rtx_REG (SImode, regno);
   22862                 :             :     }
   22863                 :             : 
   22864                 :           2 :   return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
   22865                 :           4 :                                              aggr ? 8 : 4));
   22866                 :             : }
   22867                 :             : 
   22868                 :             : /* Determine whether x86_output_mi_thunk can succeed.  */
   22869                 :             : 
   22870                 :             : static bool
   22871                 :        4892 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   22872                 :             :                          const_tree function)
   22873                 :             : {
   22874                 :             :   /* 64-bit can handle anything.  */
   22875                 :        4892 :   if (TARGET_64BIT)
   22876                 :             :     return true;
   22877                 :             : 
   22878                 :             :   /* For 32-bit, everything's fine if we have one free register.  */
   22879                 :          76 :   if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
   22880                 :             :     return true;
   22881                 :             : 
   22882                 :             :   /* Need a free register for vcall_offset.  */
   22883                 :           0 :   if (vcall_offset)
   22884                 :             :     return false;
   22885                 :             : 
   22886                 :             :   /* Need a free register for GOT references.  */
   22887                 :           0 :   if (flag_pic && !targetm.binds_local_p (function))
   22888                 :             :     return false;
   22889                 :             : 
   22890                 :             :   /* Otherwise ok.  */
   22891                 :             :   return true;
   22892                 :             : }
   22893                 :             : 
   22894                 :             : /* Output the assembler code for a thunk function.  THUNK_DECL is the
   22895                 :             :    declaration for the thunk function itself, FUNCTION is the decl for
   22896                 :             :    the target function.  DELTA is an immediate constant offset to be
   22897                 :             :    added to THIS.  If VCALL_OFFSET is nonzero, the word at
   22898                 :             :    *(*this + vcall_offset) should be added to THIS.  */
   22899                 :             : 
   22900                 :             : static void
   22901                 :        1752 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
   22902                 :             :                      HOST_WIDE_INT vcall_offset, tree function)
   22903                 :             : {
   22904                 :        1752 :   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   22905                 :        1752 :   rtx this_param = x86_this_parameter (function);
   22906                 :        1752 :   rtx this_reg, tmp, fnaddr;
   22907                 :        1752 :   unsigned int tmp_regno;
   22908                 :        1752 :   rtx_insn *insn;
   22909                 :        1752 :   int saved_flag_force_indirect_call = flag_force_indirect_call;
   22910                 :             : 
   22911                 :        1752 :   if (TARGET_64BIT)
   22912                 :             :     tmp_regno = R10_REG;
   22913                 :             :   else
   22914                 :             :     {
   22915                 :           2 :       unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
   22916                 :           2 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   22917                 :             :         tmp_regno = AX_REG;
   22918                 :           2 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   22919                 :             :         tmp_regno = DX_REG;
   22920                 :             :       else
   22921                 :           2 :         tmp_regno = CX_REG;
   22922                 :             : 
   22923                 :           2 :       if (flag_pic)
   22924                 :           2 :   flag_force_indirect_call = 0;
   22925                 :             :     }
   22926                 :             : 
   22927                 :        1752 :   emit_note (NOTE_INSN_PROLOGUE_END);
   22928                 :             : 
   22929                 :             :   /* CET is enabled, insert EB instruction.  */
   22930                 :        1752 :   if ((flag_cf_protection & CF_BRANCH))
   22931                 :          20 :     emit_insn (gen_nop_endbr ());
   22932                 :             : 
   22933                 :             :   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
   22934                 :             :      pull it in now and let DELTA benefit.  */
   22935                 :        1752 :   if (REG_P (this_param))
   22936                 :             :     this_reg = this_param;
   22937                 :           2 :   else if (vcall_offset)
   22938                 :             :     {
   22939                 :             :       /* Put the this parameter into %eax.  */
   22940                 :           1 :       this_reg = gen_rtx_REG (Pmode, AX_REG);
   22941                 :           1 :       emit_move_insn (this_reg, this_param);
   22942                 :             :     }
   22943                 :             :   else
   22944                 :             :     this_reg = NULL_RTX;
   22945                 :             : 
   22946                 :             :   /* Adjust the this parameter by a fixed constant.  */
   22947                 :        1752 :   if (delta)
   22948                 :             :     {
   22949                 :         824 :       rtx delta_rtx = GEN_INT (delta);
   22950                 :         824 :       rtx delta_dst = this_reg ? this_reg : this_param;
   22951                 :             : 
   22952                 :         824 :       if (TARGET_64BIT)
   22953                 :             :         {
   22954                 :         823 :           if (!x86_64_general_operand (delta_rtx, Pmode))
   22955                 :             :             {
   22956                 :           0 :               tmp = gen_rtx_REG (Pmode, tmp_regno);
   22957                 :           0 :               emit_move_insn (tmp, delta_rtx);
   22958                 :           0 :               delta_rtx = tmp;
   22959                 :             :             }
   22960                 :             :         }
   22961                 :             : 
   22962                 :         824 :       ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
   22963                 :             :     }
   22964                 :             : 
   22965                 :             :   /* Adjust the this parameter by a value stored in the vtable.  */
   22966                 :        1752 :   if (vcall_offset)
   22967                 :             :     {
   22968                 :         979 :       rtx vcall_addr, vcall_mem, this_mem;
   22969                 :             : 
   22970                 :         979 :       tmp = gen_rtx_REG (Pmode, tmp_regno);
   22971                 :             : 
   22972                 :         979 :       this_mem = gen_rtx_MEM (ptr_mode, this_reg);
   22973                 :         979 :       if (Pmode != ptr_mode)
   22974                 :           0 :         this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
   22975                 :         979 :       emit_move_insn (tmp, this_mem);
   22976                 :             : 
   22977                 :             :       /* Adjust the this parameter.  */
   22978                 :         979 :       vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
   22979                 :         979 :       if (TARGET_64BIT
   22980                 :         979 :           && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
   22981                 :             :         {
   22982                 :           0 :           rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
   22983                 :           0 :           emit_move_insn (tmp2, GEN_INT (vcall_offset));
   22984                 :           0 :           vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
   22985                 :             :         }
   22986                 :             : 
   22987                 :         979 :       vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
   22988                 :         979 :       if (Pmode != ptr_mode)
   22989                 :           0 :         emit_insn (gen_addsi_1_zext (this_reg,
   22990                 :             :                                      gen_rtx_REG (ptr_mode,
   22991                 :             :                                                   REGNO (this_reg)),
   22992                 :             :                                      vcall_mem));
   22993                 :             :       else
   22994                 :         979 :         ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
   22995                 :             :     }
   22996                 :             : 
   22997                 :             :   /* If necessary, drop THIS back to its stack slot.  */
   22998                 :        1752 :   if (this_reg && this_reg != this_param)
   22999                 :           1 :     emit_move_insn (this_param, this_reg);
   23000                 :             : 
   23001                 :        1752 :   fnaddr = XEXP (DECL_RTL (function), 0);
   23002                 :        1752 :   if (TARGET_64BIT)
   23003                 :             :     {
   23004                 :          25 :       if (!flag_pic || targetm.binds_local_p (function)
   23005                 :        1775 :           || TARGET_PECOFF)
   23006                 :             :         ;
   23007                 :             :       else
   23008                 :             :         {
   23009                 :           0 :           tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
   23010                 :           0 :           tmp = gen_rtx_CONST (Pmode, tmp);
   23011                 :           0 :           fnaddr = gen_const_mem (Pmode, tmp);
   23012                 :             :         }
   23013                 :             :     }
   23014                 :             :   else
   23015                 :             :     {
   23016                 :           2 :       if (!flag_pic || targetm.binds_local_p (function))
   23017                 :             :         ;
   23018                 :             : #if TARGET_MACHO
   23019                 :             :       else if (TARGET_MACHO)
   23020                 :             :         {
   23021                 :             :           fnaddr = machopic_indirect_call_target (DECL_RTL (function));
   23022                 :             :           fnaddr = XEXP (fnaddr, 0);
   23023                 :             :         }
   23024                 :             : #endif /* TARGET_MACHO */
   23025                 :             :       else
   23026                 :             :         {
   23027                 :           0 :           tmp = gen_rtx_REG (Pmode, CX_REG);
   23028                 :           0 :           output_set_got (tmp, NULL_RTX);
   23029                 :             : 
   23030                 :           0 :           fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
   23031                 :           0 :           fnaddr = gen_rtx_CONST (Pmode, fnaddr);
   23032                 :           0 :           fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
   23033                 :           0 :           fnaddr = gen_const_mem (Pmode, fnaddr);
   23034                 :             :         }
   23035                 :             :     }
   23036                 :             : 
   23037                 :             :   /* Our sibling call patterns do not allow memories, because we have no
   23038                 :             :      predicate that can distinguish between frame and non-frame memory.
   23039                 :             :      For our purposes here, we can get away with (ab)using a jump pattern,
   23040                 :             :      because we're going to do no optimization.  */
   23041                 :        1752 :   if (MEM_P (fnaddr))
   23042                 :             :     {
   23043                 :           0 :       if (sibcall_insn_operand (fnaddr, word_mode))
   23044                 :             :         {
   23045                 :           0 :           fnaddr = XEXP (DECL_RTL (function), 0);
   23046                 :           0 :           tmp = gen_rtx_MEM (QImode, fnaddr);
   23047                 :           0 :           tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   23048                 :           0 :           tmp = emit_call_insn (tmp);
   23049                 :           0 :           SIBLING_CALL_P (tmp) = 1;
   23050                 :             :         }
   23051                 :             :       else
   23052                 :           0 :         emit_jump_insn (gen_indirect_jump (fnaddr));
   23053                 :             :     }
   23054                 :             :   else
   23055                 :             :     {
   23056                 :        1752 :       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
   23057                 :             :         {
   23058                 :             :           // CM_LARGE_PIC always uses pseudo PIC register which is
   23059                 :             :           // uninitialized.  Since FUNCTION is local and calling it
   23060                 :             :           // doesn't go through PLT, we use scratch register %r11 as
   23061                 :             :           // PIC register and initialize it here.
   23062                 :           3 :           pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
   23063                 :           3 :           ix86_init_large_pic_reg (tmp_regno);
   23064                 :           3 :           fnaddr = legitimize_pic_address (fnaddr,
   23065                 :           3 :                                            gen_rtx_REG (Pmode, tmp_regno));
   23066                 :             :         }
   23067                 :             : 
   23068                 :        1752 :       if (!sibcall_insn_operand (fnaddr, word_mode))
   23069                 :             :         {
   23070                 :           9 :           tmp = gen_rtx_REG (word_mode, tmp_regno);
   23071                 :           9 :           if (GET_MODE (fnaddr) != word_mode)
   23072                 :           0 :             fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
   23073                 :           9 :           emit_move_insn (tmp, fnaddr);
   23074                 :           9 :           fnaddr = tmp;
   23075                 :             :         }
   23076                 :             : 
   23077                 :        1752 :       tmp = gen_rtx_MEM (QImode, fnaddr);
   23078                 :        1752 :       tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   23079                 :        1752 :       tmp = emit_call_insn (tmp);
   23080                 :        1752 :       SIBLING_CALL_P (tmp) = 1;
   23081                 :             :     }
   23082                 :        1752 :   emit_barrier ();
   23083                 :             : 
   23084                 :             :   /* Emit just enough of rest_of_compilation to get the insns emitted.  */
   23085                 :        1752 :   insn = get_insns ();
   23086                 :        1752 :   shorten_branches (insn);
   23087                 :        1752 :   assemble_start_function (thunk_fndecl, fnname);
   23088                 :        1752 :   final_start_function (insn, file, 1);
   23089                 :        1752 :   final (insn, file, 1);
   23090                 :        1752 :   final_end_function ();
   23091                 :        1752 :   assemble_end_function (thunk_fndecl, fnname);
   23092                 :             : 
   23093                 :        1752 :   flag_force_indirect_call = saved_flag_force_indirect_call;
   23094                 :        1752 : }
   23095                 :             : 
   23096                 :             : static void
   23097                 :      267725 : x86_file_start (void)
   23098                 :             : {
   23099                 :      267725 :   default_file_start ();
   23100                 :      267725 :   if (TARGET_16BIT)
   23101                 :           5 :     fputs ("\t.code16gcc\n", asm_out_file);
   23102                 :             : #if TARGET_MACHO
   23103                 :             :   darwin_file_start ();
   23104                 :             : #endif
   23105                 :      267725 :   if (X86_FILE_START_VERSION_DIRECTIVE)
   23106                 :             :     fputs ("\t.version\t\"01.01\"\n", asm_out_file);
   23107                 :      267725 :   if (X86_FILE_START_FLTUSED)
   23108                 :             :     fputs ("\t.global\t__fltused\n", asm_out_file);
   23109                 :      267725 :   if (ix86_asm_dialect == ASM_INTEL)
   23110                 :          57 :     fputs ("\t.intel_syntax noprefix\n", asm_out_file);
   23111                 :      267725 : }
   23112                 :             : 
   23113                 :             : int
   23114                 :    85635601 : x86_field_alignment (tree type, int computed)
   23115                 :             : {
   23116                 :    85635601 :   machine_mode mode;
   23117                 :             : 
   23118                 :    85635601 :   if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
   23119                 :             :     return computed;
   23120                 :     8695949 :   if (TARGET_IAMCU)
   23121                 :           0 :     return iamcu_alignment (type, computed);
   23122                 :     8695949 :   type = strip_array_types (type);
   23123                 :     8695949 :   mode = TYPE_MODE (type);
   23124                 :     8695949 :   if (mode == DFmode || mode == DCmode
   23125                 :     8590110 :       || GET_MODE_CLASS (mode) == MODE_INT
   23126                 :     2939390 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
   23127                 :             :     {
   23128                 :     5756559 :       if (TYPE_ATOMIC (type) && computed > 32)
   23129                 :             :         {
   23130                 :           0 :           static bool warned;
   23131                 :             : 
   23132                 :           0 :           if (!warned && warn_psabi)
   23133                 :             :             {
   23134                 :           0 :               const char *url
   23135                 :             :                 = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
   23136                 :             : 
   23137                 :           0 :               warned = true;
   23138                 :           0 :               inform (input_location, "the alignment of %<_Atomic %T%> "
   23139                 :             :                                       "fields changed in %{GCC 11.1%}",
   23140                 :           0 :                       TYPE_MAIN_VARIANT (type), url);
   23141                 :             :             }
   23142                 :             :         }
   23143                 :             :       else
   23144                 :     5756559 :       return MIN (32, computed);
   23145                 :             :     }
   23146                 :             :   return computed;
   23147                 :             : }
   23148                 :             : 
   23149                 :             : /* Print call to TARGET to FILE.  */
   23150                 :             : 
   23151                 :             : static void
   23152                 :         334 : x86_print_call_or_nop (FILE *file, const char *target)
   23153                 :             : {
   23154                 :         334 :   if (flag_nop_mcount || !strcmp (target, "nop"))
   23155                 :             :     /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
   23156                 :           5 :     fprintf (file, "1:" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   23157                 :             :   else
   23158                 :         329 :     fprintf (file, "1:\tcall\t%s\n", target);
   23159                 :         334 : }
   23160                 :             : 
   23161                 :             : static bool
   23162                 :         348 : current_fentry_name (const char **name)
   23163                 :             : {
   23164                 :         348 :   tree attr = lookup_attribute ("fentry_name",
   23165                 :         348 :                                 DECL_ATTRIBUTES (current_function_decl));
   23166                 :         348 :   if (!attr)
   23167                 :             :     return false;
   23168                 :           2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   23169                 :           2 :   return true;
   23170                 :             : }
   23171                 :             : 
   23172                 :             : static bool
   23173                 :          10 : current_fentry_section (const char **name)
   23174                 :             : {
   23175                 :          10 :   tree attr = lookup_attribute ("fentry_section",
   23176                 :          10 :                                 DECL_ATTRIBUTES (current_function_decl));
   23177                 :          10 :   if (!attr)
   23178                 :             :     return false;
   23179                 :           2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   23180                 :           2 :   return true;
   23181                 :             : }
   23182                 :             : 
   23183                 :             : /* Return a caller-saved register which isn't live or a callee-saved
   23184                 :             :    register which has been saved on stack in the prologue at entry for
   23185                 :             :    profile.  */
   23186                 :             : 
   23187                 :             : static int
   23188                 :          13 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
   23189                 :             : {
   23190                 :             :   /* Use %r10 if the profiler is emitted before the prologue or it isn't
   23191                 :             :      used by DRAP.  */
   23192                 :          13 :   if (ix86_profile_before_prologue ()
   23193                 :           9 :       || !crtl->drap_reg
   23194                 :          16 :       || REGNO (crtl->drap_reg) != R10_REG)
   23195                 :             :     return R10_REG;
   23196                 :             : 
   23197                 :             :   /* The profiler is emitted after the prologue.  If there is a
   23198                 :             :      caller-saved register which isn't live or a callee-saved
   23199                 :             :      register saved on stack in the prologue, use it.  */
   23200                 :             : 
   23201                 :           3 :   bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
   23202                 :             : 
   23203                 :           3 :   int i;
   23204                 :          88 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   23205                 :          56 :     if (GENERAL_REGNO_P (i)
   23206                 :          29 :         && i != R10_REG
   23207                 :             : #ifdef NO_PROFILE_COUNTERS
   23208                 :          27 :         && (r11_ok || i != R11_REG)
   23209                 :             : #else
   23210                 :             :         && i != R11_REG
   23211                 :             : #endif
   23212                 :          26 :         && TEST_HARD_REG_BIT (accessible_reg_set, i)
   23213                 :         111 :         && (ix86_save_reg (i, true, true)
   23214                 :          25 :             || (call_used_regs[i]
   23215                 :          18 :                 && !fixed_regs[i]
   23216                 :          16 :                 && !REGNO_REG_SET_P (reg_live, i))))
   23217                 :           3 :       return i;
   23218                 :             : 
   23219                 :           0 :   sorry ("no register available for profiling %<-mcmodel=large%s%>",
   23220                 :           0 :          ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
   23221                 :             : 
   23222                 :           0 :   return R10_REG;
   23223                 :             : }
   23224                 :             : 
   23225                 :             : /* Output assembler code to FILE to increment profiler label # LABELNO
   23226                 :             :    for profiling a function entry.  */
   23227                 :             : void
   23228                 :         348 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   23229                 :             : {
   23230                 :         348 :   if (cfun->machine->insn_queued_at_entrance)
   23231                 :             :     {
   23232                 :           5 :       if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
   23233                 :           4 :         fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
   23234                 :           5 :       unsigned int patch_area_size
   23235                 :           5 :         = crtl->patch_area_size - crtl->patch_area_entry;
   23236                 :           5 :       if (patch_area_size)
   23237                 :           2 :         ix86_output_patchable_area (patch_area_size,
   23238                 :             :                                     crtl->patch_area_entry == 0);
   23239                 :             :     }
   23240                 :             : 
   23241                 :         348 :   const char *mcount_name = MCOUNT_NAME;
   23242                 :             : 
   23243                 :         348 :   if (current_fentry_name (&mcount_name))
   23244                 :             :     ;
   23245                 :         346 :   else if (fentry_name)
   23246                 :           1 :     mcount_name = fentry_name;
   23247                 :         345 :   else if (flag_fentry)
   23248                 :          21 :     mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
   23249                 :             : 
   23250                 :         348 :   if (TARGET_64BIT)
   23251                 :             :     {
   23252                 :             : #ifndef NO_PROFILE_COUNTERS
   23253                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   23254                 :             :         fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
   23255                 :             :       else
   23256                 :             :         fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
   23257                 :             : #endif
   23258                 :             : 
   23259                 :         348 :       int scratch;
   23260                 :         348 :       const char *reg;
   23261                 :         348 :       char legacy_reg[4] = { 0 };
   23262                 :             : 
   23263                 :         348 :       if (!TARGET_PECOFF)
   23264                 :             :         {
   23265                 :         348 :           switch (ix86_cmodel)
   23266                 :             :             {
   23267                 :           5 :             case CM_LARGE:
   23268                 :           5 :               scratch = x86_64_select_profile_regnum (true);
   23269                 :           5 :               reg = hi_reg_name[scratch];
   23270                 :           5 :               if (LEGACY_INT_REGNO_P (scratch))
   23271                 :             :                 {
   23272                 :           0 :                   legacy_reg[0] = 'r';
   23273                 :           0 :                   legacy_reg[1] = reg[0];
   23274                 :           0 :                   legacy_reg[2] = reg[1];
   23275                 :           0 :                   reg = legacy_reg;
   23276                 :             :                 }
   23277                 :           5 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   23278                 :           1 :                 fprintf (file, "1:\tmovabs\t%s, OFFSET FLAT:%s\n"
   23279                 :             :                                "\tcall\t%s\n", reg, mcount_name, reg);
   23280                 :             :               else
   23281                 :           4 :                 fprintf (file, "1:\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
   23282                 :             :                          mcount_name, reg, reg);
   23283                 :             :               break;
   23284                 :           8 :             case CM_LARGE_PIC:
   23285                 :             : #ifdef NO_PROFILE_COUNTERS
   23286                 :           8 :               scratch = x86_64_select_profile_regnum (false);
   23287                 :           8 :               reg = hi_reg_name[scratch];
   23288                 :           8 :               if (LEGACY_INT_REGNO_P (scratch))
   23289                 :             :                 {
   23290                 :           1 :                   legacy_reg[0] = 'r';
   23291                 :           1 :                   legacy_reg[1] = reg[0];
   23292                 :           1 :                   legacy_reg[2] = reg[1];
   23293                 :           1 :                   reg = legacy_reg;
   23294                 :             :                 }
   23295                 :           8 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   23296                 :             :                 {
   23297                 :           1 :                   fprintf (file, "1:movabs\tr11, "
   23298                 :             :                                  "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
   23299                 :           1 :                   fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
   23300                 :           1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   23301                 :           1 :                   fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
   23302                 :             :                            mcount_name);
   23303                 :           1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   23304                 :           1 :                   fprintf (file, "\tcall\t%s\n", reg);
   23305                 :           1 :                   break;
   23306                 :             :                 }
   23307                 :           7 :               fprintf (file,
   23308                 :             :                        "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
   23309                 :           7 :               fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
   23310                 :           7 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   23311                 :           7 :               fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
   23312                 :           7 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   23313                 :           7 :               fprintf (file, "\tcall\t*%%%s\n", reg);
   23314                 :             : #else
   23315                 :             :               sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
   23316                 :             : #endif
   23317                 :           7 :               break;
   23318                 :           5 :             case CM_SMALL_PIC:
   23319                 :           5 :             case CM_MEDIUM_PIC:
   23320                 :           5 :               if (!ix86_direct_extern_access)
   23321                 :             :                 {
   23322                 :           1 :                   if (ASSEMBLER_DIALECT == ASM_INTEL)
   23323                 :           1 :                     fprintf (file, "1:\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
   23324                 :             :                              mcount_name);
   23325                 :             :                   else
   23326                 :           0 :                     fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n",
   23327                 :             :                              mcount_name);
   23328                 :             :                   break;
   23329                 :             :                 }
   23330                 :             :               /* fall through */
   23331                 :         334 :             default:
   23332                 :         334 :               x86_print_call_or_nop (file, mcount_name);
   23333                 :         334 :               break;
   23334                 :             :             }
   23335                 :             :         }
   23336                 :             :       else
   23337                 :             :         x86_print_call_or_nop (file, mcount_name);
   23338                 :             :     }
   23339                 :           0 :   else if (flag_pic)
   23340                 :             :     {
   23341                 :             : #ifndef NO_PROFILE_COUNTERS
   23342                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   23343                 :             :         fprintf (file,
   23344                 :             :                  "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
   23345                 :             :                  LPREFIX, labelno);
   23346                 :             :       else
   23347                 :             :         fprintf (file,
   23348                 :             :                  "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
   23349                 :             :                  LPREFIX, labelno);
   23350                 :             : #endif
   23351                 :           0 :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   23352                 :           0 :         fprintf (file, "1:\tcall\t[DWORD PTR %s@GOT[ebx]]\n", mcount_name);
   23353                 :             :       else
   23354                 :           0 :         fprintf (file, "1:\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
   23355                 :             :     }
   23356                 :             :   else
   23357                 :             :     {
   23358                 :             : #ifndef NO_PROFILE_COUNTERS
   23359                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   23360                 :             :         fprintf (file,
   23361                 :             :                  "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
   23362                 :             :                  LPREFIX, labelno);
   23363                 :             :       else
   23364                 :             :         fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
   23365                 :             :                  LPREFIX, labelno);
   23366                 :             : #endif
   23367                 :           0 :       x86_print_call_or_nop (file, mcount_name);
   23368                 :             :     }
   23369                 :             : 
   23370                 :         348 :   if (flag_record_mcount
   23371                 :         687 :       || lookup_attribute ("fentry_section",
   23372                 :         339 :                            DECL_ATTRIBUTES (current_function_decl)))
   23373                 :             :     {
   23374                 :          10 :       const char *sname = "__mcount_loc";
   23375                 :             : 
   23376                 :          10 :       if (current_fentry_section (&sname))
   23377                 :             :         ;
   23378                 :           8 :       else if (fentry_section)
   23379                 :           1 :         sname = fentry_section;
   23380                 :             : 
   23381                 :          10 :       fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
   23382                 :          10 :       fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   23383                 :          10 :       fprintf (file, "\t.previous\n");
   23384                 :             :     }
   23385                 :         348 : }
   23386                 :             : 
   23387                 :             : /* We don't have exact information about the insn sizes, but we may assume
   23388                 :             :    quite safely that we are informed about all 1 byte insns and memory
   23389                 :             :    address sizes.  This is enough to eliminate unnecessary padding in
   23390                 :             :    99% of cases.  */
   23391                 :             : 
   23392                 :             : int
   23393                 :   340949227 : ix86_min_insn_size (rtx_insn *insn)
   23394                 :             : {
   23395                 :   340949227 :   int l = 0, len;
   23396                 :             : 
   23397                 :   340949227 :   if (!INSN_P (insn) || !active_insn_p (insn))
   23398                 :      541745 :     return 0;
   23399                 :             : 
   23400                 :             :   /* Discard alignments we've emit and jump instructions.  */
   23401                 :   340407482 :   if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
   23402                 :   340407482 :       && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
   23403                 :             :     return 0;
   23404                 :             : 
   23405                 :             :   /* Important case - calls are always 5 bytes.
   23406                 :             :      It is common to have many calls in the row.  */
   23407                 :   340407476 :   if (CALL_P (insn)
   23408                 :     8713883 :       && symbolic_reference_mentioned_p (PATTERN (insn))
   23409                 :   348788775 :       && !SIBLING_CALL_P (insn))
   23410                 :             :     return 5;
   23411                 :   332244974 :   len = get_attr_length (insn);
   23412                 :   332244974 :   if (len <= 1)
   23413                 :             :     return 1;
   23414                 :             : 
   23415                 :             :   /* For normal instructions we rely on get_attr_length being exact,
   23416                 :             :      with a few exceptions.  */
   23417                 :   323376805 :   if (!JUMP_P (insn))
   23418                 :             :     {
   23419                 :   318479254 :       enum attr_type type = get_attr_type (insn);
   23420                 :             : 
   23421                 :   318479254 :       switch (type)
   23422                 :             :         {
   23423                 :       91123 :         case TYPE_MULTI:
   23424                 :       91123 :           if (GET_CODE (PATTERN (insn)) == ASM_INPUT
   23425                 :       91123 :               || asm_noperands (PATTERN (insn)) >= 0)
   23426                 :         502 :             return 0;
   23427                 :             :           break;
   23428                 :             :         case TYPE_OTHER:
   23429                 :             :         case TYPE_FCMP:
   23430                 :             :           break;
   23431                 :             :         default:
   23432                 :             :           /* Otherwise trust get_attr_length.  */
   23433                 :             :           return len;
   23434                 :             :         }
   23435                 :             : 
   23436                 :      464906 :       l = get_attr_length_address (insn);
   23437                 :      464906 :       if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
   23438                 :             :         l = 4;
   23439                 :             :     }
   23440                 :      374843 :   if (l)
   23441                 :       90063 :     return 1+l;
   23442                 :             :   else
   23443                 :     5272394 :     return 2;
   23444                 :             : }
   23445                 :             : 
   23446                 :             : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   23447                 :             : 
   23448                 :             : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
   23449                 :             :    window.  */
   23450                 :             : 
   23451                 :             : static void
   23452                 :       47205 : ix86_avoid_jump_mispredicts (void)
   23453                 :             : {
   23454                 :       47205 :   rtx_insn *insn, *start = get_insns ();
   23455                 :       47205 :   int nbytes = 0, njumps = 0;
   23456                 :       47205 :   bool isjump = false;
   23457                 :             : 
   23458                 :             :   /* Look for all minimal intervals of instructions containing 4 jumps.
   23459                 :             :      The intervals are bounded by START and INSN.  NBYTES is the total
   23460                 :             :      size of instructions in the interval including INSN and not including
   23461                 :             :      START.  When the NBYTES is smaller than 16 bytes, it is possible
   23462                 :             :      that the end of START and INSN ends up in the same 16byte page.
   23463                 :             : 
   23464                 :             :      The smallest offset in the page INSN can start is the case where START
   23465                 :             :      ends on the offset 0.  Offset of INSN is then NBYTES - sizeof (INSN).
   23466                 :             :      We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
   23467                 :             : 
   23468                 :             :      Don't consider asm goto as jump, while it can contain a jump, it doesn't
   23469                 :             :      have to, control transfer to label(s) can be performed through other
   23470                 :             :      means, and also we estimate minimum length of all asm stmts as 0.  */
   23471                 :      747921 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   23472                 :             :     {
   23473                 :      700716 :       int min_size;
   23474                 :             : 
   23475                 :      700716 :       if (LABEL_P (insn))
   23476                 :             :         {
   23477                 :         952 :           align_flags alignment = label_to_alignment (insn);
   23478                 :         952 :           int align = alignment.levels[0].log;
   23479                 :         952 :           int max_skip = alignment.levels[0].maxskip;
   23480                 :             : 
   23481                 :         952 :           if (max_skip > 15)
   23482                 :             :             max_skip = 15;
   23483                 :             :           /* If align > 3, only up to 16 - max_skip - 1 bytes can be
   23484                 :             :              already in the current 16 byte page, because otherwise
   23485                 :             :              ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
   23486                 :             :              bytes to reach 16 byte boundary.  */
   23487                 :         952 :           if (align <= 0
   23488                 :         325 :               || (align <= 3 && max_skip != (1 << align) - 1))
   23489                 :         952 :             max_skip = 0;
   23490                 :         952 :           if (dump_file)
   23491                 :           0 :             fprintf (dump_file, "Label %i with max_skip %i\n",
   23492                 :           0 :                      INSN_UID (insn), max_skip);
   23493                 :         952 :           if (max_skip)
   23494                 :             :             {
   23495                 :        6227 :               while (nbytes + max_skip >= 16)
   23496                 :             :                 {
   23497                 :        5902 :                   start = NEXT_INSN (start);
   23498                 :         319 :                   if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   23499                 :        5917 :                       || CALL_P (start))
   23500                 :         352 :                     njumps--, isjump = true;
   23501                 :             :                   else
   23502                 :             :                     isjump = false;
   23503                 :        5902 :                   nbytes -= ix86_min_insn_size (start);
   23504                 :             :                 }
   23505                 :             :             }
   23506                 :         952 :           continue;
   23507                 :         952 :         }
   23508                 :             : 
   23509                 :      699764 :       min_size = ix86_min_insn_size (insn);
   23510                 :      699764 :       nbytes += min_size;
   23511                 :      699764 :       if (dump_file)
   23512                 :           0 :         fprintf (dump_file, "Insn %i estimated to %i bytes\n",
   23513                 :           0 :                  INSN_UID (insn), min_size);
   23514                 :       48356 :       if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
   23515                 :      699784 :           || CALL_P (insn))
   23516                 :       49380 :         njumps++;
   23517                 :             :       else
   23518                 :      650384 :         continue;
   23519                 :             : 
   23520                 :       57646 :       while (njumps > 3)
   23521                 :             :         {
   23522                 :        8266 :           start = NEXT_INSN (start);
   23523                 :         534 :           if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   23524                 :        8266 :               || CALL_P (start))
   23525                 :        1234 :             njumps--, isjump = true;
   23526                 :             :           else
   23527                 :             :             isjump = false;
   23528                 :        8266 :           nbytes -= ix86_min_insn_size (start);
   23529                 :             :         }
   23530                 :       49380 :       gcc_assert (njumps >= 0);
   23531                 :       49380 :       if (dump_file)
   23532                 :           0 :         fprintf (dump_file, "Interval %i to %i has %i bytes\n",
   23533                 :           0 :                  INSN_UID (start), INSN_UID (insn), nbytes);
   23534                 :             : 
   23535                 :       49380 :       if (njumps == 3 && isjump && nbytes < 16)
   23536                 :             :         {
   23537                 :          46 :           int padsize = 15 - nbytes + ix86_min_insn_size (insn);
   23538                 :             : 
   23539                 :          46 :           if (dump_file)
   23540                 :           0 :             fprintf (dump_file, "Padding insn %i by %i bytes!\n",
   23541                 :           0 :                      INSN_UID (insn), padsize);
   23542                 :          46 :           emit_insn_before (gen_max_skip_align (GEN_INT (4), GEN_INT (padsize)), insn);
   23543                 :             :         }
   23544                 :             :     }
   23545                 :       47205 : }
   23546                 :             : #endif
   23547                 :             : 
   23548                 :             : /* AMD Athlon works faster
   23549                 :             :    when RET is not destination of conditional jump or directly preceded
   23550                 :             :    by other jump instruction.  We avoid the penalty by inserting NOP just
   23551                 :             :    before the RET instructions in such cases.  */
   23552                 :             : static void
   23553                 :       46923 : ix86_pad_returns (void)
   23554                 :             : {
   23555                 :       46923 :   edge e;
   23556                 :       46923 :   edge_iterator ei;
   23557                 :             : 
   23558                 :       93870 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23559                 :             :     {
   23560                 :       46947 :       basic_block bb = e->src;
   23561                 :       46947 :       rtx_insn *ret = BB_END (bb);
   23562                 :       46947 :       rtx_insn *prev;
   23563                 :       46947 :       bool replace = false;
   23564                 :             : 
   23565                 :       46937 :       if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
   23566                 :       93884 :           || optimize_bb_for_size_p (bb))
   23567                 :          23 :         continue;
   23568                 :      186784 :       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
   23569                 :      139448 :         if (active_insn_p (prev) || LABEL_P (prev))
   23570                 :             :           break;
   23571                 :       46924 :       if (prev && LABEL_P (prev))
   23572                 :             :         {
   23573                 :          42 :           edge e;
   23574                 :          42 :           edge_iterator ei;
   23575                 :             : 
   23576                 :          55 :           FOR_EACH_EDGE (e, ei, bb->preds)
   23577                 :         143 :             if (EDGE_FREQUENCY (e) && e->src->index >= 0
   23578                 :          95 :                 && !(e->flags & EDGE_FALLTHRU))
   23579                 :             :               {
   23580                 :             :                 replace = true;
   23581                 :             :                 break;
   23582                 :             :               }
   23583                 :             :         }
   23584                 :          42 :       if (!replace)
   23585                 :             :         {
   23586                 :       46889 :           prev = prev_active_insn (ret);
   23587                 :       46889 :           if (prev
   23588                 :       46889 :               && ((JUMP_P (prev) && any_condjump_p (prev))
   23589                 :       46458 :                   || CALL_P (prev)))
   23590                 :             :             replace = true;
   23591                 :             :           /* Empty functions get branch mispredict even when
   23592                 :             :              the jump destination is not visible to us.  */
   23593                 :       46889 :           if (!prev && !optimize_function_for_size_p (cfun))
   23594                 :             :             replace = true;
   23595                 :             :         }
   23596                 :       46477 :       if (replace)
   23597                 :             :         {
   23598                 :         483 :           emit_jump_insn_before (gen_simple_return_internal_long (), ret);
   23599                 :         483 :           delete_insn (ret);
   23600                 :             :         }
   23601                 :             :     }
   23602                 :       46923 : }
   23603                 :             : 
   23604                 :             : /* Count the minimum number of instructions in BB.  Return 4 if the
   23605                 :             :    number of instructions >= 4.  */
   23606                 :             : 
   23607                 :             : static int
   23608                 :          42 : ix86_count_insn_bb (basic_block bb)
   23609                 :             : {
   23610                 :          42 :   rtx_insn *insn;
   23611                 :          42 :   int insn_count = 0;
   23612                 :             : 
   23613                 :             :   /* Count number of instructions in this block.  Return 4 if the number
   23614                 :             :      of instructions >= 4.  */
   23615                 :         312 :   FOR_BB_INSNS (bb, insn)
   23616                 :             :     {
   23617                 :             :       /* Only happen in exit blocks.  */
   23618                 :         306 :       if (JUMP_P (insn)
   23619                 :         306 :           && ANY_RETURN_P (PATTERN (insn)))
   23620                 :             :         break;
   23621                 :             : 
   23622                 :         282 :       if (NONDEBUG_INSN_P (insn)
   23623                 :         102 :           && GET_CODE (PATTERN (insn)) != USE
   23624                 :         366 :           && GET_CODE (PATTERN (insn)) != CLOBBER)
   23625                 :             :         {
   23626                 :          84 :           insn_count++;
   23627                 :          84 :           if (insn_count >= 4)
   23628                 :             :             return insn_count;
   23629                 :             :         }
   23630                 :             :     }
   23631                 :             : 
   23632                 :             :   return insn_count;
   23633                 :             : }
   23634                 :             : 
   23635                 :             : 
   23636                 :             : /* Count the minimum number of instructions in code path in BB.
   23637                 :             :    Return 4 if the number of instructions >= 4.  */
   23638                 :             : 
   23639                 :             : static int
   23640                 :          64 : ix86_count_insn (basic_block bb)
   23641                 :             : {
   23642                 :          64 :   edge e;
   23643                 :          64 :   edge_iterator ei;
   23644                 :          64 :   int min_prev_count;
   23645                 :             : 
   23646                 :             :   /* Only bother counting instructions along paths with no
   23647                 :             :      more than 2 basic blocks between entry and exit.  Given
   23648                 :             :      that BB has an edge to exit, determine if a predecessor
   23649                 :             :      of BB has an edge from entry.  If so, compute the number
   23650                 :             :      of instructions in the predecessor block.  If there
   23651                 :             :      happen to be multiple such blocks, compute the minimum.  */
   23652                 :          64 :   min_prev_count = 4;
   23653                 :         148 :   FOR_EACH_EDGE (e, ei, bb->preds)
   23654                 :             :     {
   23655                 :         110 :       edge prev_e;
   23656                 :         110 :       edge_iterator prev_ei;
   23657                 :             : 
   23658                 :         110 :       if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   23659                 :             :         {
   23660                 :          26 :           min_prev_count = 0;
   23661                 :          26 :           break;
   23662                 :             :         }
   23663                 :         186 :       FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
   23664                 :             :         {
   23665                 :         112 :           if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   23666                 :             :             {
   23667                 :          10 :               int count = ix86_count_insn_bb (e->src);
   23668                 :          10 :               if (count < min_prev_count)
   23669                 :          84 :                 min_prev_count = count;
   23670                 :             :               break;
   23671                 :             :             }
   23672                 :             :         }
   23673                 :             :     }
   23674                 :             : 
   23675                 :          64 :   if (min_prev_count < 4)
   23676                 :          32 :     min_prev_count += ix86_count_insn_bb (bb);
   23677                 :             : 
   23678                 :          64 :   return min_prev_count;
   23679                 :             : }
   23680                 :             : 
   23681                 :             : /* Pad short function to 4 instructions.   */
   23682                 :             : 
   23683                 :             : static void
   23684                 :          65 : ix86_pad_short_function (void)
   23685                 :             : {
   23686                 :          65 :   edge e;
   23687                 :          65 :   edge_iterator ei;
   23688                 :             : 
   23689                 :         132 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23690                 :             :     {
   23691                 :          67 :       rtx_insn *ret = BB_END (e->src);
   23692                 :          67 :       if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
   23693                 :             :         {
   23694                 :          64 :           int insn_count = ix86_count_insn (e->src);
   23695                 :             : 
   23696                 :             :           /* Pad short function.  */
   23697                 :          64 :           if (insn_count < 4)
   23698                 :             :             {
   23699                 :             :               rtx_insn *insn = ret;
   23700                 :             : 
   23701                 :             :               /* Find epilogue.  */
   23702                 :             :               while (insn
   23703                 :          54 :                      && (!NOTE_P (insn)
   23704                 :          25 :                          || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
   23705                 :          31 :                 insn = PREV_INSN (insn);
   23706                 :             : 
   23707                 :          23 :               if (!insn)
   23708                 :           0 :                 insn = ret;
   23709                 :             : 
   23710                 :             :               /* Two NOPs count as one instruction.  */
   23711                 :          23 :               insn_count = 2 * (4 - insn_count);
   23712                 :          23 :               emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
   23713                 :             :             }
   23714                 :             :         }
   23715                 :             :     }
   23716                 :          65 : }
   23717                 :             : 
   23718                 :             : /* Fix up a Windows system unwinder issue.  If an EH region falls through into
   23719                 :             :    the epilogue, the Windows system unwinder will apply epilogue logic and
   23720                 :             :    produce incorrect offsets.  This can be avoided by adding a nop between
   23721                 :             :    the last insn that can throw and the first insn of the epilogue.  */
   23722                 :             : 
   23723                 :             : static void
   23724                 :           0 : ix86_seh_fixup_eh_fallthru (void)
   23725                 :             : {
   23726                 :           0 :   edge e;
   23727                 :           0 :   edge_iterator ei;
   23728                 :             : 
   23729                 :           0 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23730                 :             :     {
   23731                 :           0 :       rtx_insn *insn, *next;
   23732                 :             : 
   23733                 :             :       /* Find the beginning of the epilogue.  */
   23734                 :           0 :       for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
   23735                 :           0 :         if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
   23736                 :             :           break;
   23737                 :           0 :       if (insn == NULL)
   23738                 :           0 :         continue;
   23739                 :             : 
   23740                 :             :       /* We only care about preceding insns that can throw.  */
   23741                 :           0 :       insn = prev_active_insn (insn);
   23742                 :           0 :       if (insn == NULL || !can_throw_internal (insn))
   23743                 :           0 :         continue;
   23744                 :             : 
   23745                 :             :       /* Do not separate calls from their debug information.  */
   23746                 :           0 :       for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
   23747                 :           0 :         if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
   23748                 :           0 :           insn = next;
   23749                 :             :         else
   23750                 :             :           break;
   23751                 :             : 
   23752                 :           0 :       emit_insn_after (gen_nops (const1_rtx), insn);
   23753                 :             :     }
   23754                 :           0 : }
   23755                 :             : /* Split vector load from parm_decl to elemental loads to avoid STLF
   23756                 :             :    stalls.  */
   23757                 :             : static void
   23758                 :      941276 : ix86_split_stlf_stall_load ()
   23759                 :             : {
   23760                 :      941276 :   rtx_insn* insn, *start = get_insns ();
   23761                 :      941276 :   unsigned window = 0;
   23762                 :             : 
   23763                 :    25544200 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   23764                 :             :     {
   23765                 :    25543363 :       if (!NONDEBUG_INSN_P (insn))
   23766                 :    14245419 :         continue;
   23767                 :    11297944 :       window++;
   23768                 :             :       /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
   23769                 :             :          other, just emulate for pipeline) before stalled load, stlf stall
   23770                 :             :          case is as fast as no stall cases on CLX.
   23771                 :             :          Since CFG is freed before machine_reorg, just do a rough
   23772                 :             :          calculation of the window according to the layout.  */
   23773                 :    11297944 :       if (window > (unsigned) x86_stlf_window_ninsns)
   23774                 :             :         return;
   23775                 :             : 
   23776                 :    11280680 :       if (any_uncondjump_p (insn)
   23777                 :    11245804 :           || ANY_RETURN_P (PATTERN (insn))
   23778                 :    22164481 :           || CALL_P (insn))
   23779                 :             :         return;
   23780                 :             : 
   23781                 :    10357505 :       rtx set = single_set (insn);
   23782                 :    10357505 :       if (!set)
   23783                 :      384684 :         continue;
   23784                 :     9972821 :       rtx src = SET_SRC (set);
   23785                 :    19945480 :       if (!MEM_P (src)
   23786                 :             :           /* Only handle V2DFmode load since it doesn't need any scratch
   23787                 :             :              register.  */
   23788                 :     9972821 :           || GET_MODE (src) != E_V2DFmode
   23789                 :        5325 :           || !MEM_EXPR (src)
   23790                 :     9976660 :           || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL)
   23791                 :     9972659 :         continue;
   23792                 :             : 
   23793                 :         162 :       rtx zero = CONST0_RTX (V2DFmode);
   23794                 :         162 :       rtx dest = SET_DEST (set);
   23795                 :         162 :       rtx m = adjust_address (src, DFmode, 0);
   23796                 :         162 :       rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
   23797                 :         162 :       emit_insn_before (loadlpd, insn);
   23798                 :         162 :       m = adjust_address (src, DFmode, 8);
   23799                 :         162 :       rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
   23800                 :         162 :       if (dump_file && (dump_flags & TDF_DETAILS))
   23801                 :             :         {
   23802                 :           0 :           fputs ("Due to potential STLF stall, split instruction:\n",
   23803                 :             :                  dump_file);
   23804                 :           0 :           print_rtl_single (dump_file, insn);
   23805                 :           0 :           fputs ("To:\n", dump_file);
   23806                 :           0 :           print_rtl_single (dump_file, loadlpd);
   23807                 :           0 :           print_rtl_single (dump_file, loadhpd);
   23808                 :             :         }
   23809                 :         162 :       PATTERN (insn) = loadhpd;
   23810                 :         162 :       INSN_CODE (insn) = -1;
   23811                 :         162 :       gcc_assert (recog_memoized (insn) != -1);
   23812                 :             :     }
   23813                 :             : }
   23814                 :             : 
   23815                 :             : /* Implement machine specific optimizations.  We implement padding of returns
   23816                 :             :    for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window.  */
   23817                 :             : static void
   23818                 :     1433102 : ix86_reorg (void)
   23819                 :             : {
   23820                 :             :   /* We are freeing block_for_insn in the toplev to keep compatibility
   23821                 :             :      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   23822                 :     1433102 :   compute_bb_for_insn ();
   23823                 :             : 
   23824                 :     1433102 :   if (TARGET_SEH && current_function_has_exception_handlers ())
   23825                 :             :     ix86_seh_fixup_eh_fallthru ();
   23826                 :             : 
   23827                 :     1433102 :   if (optimize && optimize_function_for_speed_p (cfun))
   23828                 :             :     {
   23829                 :      943545 :       if (TARGET_SSE2)
   23830                 :      941276 :         ix86_split_stlf_stall_load ();
   23831                 :      943545 :       if (TARGET_PAD_SHORT_FUNCTION)
   23832                 :          65 :         ix86_pad_short_function ();
   23833                 :      943480 :       else if (TARGET_PAD_RETURNS)
   23834                 :       46923 :         ix86_pad_returns ();
   23835                 :             : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   23836                 :      943545 :       if (TARGET_FOUR_JUMP_LIMIT)
   23837                 :       47205 :         ix86_avoid_jump_mispredicts ();
   23838                 :             : #endif
   23839                 :             :     }
   23840                 :     1433102 : }
   23841                 :             : 
   23842                 :             : /* Return nonzero when QImode register that must be represented via REX prefix
   23843                 :             :    is used.  */
   23844                 :             : bool
   23845                 :     8012126 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
   23846                 :             : {
   23847                 :     8012126 :   int i;
   23848                 :     8012126 :   extract_insn_cached (insn);
   23849                 :    30200318 :   for (i = 0; i < recog_data.n_operands; i++)
   23850                 :     4386045 :     if (GENERAL_REG_P (recog_data.operand[i])
   23851                 :    20055727 :         && !QI_REGNO_P (REGNO (recog_data.operand[i])))
   23852                 :             :        return true;
   23853                 :             :   return false;
   23854                 :             : }
   23855                 :             : 
   23856                 :             : /* Return true when INSN mentions register that must be encoded using REX
   23857                 :             :    prefix.  */
   23858                 :             : bool
   23859                 :   178896286 : x86_extended_reg_mentioned_p (rtx insn)
   23860                 :             : {
   23861                 :   178896286 :   subrtx_iterator::array_type array;
   23862                 :   930665652 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   23863                 :             :     {
   23864                 :   796994506 :       const_rtx x = *iter;
   23865                 :   796994506 :       if (REG_P (x)
   23866                 :   796994506 :           && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
   23867                 :   228816469 :               || REX2_INT_REGNO_P (REGNO (x))))
   23868                 :    45225140 :         return true;
   23869                 :             :     }
   23870                 :   133671146 :   return false;
   23871                 :   178896286 : }
   23872                 :             : 
   23873                 :             : /* Return true when INSN mentions register that must be encoded using REX2
   23874                 :             :    prefix.  */
   23875                 :             : bool
   23876                 :     1884274 : x86_extended_rex2reg_mentioned_p (rtx insn)
   23877                 :             : {
   23878                 :     1884274 :   subrtx_iterator::array_type array;
   23879                 :     8902550 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   23880                 :             :     {
   23881                 :     7018924 :       const_rtx x = *iter;
   23882                 :     7018924 :       if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
   23883                 :         648 :         return true;
   23884                 :             :     }
   23885                 :     1883626 :   return false;
   23886                 :     1884274 : }
   23887                 :             : 
   23888                 :             : /* Return true when rtx operands mentions register that must be encoded using
   23889                 :             :    evex prefix.  */
   23890                 :             : bool
   23891                 :           8 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
   23892                 :             : {
   23893                 :           8 :   int i;
   23894                 :          20 :   for (i = 0; i < nops; i++)
   23895                 :          16 :     if (EXT_REX_SSE_REG_P (operands[i])
   23896                 :          28 :         || x86_extended_rex2reg_mentioned_p (operands[i]))
   23897                 :           4 :       return true;
   23898                 :             :   return false;
   23899                 :             : }
   23900                 :             : 
   23901                 :             : /* If profitable, negate (without causing overflow) integer constant
   23902                 :             :    of mode MODE at location LOC.  Return true in this case.  */
   23903                 :             : bool
   23904                 :     5672970 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
   23905                 :             : {
   23906                 :     5672970 :   HOST_WIDE_INT val;
   23907                 :             : 
   23908                 :     5672970 :   if (!CONST_INT_P (*loc))
   23909                 :             :     return false;
   23910                 :             : 
   23911                 :     4802381 :   switch (mode)
   23912                 :             :     {
   23913                 :     2690092 :     case E_DImode:
   23914                 :             :       /* DImode x86_64 constants must fit in 32 bits.  */
   23915                 :     2690092 :       gcc_assert (x86_64_immediate_operand (*loc, mode));
   23916                 :             : 
   23917                 :             :       mode = SImode;
   23918                 :             :       break;
   23919                 :             : 
   23920                 :             :     case E_SImode:
   23921                 :             :     case E_HImode:
   23922                 :             :     case E_QImode:
   23923                 :             :       break;
   23924                 :             : 
   23925                 :           0 :     default:
   23926                 :           0 :       gcc_unreachable ();
   23927                 :             :     }
   23928                 :             : 
   23929                 :             :   /* Avoid overflows.  */
   23930                 :     4802381 :   if (mode_signbit_p (mode, *loc))
   23931                 :             :     return false;
   23932                 :             : 
   23933                 :     4801989 :   val = INTVAL (*loc);
   23934                 :             : 
   23935                 :             :   /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
   23936                 :             :      Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
   23937                 :     4801989 :   if ((val < 0 && val != -128)
   23938                 :     3154100 :       || val == 128)
   23939                 :             :     {
   23940                 :     1658674 :       *loc = GEN_INT (-val);
   23941                 :     1658674 :       return true;
   23942                 :             :     }
   23943                 :             : 
   23944                 :             :   return false;
   23945                 :             : }
   23946                 :             : 
   23947                 :             : /* Generate an unsigned DImode/SImode to FP conversion.  This is the same code
   23948                 :             :    optabs would emit if we didn't have TFmode patterns.  */
   23949                 :             : 
   23950                 :             : void
   23951                 :        4621 : x86_emit_floatuns (rtx operands[2])
   23952                 :             : {
   23953                 :        4621 :   rtx_code_label *neglab, *donelab;
   23954                 :        4621 :   rtx i0, i1, f0, in, out;
   23955                 :        4621 :   machine_mode mode, inmode;
   23956                 :             : 
   23957                 :        4621 :   inmode = GET_MODE (operands[1]);
   23958                 :        4621 :   gcc_assert (inmode == SImode || inmode == DImode);
   23959                 :             : 
   23960                 :        4621 :   out = operands[0];
   23961                 :        4621 :   in = force_reg (inmode, operands[1]);
   23962                 :        4621 :   mode = GET_MODE (out);
   23963                 :        4621 :   neglab = gen_label_rtx ();
   23964                 :        4621 :   donelab = gen_label_rtx ();
   23965                 :        4621 :   f0 = gen_reg_rtx (mode);
   23966                 :             : 
   23967                 :        4621 :   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
   23968                 :             : 
   23969                 :        4621 :   expand_float (out, in, 0);
   23970                 :             : 
   23971                 :        4621 :   emit_jump_insn (gen_jump (donelab));
   23972                 :        4621 :   emit_barrier ();
   23973                 :             : 
   23974                 :        4621 :   emit_label (neglab);
   23975                 :             : 
   23976                 :        4621 :   i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
   23977                 :             :                             1, OPTAB_DIRECT);
   23978                 :        4621 :   i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
   23979                 :             :                             1, OPTAB_DIRECT);
   23980                 :        4621 :   i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
   23981                 :             : 
   23982                 :        4621 :   expand_float (f0, i0, 0);
   23983                 :             : 
   23984                 :        4621 :   emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
   23985                 :             : 
   23986                 :        4621 :   emit_label (donelab);
   23987                 :        4621 : }
   23988                 :             : 
   23989                 :             : /* Return the diagnostic message string if conversion from FROMTYPE to
   23990                 :             :    TOTYPE is not allowed, NULL otherwise.  */
   23991                 :             : 
   23992                 :             : static const char *
   23993                 :   968266511 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
   23994                 :             : {
   23995                 :   968266511 :   machine_mode from_mode = element_mode (fromtype);
   23996                 :   968266511 :   machine_mode to_mode = element_mode (totype);
   23997                 :             : 
   23998                 :   968266511 :   if (!TARGET_SSE2 && from_mode != to_mode)
   23999                 :             :     {
   24000                 :             :       /* Do no allow conversions to/from BFmode/HFmode scalar types
   24001                 :             :          when TARGET_SSE2 is not available.  */
   24002                 :      528502 :       if (from_mode == BFmode)
   24003                 :             :         return N_("invalid conversion from type %<__bf16%> "
   24004                 :             :                   "without option %<-msse2%>");
   24005                 :      528501 :       if (from_mode == HFmode)
   24006                 :             :         return N_("invalid conversion from type %<_Float16%> "
   24007                 :             :                   "without option %<-msse2%>");
   24008                 :      528501 :       if (to_mode == BFmode)
   24009                 :             :         return N_("invalid conversion to type %<__bf16%> "
   24010                 :             :                   "without option %<-msse2%>");
   24011                 :      528501 :       if (to_mode == HFmode)
   24012                 :             :         return N_("invalid conversion to type %<_Float16%> "
   24013                 :             :                   "without option %<-msse2%>");
   24014                 :             :     }
   24015                 :             : 
   24016                 :             :   /* Warn for silent implicit conversion between __bf16 and short,
   24017                 :             :      since __bfloat16 is refined as real __bf16 instead of short
   24018                 :             :      since GCC13.  */
   24019                 :   968266509 :   if (element_mode (fromtype) != element_mode (totype)
   24020                 :   968266509 :       && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
   24021                 :             :     {
   24022                 :             :       /* Warn for silent implicit conversion where user may expect
   24023                 :             :          a bitcast.  */
   24024                 :    12116860 :       if ((TYPE_MODE (fromtype) == BFmode
   24025                 :          13 :            && TYPE_MODE (totype) == HImode)
   24026                 :    12116872 :           || (TYPE_MODE (totype) == BFmode
   24027                 :          38 :               && TYPE_MODE (fromtype) == HImode))
   24028                 :           1 :         warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
   24029                 :             :                 "to real %<__bf16%> since GCC 13.1, be careful of "
   24030                 :             :                  "implicit conversion between %<__bf16%> and %<short%>; "
   24031                 :             :                  "an explicit bitcast may be needed here");
   24032                 :             :     }
   24033                 :             : 
   24034                 :             :   /* Conversion allowed.  */
   24035                 :             :   return NULL;
   24036                 :             : }
   24037                 :             : 
   24038                 :             : /* Return the diagnostic message string if the unary operation OP is
   24039                 :             :    not permitted on TYPE, NULL otherwise.  */
   24040                 :             : 
   24041                 :             : static const char *
   24042                 :    87328346 : ix86_invalid_unary_op (int op, const_tree type)
   24043                 :             : {
   24044                 :    87328346 :   machine_mode mmode = element_mode (type);
   24045                 :             :   /* Reject all single-operand operations on BFmode/HFmode except for &
   24046                 :             :      when TARGET_SSE2 is not available.  */
   24047                 :    87328346 :   if (!TARGET_SSE2 && op != ADDR_EXPR)
   24048                 :             :     {
   24049                 :      107987 :       if (mmode == BFmode)
   24050                 :             :         return N_("operation not permitted on type %<__bf16%> "
   24051                 :             :                   "without option %<-msse2%>");
   24052                 :      107987 :       if (mmode == HFmode)
   24053                 :           0 :         return N_("operation not permitted on type %<_Float16%> "
   24054                 :             :                   "without option %<-msse2%>");
   24055                 :             :     }
   24056                 :             : 
   24057                 :             :   /* Operation allowed.  */
   24058                 :             :   return NULL;
   24059                 :             : }
   24060                 :             : 
   24061                 :             : /* Return the diagnostic message string if the binary operation OP is
   24062                 :             :    not permitted on TYPE1 and TYPE2, NULL otherwise.  */
   24063                 :             : 
   24064                 :             : static const char *
   24065                 :   132625336 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
   24066                 :             :                         const_tree type2)
   24067                 :             : {
   24068                 :   132625336 :   machine_mode type1_mode = element_mode (type1);
   24069                 :   132625336 :   machine_mode type2_mode = element_mode (type2);
   24070                 :             :   /* Reject all 2-operand operations on BFmode or HFmode
   24071                 :             :      when TARGET_SSE2 is not available.  */
   24072                 :   132625336 :   if (!TARGET_SSE2)
   24073                 :             :     {
   24074                 :      982049 :       if (type1_mode == BFmode || type2_mode == BFmode)
   24075                 :             :         return N_("operation not permitted on type %<__bf16%> "
   24076                 :             :                   "without option %<-msse2%>");
   24077                 :             : 
   24078                 :      982049 :       if (type1_mode == HFmode || type2_mode == HFmode)
   24079                 :           0 :         return N_("operation not permitted on type %<_Float16%> "
   24080                 :             :                   "without option %<-msse2%>");
   24081                 :             :     }
   24082                 :             : 
   24083                 :             :   /* Operation allowed.  */
   24084                 :             :   return NULL;
   24085                 :             : }
   24086                 :             : 
   24087                 :             : 
   24088                 :             : /* Target hook for scalar_mode_supported_p.  */
   24089                 :             : static bool
   24090                 :     4271355 : ix86_scalar_mode_supported_p (scalar_mode mode)
   24091                 :             : {
   24092                 :     4271355 :   if (DECIMAL_FLOAT_MODE_P (mode))
   24093                 :      614182 :     return default_decimal_float_supported_p ();
   24094                 :     3657173 :   else if (mode == TFmode)
   24095                 :             :     return true;
   24096                 :     3341299 :   else if (mode == HFmode || mode == BFmode)
   24097                 :             :     return true;
   24098                 :             :   else
   24099                 :     2711534 :     return default_scalar_mode_supported_p (mode);
   24100                 :             : }
   24101                 :             : 
   24102                 :             : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
   24103                 :             :    if MODE is HFmode, and punt to the generic implementation otherwise.  */
   24104                 :             : 
   24105                 :             : static bool
   24106                 :     2169096 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
   24107                 :             : {
   24108                 :             :   /* NB: Always return TRUE for HFmode so that the _Float16 type will
   24109                 :             :      be defined by the C front-end for AVX512FP16 intrinsics.  We will
   24110                 :             :      issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
   24111                 :             :      enabled.  */
   24112                 :     1854689 :   return ((mode == HFmode || mode == BFmode)
   24113                 :     3709378 :           ? true
   24114                 :     1540282 :           : default_libgcc_floating_mode_supported_p (mode));
   24115                 :             : }
   24116                 :             : 
   24117                 :             : /* Implements target hook vector_mode_supported_p.  */
   24118                 :             : static bool
   24119                 :  1272906829 : ix86_vector_mode_supported_p (machine_mode mode)
   24120                 :             : {
   24121                 :             :   /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
   24122                 :             :      either.  */
   24123                 :  1411059111 :   if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
   24124                 :             :     return false;
   24125                 :  1272906661 :   if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   24126                 :             :     return true;
   24127                 :  1072182324 :   if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   24128                 :             :     return true;
   24129                 :   482367222 :   if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   24130                 :             :     return true;
   24131                 :   330492249 :   if (TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
   24132                 :             :     return true;
   24133                 :   206952955 :   if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   24134                 :   206898359 :       && VALID_MMX_REG_MODE (mode))
   24135                 :             :     return true;
   24136                 :    27204807 :   if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
   24137                 :    26602679 :       && VALID_MMX_REG_MODE_3DNOW (mode))
   24138                 :             :     return true;
   24139                 :    18357305 :   if (mode == V2QImode)
   24140                 :       17908 :     return true;
   24141                 :             :   return false;
   24142                 :             : }
   24143                 :             : 
   24144                 :             : /* Target hook for c_mode_for_suffix.  */
   24145                 :             : static machine_mode
   24146                 :       77771 : ix86_c_mode_for_suffix (char suffix)
   24147                 :             : {
   24148                 :       77771 :   if (suffix == 'q')
   24149                 :             :     return TFmode;
   24150                 :          36 :   if (suffix == 'w')
   24151                 :             :     return XFmode;
   24152                 :             : 
   24153                 :           0 :   return VOIDmode;
   24154                 :             : }
   24155                 :             : 
   24156                 :             : /* Helper function to map common constraints to non-EGPR ones.
   24157                 :             :    All related constraints have h prefix, and h plus Upper letter
   24158                 :             :    means the constraint is strictly EGPR enabled, while h plus
   24159                 :             :    lower letter indicates the constraint is strictly gpr16 only.
   24160                 :             : 
   24161                 :             :    Specially for "g" constraint, split it to rmi as there is
   24162                 :             :    no corresponding general constraint define for backend.
   24163                 :             : 
   24164                 :             :    Here is the full list to map constraints that may involve
   24165                 :             :    gpr to h prefixed.
   24166                 :             : 
   24167                 :             :    "g" -> "jrjmi"
   24168                 :             :    "r" -> "jr"
   24169                 :             :    "m" -> "jm"
   24170                 :             :    "<" -> "j<"
   24171                 :             :    ">" -> "j>"
   24172                 :             :    "o" -> "jo"
   24173                 :             :    "V" -> "jV"
   24174                 :             :    "p" -> "jp"
   24175                 :             :    "Bm" -> "ja"
   24176                 :             : */
   24177                 :             : 
   24178                 :          45 : static void map_egpr_constraints (vec<const char *> &constraints)
   24179                 :             : {
   24180                 :          55 :   for (size_t i = 0; i < constraints.length(); i++)
   24181                 :             :     {
   24182                 :          10 :       const char *cur = constraints[i];
   24183                 :             : 
   24184                 :          10 :       if (startswith (cur, "=@cc"))
   24185                 :           0 :         continue;
   24186                 :             : 
   24187                 :          10 :       int len = strlen (cur);
   24188                 :          10 :       auto_vec<char> buf;
   24189                 :             : 
   24190                 :          24 :       for (int j = 0; j < len; j++)
   24191                 :             :         {
   24192                 :          14 :           switch (cur[j])
   24193                 :             :             {
   24194                 :           2 :             case 'g':
   24195                 :           2 :               buf.safe_push ('j');
   24196                 :           2 :               buf.safe_push ('r');
   24197                 :           2 :               buf.safe_push ('j');
   24198                 :           2 :               buf.safe_push ('m');
   24199                 :           2 :               buf.safe_push ('i');
   24200                 :           2 :               break;
   24201                 :           8 :             case 'r':
   24202                 :           8 :             case 'm':
   24203                 :           8 :             case '<':
   24204                 :           8 :             case '>':
   24205                 :           8 :             case 'o':
   24206                 :           8 :             case 'V':
   24207                 :           8 :             case 'p':
   24208                 :           8 :               buf.safe_push ('j');
   24209                 :           8 :               buf.safe_push (cur[j]);
   24210                 :           8 :               break;
   24211                 :           0 :             case 'B':
   24212                 :           0 :               if (cur[j + 1] == 'm')
   24213                 :             :                 {
   24214                 :           0 :                   buf.safe_push ('j');
   24215                 :           0 :                   buf.safe_push ('a');
   24216                 :           0 :                   j++;
   24217                 :             :                 }
   24218                 :             :               else
   24219                 :             :                 {
   24220                 :           0 :                   buf.safe_push (cur[j]);
   24221                 :           0 :                   buf.safe_push (cur[j + 1]);
   24222                 :           0 :                   j++;
   24223                 :             :                 }
   24224                 :             :               break;
   24225                 :           0 :             case 'T':
   24226                 :           0 :             case 'Y':
   24227                 :           0 :             case 'W':
   24228                 :           0 :             case 'j':
   24229                 :           0 :               buf.safe_push (cur[j]);
   24230                 :           0 :               buf.safe_push (cur[j + 1]);
   24231                 :           0 :               j++;
   24232                 :           0 :               break;
   24233                 :           4 :             default:
   24234                 :           4 :               buf.safe_push (cur[j]);
   24235                 :           4 :               break;
   24236                 :             :             }
   24237                 :             :         }
   24238                 :          10 :       buf.safe_push ('\0');
   24239                 :          20 :       constraints[i] = xstrdup (buf.address ());
   24240                 :          10 :     }
   24241                 :          45 : }
   24242                 :             : 
   24243                 :             : /* Worker function for TARGET_MD_ASM_ADJUST.
   24244                 :             : 
   24245                 :             :    We implement asm flag outputs, and maintain source compatibility
   24246                 :             :    with the old cc0-based compiler.  */
   24247                 :             : 
   24248                 :             : static rtx_insn *
   24249                 :      104551 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
   24250                 :             :                     vec<machine_mode> & /*input_modes*/,
   24251                 :             :                     vec<const char *> &constraints, vec<rtx> &/*uses*/,
   24252                 :             :                     vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
   24253                 :             :                     location_t loc)
   24254                 :             : {
   24255                 :      104551 :   bool saw_asm_flag = false;
   24256                 :             : 
   24257                 :      104551 :   start_sequence ();
   24258                 :             : 
   24259                 :      104551 :   if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
   24260                 :          45 :     map_egpr_constraints (constraints);
   24261                 :             : 
   24262                 :      279860 :   for (unsigned i = 0, n = outputs.length (); i < n; ++i)
   24263                 :             :     {
   24264                 :       71689 :       const char *con = constraints[i];
   24265                 :       71689 :       if (!startswith (con, "=@cc"))
   24266                 :       71602 :         continue;
   24267                 :          87 :       con += 4;
   24268                 :          87 :       if (strchr (con, ',') != NULL)
   24269                 :             :         {
   24270                 :           1 :           error_at (loc, "alternatives not allowed in %<asm%> flag output");
   24271                 :           1 :           continue;
   24272                 :             :         }
   24273                 :             : 
   24274                 :          86 :       bool invert = false;
   24275                 :          86 :       if (con[0] == 'n')
   24276                 :          19 :         invert = true, con++;
   24277                 :             : 
   24278                 :          86 :       machine_mode mode = CCmode;
   24279                 :          86 :       rtx_code code = UNKNOWN;
   24280                 :             : 
   24281                 :          86 :       switch (con[0])
   24282                 :             :         {
   24283                 :          15 :         case 'a':
   24284                 :          15 :           if (con[1] == 0)
   24285                 :             :             mode = CCAmode, code = EQ;
   24286                 :           4 :           else if (con[1] == 'e' && con[2] == 0)
   24287                 :             :             mode = CCCmode, code = NE;
   24288                 :             :           break;
   24289                 :          11 :         case 'b':
   24290                 :          11 :           if (con[1] == 0)
   24291                 :             :             mode = CCCmode, code = EQ;
   24292                 :           6 :           else if (con[1] == 'e' && con[2] == 0)
   24293                 :             :             mode = CCAmode, code = NE;
   24294                 :             :           break;
   24295                 :          14 :         case 'c':
   24296                 :          14 :           if (con[1] == 0)
   24297                 :             :             mode = CCCmode, code = EQ;
   24298                 :             :           break;
   24299                 :           8 :         case 'e':
   24300                 :           8 :           if (con[1] == 0)
   24301                 :             :             mode = CCZmode, code = EQ;
   24302                 :             :           break;
   24303                 :          11 :         case 'g':
   24304                 :          11 :           if (con[1] == 0)
   24305                 :             :             mode = CCGCmode, code = GT;
   24306                 :           5 :           else if (con[1] == 'e' && con[2] == 0)
   24307                 :             :             mode = CCGCmode, code = GE;
   24308                 :             :           break;
   24309                 :          10 :         case 'l':
   24310                 :          10 :           if (con[1] == 0)
   24311                 :             :             mode = CCGCmode, code = LT;
   24312                 :           5 :           else if (con[1] == 'e' && con[2] == 0)
   24313                 :             :             mode = CCGCmode, code = LE;
   24314                 :             :           break;
   24315                 :           4 :         case 'o':
   24316                 :           4 :           if (con[1] == 0)
   24317                 :             :             mode = CCOmode, code = EQ;
   24318                 :             :           break;
   24319                 :           4 :         case 'p':
   24320                 :           4 :           if (con[1] == 0)
   24321                 :             :             mode = CCPmode, code = EQ;
   24322                 :             :           break;
   24323                 :           4 :         case 's':
   24324                 :           4 :           if (con[1] == 0)
   24325                 :             :             mode = CCSmode, code = EQ;
   24326                 :             :           break;
   24327                 :           5 :         case 'z':
   24328                 :           5 :           if (con[1] == 0)
   24329                 :             :             mode = CCZmode, code = EQ;
   24330                 :             :           break;
   24331                 :             :         }
   24332                 :           1 :       if (code == UNKNOWN)
   24333                 :             :         {
   24334                 :           1 :           error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
   24335                 :           1 :           continue;
   24336                 :             :         }
   24337                 :          85 :       if (invert)
   24338                 :          19 :         code = reverse_condition (code);
   24339                 :             : 
   24340                 :          85 :       rtx dest = outputs[i];
   24341                 :          85 :       if (!saw_asm_flag)
   24342                 :             :         {
   24343                 :             :           /* This is the first asm flag output.  Here we put the flags
   24344                 :             :              register in as the real output and adjust the condition to
   24345                 :             :              allow it.  */
   24346                 :          74 :           constraints[i] = "=Bf";
   24347                 :          74 :           outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
   24348                 :          74 :           saw_asm_flag = true;
   24349                 :             :         }
   24350                 :             :       else
   24351                 :             :         {
   24352                 :             :           /* We don't need the flags register as output twice.  */
   24353                 :          11 :           constraints[i] = "=X";
   24354                 :          11 :           outputs[i] = gen_rtx_SCRATCH (SImode);
   24355                 :             :         }
   24356                 :             : 
   24357                 :          85 :       rtx x = gen_rtx_REG (mode, FLAGS_REG);
   24358                 :          85 :       x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
   24359                 :             : 
   24360                 :          85 :       machine_mode dest_mode = GET_MODE (dest);
   24361                 :          85 :       if (!SCALAR_INT_MODE_P (dest_mode))
   24362                 :             :         {
   24363                 :           3 :           error_at (loc, "invalid type for %<asm%> flag output");
   24364                 :           3 :           continue;
   24365                 :             :         }
   24366                 :             : 
   24367                 :          82 :       if (dest_mode == QImode)
   24368                 :          72 :         emit_insn (gen_rtx_SET (dest, x));
   24369                 :             :       else
   24370                 :             :         {
   24371                 :          10 :           rtx reg = gen_reg_rtx (QImode);
   24372                 :          10 :           emit_insn (gen_rtx_SET (reg, x));
   24373                 :             : 
   24374                 :          10 :           reg = convert_to_mode (dest_mode, reg, 1);
   24375                 :          10 :           emit_move_insn (dest, reg);
   24376                 :             :         }
   24377                 :             :     }
   24378                 :             : 
   24379                 :      104551 :   rtx_insn *seq = get_insns ();
   24380                 :      104551 :   end_sequence ();
   24381                 :             : 
   24382                 :      104551 :   if (saw_asm_flag)
   24383                 :             :     return seq;
   24384                 :             :   else
   24385                 :             :     {
   24386                 :             :       /* If we had no asm flag outputs, clobber the flags.  */
   24387                 :      104477 :       clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
   24388                 :      104477 :       SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
   24389                 :      104477 :       return NULL;
   24390                 :             :     }
   24391                 :             : }
   24392                 :             : 
   24393                 :             : /* Implements target vector targetm.asm.encode_section_info.  */
   24394                 :             : 
   24395                 :             : static void ATTRIBUTE_UNUSED
   24396                 :     9723073 : ix86_encode_section_info (tree decl, rtx rtl, int first)
   24397                 :             : {
   24398                 :     9723073 :   default_encode_section_info (decl, rtl, first);
   24399                 :             : 
   24400                 :     9723073 :   if (ix86_in_large_data_p (decl))
   24401                 :          32 :     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
   24402                 :     9723073 : }
   24403                 :             : 
   24404                 :             : /* Worker function for REVERSE_CONDITION.  */
   24405                 :             : 
   24406                 :             : enum rtx_code
   24407                 :    29232369 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
   24408                 :             : {
   24409                 :    29232369 :   return (mode == CCFPmode
   24410                 :    29232369 :           ? reverse_condition_maybe_unordered (code)
   24411                 :    25032847 :           : reverse_condition (code));
   24412                 :             : }
   24413                 :             : 
   24414                 :             : /* Output code to perform an x87 FP register move, from OPERANDS[1]
   24415                 :             :    to OPERANDS[0].  */
   24416                 :             : 
   24417                 :             : const char *
   24418                 :      654682 : output_387_reg_move (rtx_insn *insn, rtx *operands)
   24419                 :             : {
   24420                 :      654682 :   if (REG_P (operands[0]))
   24421                 :             :     {
   24422                 :      550640 :       if (REG_P (operands[1])
   24423                 :      550640 :           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   24424                 :             :         {
   24425                 :      301658 :           if (REGNO (operands[0]) == FIRST_STACK_REG)
   24426                 :      281030 :             return output_387_ffreep (operands, 0);
   24427                 :             :           return "fstp\t%y0";
   24428                 :             :         }
   24429                 :      248982 :       if (STACK_TOP_P (operands[0]))
   24430                 :      248982 :         return "fld%Z1\t%y1";
   24431                 :             :       return "fst\t%y0";
   24432                 :             :     }
   24433                 :      104042 :   else if (MEM_P (operands[0]))
   24434                 :             :     {
   24435                 :      104042 :       gcc_assert (REG_P (operands[1]));
   24436                 :      104042 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   24437                 :             :         return "fstp%Z0\t%y0";
   24438                 :             :       else
   24439                 :             :         {
   24440                 :             :           /* There is no non-popping store to memory for XFmode.
   24441                 :             :              So if we need one, follow the store with a load.  */
   24442                 :        5561 :           if (GET_MODE (operands[0]) == XFmode)
   24443                 :             :             return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
   24444                 :             :           else
   24445                 :        1702 :             return "fst%Z0\t%y0";
   24446                 :             :         }
   24447                 :             :     }
   24448                 :             :   else
   24449                 :           0 :     gcc_unreachable();
   24450                 :             : }
   24451                 :             : #ifdef TARGET_SOLARIS
   24452                 :             : /* Solaris implementation of TARGET_ASM_NAMED_SECTION.  */
   24453                 :             : 
   24454                 :             : static void
   24455                 :             : i386_solaris_elf_named_section (const char *name, unsigned int flags,
   24456                 :             :                                 tree decl)
   24457                 :             : {
   24458                 :             :   /* With Binutils 2.15, the "@unwind" marker must be specified on
   24459                 :             :      every occurrence of the ".eh_frame" section, not just the first
   24460                 :             :      one.  */
   24461                 :             :   if (TARGET_64BIT
   24462                 :             :       && strcmp (name, ".eh_frame") == 0)
   24463                 :             :     {
   24464                 :             :       fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
   24465                 :             :                flags & SECTION_WRITE ? "aw" : "a");
   24466                 :             :       return;
   24467                 :             :     }
   24468                 :             : 
   24469                 :             : #ifndef USE_GAS
   24470                 :             :   if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
   24471                 :             :     {
   24472                 :             :       solaris_elf_asm_comdat_section (name, flags, decl);
   24473                 :             :       return;
   24474                 :             :     }
   24475                 :             : 
   24476                 :             :   /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
   24477                 :             :      SPARC assembler.  One cannot mix single-letter flags and #exclude, so
   24478                 :             :      only emit the latter here.  */
   24479                 :             :   if (flags & SECTION_EXCLUDE)
   24480                 :             :     {
   24481                 :             :       fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
   24482                 :             :       return;
   24483                 :             :     }
   24484                 :             : #endif
   24485                 :             : 
   24486                 :             :   default_elf_asm_named_section (name, flags, decl);
   24487                 :             : }
   24488                 :             : #endif /* TARGET_SOLARIS */
   24489                 :             : 
   24490                 :             : /* Return the mangling of TYPE if it is an extended fundamental type.  */
   24491                 :             : 
   24492                 :             : static const char *
   24493                 :   599210114 : ix86_mangle_type (const_tree type)
   24494                 :             : {
   24495                 :   599210114 :   type = TYPE_MAIN_VARIANT (type);
   24496                 :             : 
   24497                 :   599210114 :   if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
   24498                 :             :       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
   24499                 :             :     return NULL;
   24500                 :             : 
   24501                 :   318834200 :   if (type == float128_type_node || type == float64x_type_node)
   24502                 :             :     return NULL;
   24503                 :             : 
   24504                 :   317998183 :   switch (TYPE_MODE (type))
   24505                 :             :     {
   24506                 :             :     case E_BFmode:
   24507                 :             :       return "DF16b";
   24508                 :      311930 :     case E_HFmode:
   24509                 :             :       /* _Float16 is "DF16_".
   24510                 :             :          Align with clang's decision in https://reviews.llvm.org/D33719. */
   24511                 :      311930 :       return "DF16_";
   24512                 :      384881 :     case E_TFmode:
   24513                 :             :       /* __float128 is "g".  */
   24514                 :      384881 :       return "g";
   24515                 :     5650743 :     case E_XFmode:
   24516                 :             :       /* "long double" or __float80 is "e".  */
   24517                 :     5650743 :       return "e";
   24518                 :             :     default:
   24519                 :             :       return NULL;
   24520                 :             :     }
   24521                 :             : }
   24522                 :             : 
   24523                 :             : /* Create C++ tinfo symbols for only conditionally available fundamental
   24524                 :             :    types.  */
   24525                 :             : 
   24526                 :             : static void
   24527                 :           5 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
   24528                 :             : {
   24529                 :           5 :   extern tree ix86_float16_type_node;
   24530                 :           5 :   extern tree ix86_bf16_type_node;
   24531                 :             : 
   24532                 :           5 :   if (!TARGET_SSE2)
   24533                 :             :     {
   24534                 :           0 :       if (!float16_type_node)
   24535                 :           0 :         float16_type_node = ix86_float16_type_node;
   24536                 :           0 :       if (!bfloat16_type_node)
   24537                 :           0 :         bfloat16_type_node = ix86_bf16_type_node;
   24538                 :           0 :       callback (float16_type_node);
   24539                 :           0 :       callback (bfloat16_type_node);
   24540                 :           0 :       float16_type_node = NULL_TREE;
   24541                 :           0 :       bfloat16_type_node = NULL_TREE;
   24542                 :             :     }
   24543                 :           5 : }
   24544                 :             : 
   24545                 :             : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
   24546                 :             : 
   24547                 :             : static tree
   24548                 :         226 : ix86_stack_protect_guard (void)
   24549                 :             : {
   24550                 :         226 :   if (TARGET_SSP_TLS_GUARD)
   24551                 :             :     {
   24552                 :         223 :       tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
   24553                 :         223 :       int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
   24554                 :         223 :       tree type = build_qualified_type (type_node, qual);
   24555                 :         223 :       tree t;
   24556                 :             : 
   24557                 :         223 :       if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
   24558                 :             :         {
   24559                 :           1 :           t = ix86_tls_stack_chk_guard_decl;
   24560                 :             : 
   24561                 :           1 :           if (t == NULL)
   24562                 :             :             {
   24563                 :           1 :               rtx x;
   24564                 :             : 
   24565                 :           1 :               t = build_decl
   24566                 :           1 :                 (UNKNOWN_LOCATION, VAR_DECL,
   24567                 :             :                  get_identifier (ix86_stack_protector_guard_symbol_str),
   24568                 :             :                  type);
   24569                 :           1 :               TREE_STATIC (t) = 1;
   24570                 :           1 :               TREE_PUBLIC (t) = 1;
   24571                 :           1 :               DECL_EXTERNAL (t) = 1;
   24572                 :           1 :               TREE_USED (t) = 1;
   24573                 :           1 :               TREE_THIS_VOLATILE (t) = 1;
   24574                 :           1 :               DECL_ARTIFICIAL (t) = 1;
   24575                 :           1 :               DECL_IGNORED_P (t) = 1;
   24576                 :             : 
   24577                 :             :               /* Do not share RTL as the declaration is visible outside of
   24578                 :             :                  current function.  */
   24579                 :           1 :               x = DECL_RTL (t);
   24580                 :           1 :               RTX_FLAG (x, used) = 1;
   24581                 :             : 
   24582                 :           1 :               ix86_tls_stack_chk_guard_decl = t;
   24583                 :             :             }
   24584                 :             :         }
   24585                 :             :       else
   24586                 :             :         {
   24587                 :         222 :           tree asptrtype = build_pointer_type (type);
   24588                 :             : 
   24589                 :         222 :           t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
   24590                 :         222 :           t = build2 (MEM_REF, asptrtype, t,
   24591                 :         222 :                       build_int_cst (asptrtype, 0));
   24592                 :         222 :           TREE_THIS_VOLATILE (t) = 1;
   24593                 :             :         }
   24594                 :             : 
   24595                 :         223 :       return t;
   24596                 :             :     }
   24597                 :             : 
   24598                 :           3 :   return default_stack_protect_guard ();
   24599                 :             : }
   24600                 :             : 
   24601                 :             : static bool
   24602                 :         691 : ix86_stack_protect_runtime_enabled_p (void)
   24603                 :             : {
   24604                 :             :   /* Naked functions should not enable stack protector.  */
   24605                 :         691 :   return !ix86_function_naked (current_function_decl);
   24606                 :             : }
   24607                 :             : 
   24608                 :             : /* For 32-bit code we can save PIC register setup by using
   24609                 :             :    __stack_chk_fail_local hidden function instead of calling
   24610                 :             :    __stack_chk_fail directly.  64-bit code doesn't need to setup any PIC
   24611                 :             :    register, so it is better to call __stack_chk_fail directly.  */
   24612                 :             : 
   24613                 :             : static tree ATTRIBUTE_UNUSED
   24614                 :         236 : ix86_stack_protect_fail (void)
   24615                 :             : {
   24616                 :         236 :   return TARGET_64BIT
   24617                 :         236 :          ? default_external_stack_protect_fail ()
   24618                 :           1 :          : default_hidden_stack_protect_fail ();
   24619                 :             : }
   24620                 :             : 
   24621                 :             : /* Select a format to encode pointers in exception handling data.  CODE
   24622                 :             :    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
   24623                 :             :    true if the symbol may be affected by dynamic relocations.
   24624                 :             : 
   24625                 :             :    ??? All x86 object file formats are capable of representing this.
   24626                 :             :    After all, the relocation needed is the same as for the call insn.
   24627                 :             :    Whether or not a particular assembler allows us to enter such, I
   24628                 :             :    guess we'll have to see.  */
   24629                 :             : 
   24630                 :             : int
   24631                 :      759639 : asm_preferred_eh_data_format (int code, int global)
   24632                 :             : {
   24633                 :             :   /* PE-COFF is effectively always -fPIC because of the .reloc section.  */
   24634                 :      759639 :   if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
   24635                 :             :     {
   24636                 :       37262 :       int type = DW_EH_PE_sdata8;
   24637                 :       37262 :       if (ptr_mode == SImode
   24638                 :       23551 :           || ix86_cmodel == CM_SMALL_PIC
   24639                 :       37328 :           || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
   24640                 :             :         type = DW_EH_PE_sdata4;
   24641                 :       52235 :       return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
   24642                 :             :     }
   24643                 :             : 
   24644                 :      722377 :   if (ix86_cmodel == CM_SMALL
   24645                 :       18686 :       || (ix86_cmodel == CM_MEDIUM && code))
   24646                 :      703702 :     return DW_EH_PE_udata4;
   24647                 :             : 
   24648                 :             :   return DW_EH_PE_absptr;
   24649                 :             : }
   24650                 :             : 
   24651                 :             : /* Implement targetm.vectorize.builtin_vectorization_cost.  */
   24652                 :             : static int
   24653                 :    14602058 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
   24654                 :             :                                  tree vectype, int)
   24655                 :             : {
   24656                 :    14602058 :   bool fp = false;
   24657                 :    14602058 :   machine_mode mode = TImode;
   24658                 :    14602058 :   int index;
   24659                 :    14602058 :   if (vectype != NULL)
   24660                 :             :     {
   24661                 :    13720863 :       fp = FLOAT_TYPE_P (vectype);
   24662                 :    13720863 :       mode = TYPE_MODE (vectype);
   24663                 :             :     }
   24664                 :             : 
   24665                 :    14602058 :   switch (type_of_cost)
   24666                 :             :     {
   24667                 :     2558140 :       case scalar_stmt:
   24668                 :     2558140 :         return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
   24669                 :             : 
   24670                 :     1770514 :       case scalar_load:
   24671                 :             :         /* load/store costs are relative to register move which is 2. Recompute
   24672                 :             :            it to COSTS_N_INSNS so everything have same base.  */
   24673                 :     3541028 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
   24674                 :     1770514 :                               : ix86_cost->int_load [2]) / 2;
   24675                 :             : 
   24676                 :     3562303 :       case scalar_store:
   24677                 :     7124606 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
   24678                 :     3562303 :                               : ix86_cost->int_store [2]) / 2;
   24679                 :             : 
   24680                 :      942989 :       case vector_stmt:
   24681                 :     1885978 :         return ix86_vec_cost (mode,
   24682                 :     1885978 :                               fp ? ix86_cost->addss : ix86_cost->sse_op);
   24683                 :             : 
   24684                 :     1675779 :       case vector_load:
   24685                 :     1675779 :         index = sse_store_index (mode);
   24686                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24687                 :     1675779 :         if (index < 0)
   24688                 :       89467 :           index = 2;
   24689                 :     1675779 :         return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
   24690                 :             : 
   24691                 :      937548 :       case vector_store:
   24692                 :      937548 :         index = sse_store_index (mode);
   24693                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24694                 :      937548 :         if (index < 0)
   24695                 :       86908 :           index = 2;
   24696                 :      937548 :         return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
   24697                 :             : 
   24698                 :      902133 :       case vec_to_scalar:
   24699                 :      902133 :       case scalar_to_vec:
   24700                 :      902133 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   24701                 :             : 
   24702                 :             :       /* We should have separate costs for unaligned loads and gather/scatter.
   24703                 :             :          Do that incrementally.  */
   24704                 :      389162 :       case unaligned_load:
   24705                 :      389162 :         index = sse_store_index (mode);
   24706                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24707                 :      389162 :         if (index < 0)
   24708                 :        2764 :           index = 2;
   24709                 :      389162 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
   24710                 :             : 
   24711                 :      737067 :       case unaligned_store:
   24712                 :      737067 :         index = sse_store_index (mode);
   24713                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24714                 :      737067 :         if (index < 0)
   24715                 :       13432 :           index = 2;
   24716                 :      737067 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
   24717                 :             : 
   24718                 :           0 :       case vector_gather_load:
   24719                 :           0 :         return ix86_vec_cost (mode,
   24720                 :           0 :                               COSTS_N_INSNS
   24721                 :             :                                  (ix86_cost->gather_static
   24722                 :             :                                   + ix86_cost->gather_per_elt
   24723                 :           0 :                                     * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
   24724                 :             : 
   24725                 :           0 :       case vector_scatter_store:
   24726                 :           0 :         return ix86_vec_cost (mode,
   24727                 :           0 :                               COSTS_N_INSNS
   24728                 :             :                                  (ix86_cost->scatter_static
   24729                 :             :                                   + ix86_cost->scatter_per_elt
   24730                 :           0 :                                     * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
   24731                 :             : 
   24732                 :      229685 :       case cond_branch_taken:
   24733                 :      229685 :         return ix86_cost->cond_taken_branch_cost;
   24734                 :             : 
   24735                 :        4803 :       case cond_branch_not_taken:
   24736                 :        4803 :         return ix86_cost->cond_not_taken_branch_cost;
   24737                 :             : 
   24738                 :      323881 :       case vec_perm:
   24739                 :      323881 :       case vec_promote_demote:
   24740                 :      323881 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   24741                 :             : 
   24742                 :      568054 :       case vec_construct:
   24743                 :      568054 :         {
   24744                 :      568054 :           int n = TYPE_VECTOR_SUBPARTS (vectype);
   24745                 :             :           /* N - 1 element inserts into an SSE vector, the possible
   24746                 :             :              GPR -> XMM move is accounted for in add_stmt_cost.  */
   24747                 :     1136108 :           if (GET_MODE_BITSIZE (mode) <= 128)
   24748                 :      559634 :             return (n - 1) * ix86_cost->sse_op;
   24749                 :             :           /* One vinserti128 for combining two SSE vectors for AVX256.  */
   24750                 :       16840 :           else if (GET_MODE_BITSIZE (mode) == 256)
   24751                 :        6478 :             return ((n - 2) * ix86_cost->sse_op
   24752                 :        6478 :                     + ix86_vec_cost (mode, ix86_cost->addss));
   24753                 :             :           /* One vinserti64x4 and two vinserti128 for combining SSE
   24754                 :             :              and AVX256 vectors to AVX512.  */
   24755                 :        3884 :           else if (GET_MODE_BITSIZE (mode) == 512)
   24756                 :        1942 :             return ((n - 4) * ix86_cost->sse_op
   24757                 :        1942 :                     + 3 * ix86_vec_cost (mode, ix86_cost->addss));
   24758                 :           0 :           gcc_unreachable ();
   24759                 :             :         }
   24760                 :             : 
   24761                 :           0 :       default:
   24762                 :           0 :         gcc_unreachable ();
   24763                 :             :     }
   24764                 :             : }
   24765                 :             : 
   24766                 :             : 
   24767                 :             : /* This function returns the calling abi specific va_list type node.
   24768                 :             :    It returns  the FNDECL specific va_list type.  */
   24769                 :             : 
   24770                 :             : static tree
   24771                 :       46303 : ix86_fn_abi_va_list (tree fndecl)
   24772                 :             : {
   24773                 :       46303 :   if (!TARGET_64BIT)
   24774                 :         698 :     return va_list_type_node;
   24775                 :       45605 :   gcc_assert (fndecl != NULL_TREE);
   24776                 :             : 
   24777                 :       45605 :   if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
   24778                 :       12868 :     return ms_va_list_type_node;
   24779                 :             :   else
   24780                 :       32737 :     return sysv_va_list_type_node;
   24781                 :             : }
   24782                 :             : 
   24783                 :             : /* Returns the canonical va_list type specified by TYPE. If there
   24784                 :             :    is no valid TYPE provided, it return NULL_TREE.  */
   24785                 :             : 
   24786                 :             : static tree
   24787                 :      245085 : ix86_canonical_va_list_type (tree type)
   24788                 :             : {
   24789                 :      245085 :   if (TARGET_64BIT)
   24790                 :             :     {
   24791                 :      244583 :       if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
   24792                 :        5944 :         return ms_va_list_type_node;
   24793                 :             : 
   24794                 :      238639 :       if ((TREE_CODE (type) == ARRAY_TYPE
   24795                 :       49764 :            && integer_zerop (array_type_nelts_minus_one (type)))
   24796                 :      238639 :           || POINTER_TYPE_P (type))
   24797                 :             :         {
   24798                 :      187182 :           tree elem_type = TREE_TYPE (type);
   24799                 :      187182 :           if (TREE_CODE (elem_type) == RECORD_TYPE
   24800                 :      338094 :               && lookup_attribute ("sysv_abi va_list",
   24801                 :      150912 :                                    TYPE_ATTRIBUTES (elem_type)))
   24802                 :      150912 :             return sysv_va_list_type_node;
   24803                 :             :         }
   24804                 :             : 
   24805                 :       87727 :       return NULL_TREE;
   24806                 :             :     }
   24807                 :             : 
   24808                 :         502 :   return std_canonical_va_list_type (type);
   24809                 :             : }
   24810                 :             : 
   24811                 :             : /* Iterate through the target-specific builtin types for va_list.
   24812                 :             :    IDX denotes the iterator, *PTREE is set to the result type of
   24813                 :             :    the va_list builtin, and *PNAME to its internal type.
   24814                 :             :    Returns zero if there is no element for this index, otherwise
   24815                 :             :    IDX should be increased upon the next call.
   24816                 :             :    Note, do not iterate a base builtin's name like __builtin_va_list.
   24817                 :             :    Used from c_common_nodes_and_builtins.  */
   24818                 :             : 
   24819                 :             : static int
   24820                 :      602402 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
   24821                 :             : {
   24822                 :      602402 :   if (TARGET_64BIT)
   24823                 :             :     {
   24824                 :      597123 :       switch (idx)
   24825                 :             :         {
   24826                 :             :         default:
   24827                 :             :           break;
   24828                 :             : 
   24829                 :      199041 :         case 0:
   24830                 :      199041 :           *ptree = ms_va_list_type_node;
   24831                 :      199041 :           *pname = "__builtin_ms_va_list";
   24832                 :      199041 :           return 1;
   24833                 :             : 
   24834                 :      199041 :         case 1:
   24835                 :      199041 :           *ptree = sysv_va_list_type_node;
   24836                 :      199041 :           *pname = "__builtin_sysv_va_list";
   24837                 :      199041 :           return 1;
   24838                 :             :         }
   24839                 :             :     }
   24840                 :             : 
   24841                 :             :   return 0;
   24842                 :             : }
   24843                 :             : 
   24844                 :             : #undef TARGET_SCHED_DISPATCH
   24845                 :             : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
   24846                 :             : #undef TARGET_SCHED_DISPATCH_DO
   24847                 :             : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
   24848                 :             : #undef TARGET_SCHED_REASSOCIATION_WIDTH
   24849                 :             : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
   24850                 :             : #undef TARGET_SCHED_REORDER
   24851                 :             : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
   24852                 :             : #undef TARGET_SCHED_ADJUST_PRIORITY
   24853                 :             : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
   24854                 :             : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
   24855                 :             : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
   24856                 :             :   ix86_dependencies_evaluation_hook
   24857                 :             : 
   24858                 :             : 
   24859                 :             : /* Implementation of reassociation_width target hook used by
   24860                 :             :    reassoc phase to identify parallelism level in reassociated
   24861                 :             :    tree.  Statements tree_code is passed in OPC.  Arguments type
   24862                 :             :    is passed in MODE.  */
   24863                 :             : 
   24864                 :             : static int
   24865                 :       31311 : ix86_reassociation_width (unsigned int op, machine_mode mode)
   24866                 :             : {
   24867                 :       31311 :   int width = 1;
   24868                 :             :   /* Vector part.  */
   24869                 :       31311 :   if (VECTOR_MODE_P (mode))
   24870                 :             :     {
   24871                 :        7465 :       int div = 1;
   24872                 :        7465 :       if (INTEGRAL_MODE_P (mode))
   24873                 :        2254 :         width = ix86_cost->reassoc_vec_int;
   24874                 :        5211 :       else if (FLOAT_MODE_P (mode))
   24875                 :        5211 :         width = ix86_cost->reassoc_vec_fp;
   24876                 :             : 
   24877                 :        7465 :       if (width == 1)
   24878                 :             :         return 1;
   24879                 :             : 
   24880                 :             :       /* Znver1-4 Integer vector instructions execute in FP unit
   24881                 :             :          and can execute 3 additions and one multiplication per cycle.  */
   24882                 :        7460 :       if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
   24883                 :        7460 :            || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4)
   24884                 :           0 :           && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
   24885                 :             :         return 1;
   24886                 :             :       /* Znver5 can do 2 integer multiplications per cycle with latency
   24887                 :             :          of 3.  */
   24888                 :        7460 :       if (ix86_tune == PROCESSOR_ZNVER5
   24889                 :           0 :           && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
   24890                 :        7460 :         width = 6;
   24891                 :             : 
   24892                 :             :       /* Account for targets that splits wide vectors into multiple parts.  */
   24893                 :        7460 :       if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
   24894                 :           0 :         div = GET_MODE_BITSIZE (mode) / 256;
   24895                 :        7460 :       else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
   24896                 :           0 :         div = GET_MODE_BITSIZE (mode) / 128;
   24897                 :        7460 :       else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
   24898                 :           0 :         div = GET_MODE_BITSIZE (mode) / 64;
   24899                 :        7460 :       width = (width + div - 1) / div;
   24900                 :        7460 :     }
   24901                 :             :   /* Scalar part.  */
   24902                 :             :   else if (INTEGRAL_MODE_P (mode))
   24903                 :       14181 :     width = ix86_cost->reassoc_int;
   24904                 :             :   else if (FLOAT_MODE_P (mode))
   24905                 :        9665 :     width = ix86_cost->reassoc_fp;
   24906                 :             : 
   24907                 :             :   /* Avoid using too many registers in 32bit mode.  */
   24908                 :       31306 :   if (!TARGET_64BIT && width > 2)
   24909                 :       31311 :     width = 2;
   24910                 :             :   return width;
   24911                 :             : }
   24912                 :             : 
   24913                 :             : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
   24914                 :             :    place emms and femms instructions.  */
   24915                 :             : 
   24916                 :             : static machine_mode
   24917                 :     4734441 : ix86_preferred_simd_mode (scalar_mode mode)
   24918                 :             : {
   24919                 :     4734441 :   if (!TARGET_SSE)
   24920                 :         800 :     return word_mode;
   24921                 :             : 
   24922                 :     4733641 :   switch (mode)
   24923                 :             :     {
   24924                 :      357704 :     case E_QImode:
   24925                 :      357704 :       if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24926                 :             :         return V64QImode;
   24927                 :      350894 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24928                 :             :         return V32QImode;
   24929                 :             :       else
   24930                 :      331724 :         return V16QImode;
   24931                 :             : 
   24932                 :      175277 :     case E_HImode:
   24933                 :      175277 :       if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24934                 :             :         return V32HImode;
   24935                 :      166602 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24936                 :             :         return V16HImode;
   24937                 :             :       else
   24938                 :      150922 :         return V8HImode;
   24939                 :             : 
   24940                 :     1439075 :     case E_SImode:
   24941                 :     1439075 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24942                 :             :         return V16SImode;
   24943                 :     1374648 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24944                 :             :         return V8SImode;
   24945                 :             :       else
   24946                 :     1225948 :         return V4SImode;
   24947                 :             : 
   24948                 :     1693541 :     case E_DImode:
   24949                 :     1693541 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24950                 :             :         return V8DImode;
   24951                 :     1339653 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24952                 :             :         return V4DImode;
   24953                 :             :       else
   24954                 :     1239204 :         return V2DImode;
   24955                 :             : 
   24956                 :      146383 :     case E_HFmode:
   24957                 :      146383 :       if (TARGET_AVX512FP16)
   24958                 :             :         {
   24959                 :      145849 :           if (TARGET_AVX512VL)
   24960                 :             :             {
   24961                 :       73286 :               if (TARGET_PREFER_AVX128)
   24962                 :             :                 return V8HFmode;
   24963                 :       73064 :               else if (TARGET_PREFER_AVX256 || !TARGET_EVEX512)
   24964                 :             :                 return V16HFmode;
   24965                 :             :             }
   24966                 :      132495 :           if (TARGET_EVEX512)
   24967                 :             :             return V32HFmode;
   24968                 :             :         }
   24969                 :        4400 :       return word_mode;
   24970                 :             : 
   24971                 :       56717 :     case E_BFmode:
   24972                 :       56717 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24973                 :             :         return V32BFmode;
   24974                 :       31427 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24975                 :             :         return V16BFmode;
   24976                 :             :       else
   24977                 :       13390 :         return V8BFmode;
   24978                 :             : 
   24979                 :      583498 :     case E_SFmode:
   24980                 :      583498 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24981                 :             :         return V16SFmode;
   24982                 :      400646 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24983                 :             :         return V8SFmode;
   24984                 :             :       else
   24985                 :      326830 :         return V4SFmode;
   24986                 :             : 
   24987                 :      259249 :     case E_DFmode:
   24988                 :      259249 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24989                 :             :         return V8DFmode;
   24990                 :      147132 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24991                 :             :         return V4DFmode;
   24992                 :       88718 :       else if (TARGET_SSE2)
   24993                 :             :         return V2DFmode;
   24994                 :             :       /* FALLTHRU */
   24995                 :             : 
   24996                 :       22253 :     default:
   24997                 :       22253 :       return word_mode;
   24998                 :             :     }
   24999                 :             : }
   25000                 :             : 
   25001                 :             : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
   25002                 :             :    vectors.  If AVX512F is enabled then try vectorizing with 512bit,
   25003                 :             :    256bit and 128bit vectors.  */
   25004                 :             : 
   25005                 :             : static unsigned int
   25006                 :     2256096 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
   25007                 :             : {
   25008                 :     2256096 :   if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   25009                 :             :     {
   25010                 :       70516 :       modes->safe_push (V64QImode);
   25011                 :       70516 :       modes->safe_push (V32QImode);
   25012                 :       70516 :       modes->safe_push (V16QImode);
   25013                 :             :     }
   25014                 :     2185580 :   else if (TARGET_AVX512F && TARGET_EVEX512 && all)
   25015                 :             :     {
   25016                 :         550 :       modes->safe_push (V32QImode);
   25017                 :         550 :       modes->safe_push (V16QImode);
   25018                 :         550 :       modes->safe_push (V64QImode);
   25019                 :             :     }
   25020                 :     2185030 :   else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   25021                 :             :     {
   25022                 :       31264 :       modes->safe_push (V32QImode);
   25023                 :       31264 :       modes->safe_push (V16QImode);
   25024                 :             :     }
   25025                 :     2153766 :   else if (TARGET_AVX && all)
   25026                 :             :     {
   25027                 :          24 :       modes->safe_push (V16QImode);
   25028                 :          24 :       modes->safe_push (V32QImode);
   25029                 :             :     }
   25030                 :     2153742 :   else if (TARGET_SSE2)
   25031                 :     2151518 :     modes->safe_push (V16QImode);
   25032                 :             : 
   25033                 :     2256096 :   if (TARGET_MMX_WITH_SSE)
   25034                 :     1786445 :     modes->safe_push (V8QImode);
   25035                 :             : 
   25036                 :     2256096 :   if (TARGET_SSE2)
   25037                 :     2253872 :     modes->safe_push (V4QImode);
   25038                 :             : 
   25039                 :     2256096 :   return 0;
   25040                 :             : }
   25041                 :             : 
   25042                 :             : /* Implemenation of targetm.vectorize.get_mask_mode.  */
   25043                 :             : 
   25044                 :             : static opt_machine_mode
   25045                 :     1785480 : ix86_get_mask_mode (machine_mode data_mode)
   25046                 :             : {
   25047                 :     1785480 :   unsigned vector_size = GET_MODE_SIZE (data_mode);
   25048                 :     1785480 :   unsigned nunits = GET_MODE_NUNITS (data_mode);
   25049                 :     1785480 :   unsigned elem_size = vector_size / nunits;
   25050                 :             : 
   25051                 :             :   /* Scalar mask case.  */
   25052                 :      130490 :   if ((TARGET_AVX512F && TARGET_EVEX512 && vector_size == 64)
   25053                 :     1761252 :       || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
   25054                 :             :       /* AVX512FP16 only supports vector comparison
   25055                 :             :          to kmask for _Float16.  */
   25056                 :     1716132 :       || (TARGET_AVX512VL && TARGET_AVX512FP16
   25057                 :         345 :           && GET_MODE_INNER (data_mode) == E_HFmode)
   25058                 :     3501601 :       || (TARGET_AVX10_2_256 && GET_MODE_INNER (data_mode) == E_BFmode))
   25059                 :             :     {
   25060                 :       69445 :       if (elem_size == 4
   25061                 :       69445 :           || elem_size == 8
   25062                 :       23483 :           || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
   25063                 :       61356 :         return smallest_int_mode_for_size (nunits).require ();
   25064                 :             :     }
   25065                 :             : 
   25066                 :     1724124 :   scalar_int_mode elem_mode
   25067                 :     1724124 :     = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT).require ();
   25068                 :             : 
   25069                 :     1724124 :   gcc_assert (elem_size * nunits == vector_size);
   25070                 :             : 
   25071                 :     1724124 :   return mode_for_vector (elem_mode, nunits);
   25072                 :             : }
   25073                 :             : 
   25074                 :             : 
   25075                 :             : 
   25076                 :             : /* Return class of registers which could be used for pseudo of MODE
   25077                 :             :    and of class RCLASS for spilling instead of memory.  Return NO_REGS
   25078                 :             :    if it is not possible or non-profitable.  */
   25079                 :             : 
   25080                 :             : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   25081                 :             : 
   25082                 :             : static reg_class_t
   25083                 :  6334720211 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
   25084                 :             : {
   25085                 :  6334720211 :   if (0 && TARGET_GENERAL_REGS_SSE_SPILL
   25086                 :             :       && TARGET_SSE2
   25087                 :             :       && TARGET_INTER_UNIT_MOVES_TO_VEC
   25088                 :             :       && TARGET_INTER_UNIT_MOVES_FROM_VEC
   25089                 :             :       && (mode == SImode || (TARGET_64BIT && mode == DImode))
   25090                 :             :       && INTEGER_CLASS_P (rclass))
   25091                 :             :     return ALL_SSE_REGS;
   25092                 :  6334720211 :   return NO_REGS;
   25093                 :             : }
   25094                 :             : 
   25095                 :             : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  Like the default implementation,
   25096                 :             :    but returns a lower bound.  */
   25097                 :             : 
   25098                 :             : static unsigned int
   25099                 :     1791065 : ix86_max_noce_ifcvt_seq_cost (edge e)
   25100                 :             : {
   25101                 :     1791065 :   bool predictable_p = predictable_edge_p (e);
   25102                 :     1791065 :   if (predictable_p)
   25103                 :             :     {
   25104                 :      137988 :       if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
   25105                 :           0 :         return param_max_rtl_if_conversion_predictable_cost;
   25106                 :             :     }
   25107                 :             :   else
   25108                 :             :     {
   25109                 :     1653077 :       if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
   25110                 :          83 :         return param_max_rtl_if_conversion_unpredictable_cost;
   25111                 :             :     }
   25112                 :             : 
   25113                 :             :   /* For modern machines with deeper pipeline, the penalty for branch
   25114                 :             :      misprediction could be higher than before to reset the pipeline
   25115                 :             :      slots. Add parameter br_mispredict_scale as a factor to describe
   25116                 :             :      the impact of reseting the pipeline.  */
   25117                 :             : 
   25118                 :     1790982 :   return BRANCH_COST (true, predictable_p)
   25119                 :     1790982 :          * ix86_tune_cost->br_mispredict_scale;
   25120                 :             : }
   25121                 :             : 
   25122                 :             : /* Return true if SEQ is a good candidate as a replacement for the
   25123                 :             :    if-convertible sequence described in IF_INFO.  */
   25124                 :             : 
   25125                 :             : static bool
   25126                 :      225153 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
   25127                 :             : {
   25128                 :      225153 :   if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
   25129                 :             :     {
   25130                 :             :       int cmov_cnt = 0;
   25131                 :             :       /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
   25132                 :             :          Maybe we should allow even more conditional moves as long as they
   25133                 :             :          are used far enough not to stall the CPU, or also consider
   25134                 :             :          IF_INFO->TEST_BB succ edge probabilities.  */
   25135                 :         314 :       for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
   25136                 :             :         {
   25137                 :         259 :           rtx set = single_set (insn);
   25138                 :         259 :           if (!set)
   25139                 :           0 :             continue;
   25140                 :         259 :           if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
   25141                 :         210 :             continue;
   25142                 :          49 :           rtx src = SET_SRC (set);
   25143                 :          49 :           machine_mode mode = GET_MODE (src);
   25144                 :          49 :           if (GET_MODE_CLASS (mode) != MODE_INT
   25145                 :           0 :               && GET_MODE_CLASS (mode) != MODE_FLOAT)
   25146                 :           0 :             continue;
   25147                 :          49 :           if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
   25148                 :          48 :               || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
   25149                 :           1 :             continue;
   25150                 :             :           /* insn is CMOV or FCMOV.  */
   25151                 :          48 :           if (++cmov_cnt > 1)
   25152                 :             :             return false;
   25153                 :             :         }
   25154                 :             :     }
   25155                 :             : 
   25156                 :             :   /* W/o TARGET_SSE4_1, it takes 3 instructions (pand, pandn and por)
   25157                 :             :      for movdfcc/movsfcc, and could possibly fail cost comparison.
   25158                 :             :      Increase branch cost will hurt performance for other modes, so
   25159                 :             :      specially add some preference for floating point ifcvt.  */
   25160                 :      225145 :   if (!TARGET_SSE4_1 && if_info->x
   25161                 :      171966 :       && GET_MODE_CLASS (GET_MODE (if_info->x)) == MODE_FLOAT
   25162                 :       34348 :       && if_info->speed_p)
   25163                 :             :     {
   25164                 :       27200 :       unsigned cost = seq_cost (seq, true);
   25165                 :             : 
   25166                 :       27200 :       if (cost <= if_info->original_cost)
   25167                 :             :         return true;
   25168                 :             : 
   25169                 :       26153 :       return cost <= (if_info->max_seq_cost + COSTS_N_INSNS (2));
   25170                 :             :     }
   25171                 :             : 
   25172                 :      197945 :   return default_noce_conversion_profitable_p (seq, if_info);
   25173                 :             : }
   25174                 :             : 
   25175                 :             : /* x86-specific vector costs.  */
   25176                 :             : class ix86_vector_costs : public vector_costs
   25177                 :             : {
   25178                 :             : public:
   25179                 :             :   ix86_vector_costs (vec_info *, bool);
   25180                 :             : 
   25181                 :             :   unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
   25182                 :             :                               stmt_vec_info stmt_info, slp_tree node,
   25183                 :             :                               tree vectype, int misalign,
   25184                 :             :                               vect_cost_model_location where) override;
   25185                 :             :   void finish_cost (const vector_costs *) override;
   25186                 :             : 
   25187                 :             : private:
   25188                 :             : 
   25189                 :             :   /* Estimate register pressure of the vectorized code.  */
   25190                 :             :   void ix86_vect_estimate_reg_pressure ();
   25191                 :             :   /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
   25192                 :             :      estimation of register pressure.
   25193                 :             :      ??? Currently it's only used by vec_construct/scalar_to_vec
   25194                 :             :      where we know it's not loaded from memory.  */
   25195                 :             :   unsigned m_num_gpr_needed[3];
   25196                 :             :   unsigned m_num_sse_needed[3];
   25197                 :             :   /* Number of 256-bit vector permutation.  */
   25198                 :             :   unsigned m_num_avx256_vec_perm[3];
   25199                 :             : };
   25200                 :             : 
   25201                 :     1854317 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
   25202                 :             :   : vector_costs (vinfo, costing_for_scalar),
   25203                 :     7417268 :     m_num_gpr_needed (),
   25204                 :     7417268 :     m_num_sse_needed (),
   25205                 :    11125902 :     m_num_avx256_vec_perm ()
   25206                 :             : {
   25207                 :     1854317 : }
   25208                 :             : 
   25209                 :             : /* Implement targetm.vectorize.create_costs.  */
   25210                 :             : 
   25211                 :             : static vector_costs *
   25212                 :     1854317 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
   25213                 :             : {
   25214                 :     1854317 :   return new ix86_vector_costs (vinfo, costing_for_scalar);
   25215                 :             : }
   25216                 :             : 
   25217                 :             : unsigned
   25218                 :     6396478 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   25219                 :             :                                   stmt_vec_info stmt_info, slp_tree node,
   25220                 :             :                                   tree vectype, int misalign,
   25221                 :             :                                   vect_cost_model_location where)
   25222                 :             : {
   25223                 :     6396478 :   unsigned retval = 0;
   25224                 :     6396478 :   bool scalar_p
   25225                 :             :     = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
   25226                 :     6396478 :   int stmt_cost = - 1;
   25227                 :             : 
   25228                 :     6396478 :   bool fp = false;
   25229                 :     6396478 :   machine_mode mode = scalar_p ? SImode : TImode;
   25230                 :             : 
   25231                 :     6396478 :   if (vectype != NULL)
   25232                 :             :     {
   25233                 :     6100078 :       fp = FLOAT_TYPE_P (vectype);
   25234                 :     6100078 :       mode = TYPE_MODE (vectype);
   25235                 :     6100078 :       if (scalar_p)
   25236                 :     3499181 :         mode = TYPE_MODE (TREE_TYPE (vectype));
   25237                 :             :     }
   25238                 :             : 
   25239                 :     6396478 :   if ((kind == vector_stmt || kind == scalar_stmt)
   25240                 :     1647119 :       && stmt_info
   25241                 :     8037891 :       && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
   25242                 :             :     {
   25243                 :     1357875 :       tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   25244                 :             :       /*machine_mode inner_mode = mode;
   25245                 :             :       if (VECTOR_MODE_P (mode))
   25246                 :             :         inner_mode = GET_MODE_INNER (mode);*/
   25247                 :             : 
   25248                 :     1357875 :       switch (subcode)
   25249                 :             :         {
   25250                 :      563606 :         case PLUS_EXPR:
   25251                 :      563606 :         case POINTER_PLUS_EXPR:
   25252                 :      563606 :         case MINUS_EXPR:
   25253                 :      563606 :           if (kind == scalar_stmt)
   25254                 :             :             {
   25255                 :      390831 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   25256                 :       74788 :                 stmt_cost = ix86_cost->addss;
   25257                 :      316043 :               else if (X87_FLOAT_MODE_P (mode))
   25258                 :          80 :                 stmt_cost = ix86_cost->fadd;
   25259                 :             :               else
   25260                 :      315963 :                 stmt_cost = ix86_cost->add;
   25261                 :             :             }
   25262                 :             :           else
   25263                 :      172775 :             stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
   25264                 :             :                                        : ix86_cost->sse_op);
   25265                 :             :           break;
   25266                 :             : 
   25267                 :      173410 :         case MULT_EXPR:
   25268                 :             :           /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
   25269                 :             :              take it as MULT_EXPR.  */
   25270                 :      173410 :         case MULT_HIGHPART_EXPR:
   25271                 :      173410 :           stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   25272                 :      173410 :           break;
   25273                 :             :           /* There's no direct instruction for WIDEN_MULT_EXPR,
   25274                 :             :              take emulation into account.  */
   25275                 :        1856 :         case WIDEN_MULT_EXPR:
   25276                 :        3712 :           stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
   25277                 :        1856 :                                             TYPE_UNSIGNED (vectype));
   25278                 :        1856 :           break;
   25279                 :             : 
   25280                 :        6318 :         case NEGATE_EXPR:
   25281                 :        6318 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   25282                 :        1897 :             stmt_cost = ix86_cost->sse_op;
   25283                 :        4421 :           else if (X87_FLOAT_MODE_P (mode))
   25284                 :           0 :             stmt_cost = ix86_cost->fchs;
   25285                 :        4421 :           else if (VECTOR_MODE_P (mode))
   25286                 :        1954 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   25287                 :             :           else
   25288                 :        2467 :             stmt_cost = ix86_cost->add;
   25289                 :             :           break;
   25290                 :        8051 :         case TRUNC_DIV_EXPR:
   25291                 :        8051 :         case CEIL_DIV_EXPR:
   25292                 :        8051 :         case FLOOR_DIV_EXPR:
   25293                 :        8051 :         case ROUND_DIV_EXPR:
   25294                 :        8051 :         case TRUNC_MOD_EXPR:
   25295                 :        8051 :         case CEIL_MOD_EXPR:
   25296                 :        8051 :         case FLOOR_MOD_EXPR:
   25297                 :        8051 :         case RDIV_EXPR:
   25298                 :        8051 :         case ROUND_MOD_EXPR:
   25299                 :        8051 :         case EXACT_DIV_EXPR:
   25300                 :        8051 :           stmt_cost = ix86_division_cost (ix86_cost, mode);
   25301                 :        8051 :           break;
   25302                 :             : 
   25303                 :       40941 :         case RSHIFT_EXPR:
   25304                 :       40941 :         case LSHIFT_EXPR:
   25305                 :       40941 :         case LROTATE_EXPR:
   25306                 :       40941 :         case RROTATE_EXPR:
   25307                 :       40941 :           {
   25308                 :       40941 :             tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
   25309                 :       40941 :             tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
   25310                 :       40941 :             stmt_cost = ix86_shift_rotate_cost
   25311                 :       40941 :                            (ix86_cost,
   25312                 :             :                             (subcode == RSHIFT_EXPR
   25313                 :       25714 :                              && !TYPE_UNSIGNED (TREE_TYPE (op1)))
   25314                 :             :                             ? ASHIFTRT : LSHIFTRT, mode,
   25315                 :       40941 :                             TREE_CODE (op2) == INTEGER_CST,
   25316                 :       40941 :                             cst_and_fits_in_hwi (op2)
   25317                 :       25954 :                             ? int_cst_value (op2) : -1,
   25318                 :             :                             false, false, NULL, NULL);
   25319                 :             :           }
   25320                 :       40941 :           break;
   25321                 :       69996 :         case NOP_EXPR:
   25322                 :             :           /* Only sign-conversions are free.  */
   25323                 :       69996 :           if (tree_nop_conversion_p
   25324                 :       69996 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
   25325                 :       69996 :                  TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
   25326                 :     6396478 :             stmt_cost = 0;
   25327                 :             :           break;
   25328                 :             : 
   25329                 :      113624 :         case BIT_IOR_EXPR:
   25330                 :      113624 :         case ABS_EXPR:
   25331                 :      113624 :         case ABSU_EXPR:
   25332                 :      113624 :         case MIN_EXPR:
   25333                 :      113624 :         case MAX_EXPR:
   25334                 :      113624 :         case BIT_XOR_EXPR:
   25335                 :      113624 :         case BIT_AND_EXPR:
   25336                 :      113624 :         case BIT_NOT_EXPR:
   25337                 :      113624 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   25338                 :        2317 :             stmt_cost = ix86_cost->sse_op;
   25339                 :      111307 :           else if (VECTOR_MODE_P (mode))
   25340                 :       33438 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   25341                 :             :           else
   25342                 :       77869 :             stmt_cost = ix86_cost->add;
   25343                 :             :           break;
   25344                 :             :         default:
   25345                 :             :           break;
   25346                 :             :         }
   25347                 :             :     }
   25348                 :             : 
   25349                 :     6396478 :   combined_fn cfn;
   25350                 :     6396478 :   if ((kind == vector_stmt || kind == scalar_stmt)
   25351                 :     1647119 :       && stmt_info
   25352                 :     1641413 :       && stmt_info->stmt
   25353                 :     8037891 :       && (cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
   25354                 :       15890 :     switch (cfn)
   25355                 :             :       {
   25356                 :          28 :       case CFN_FMA:
   25357                 :          28 :         stmt_cost = ix86_vec_cost (mode,
   25358                 :          28 :                                    mode == SFmode ? ix86_cost->fmass
   25359                 :             :                                    : ix86_cost->fmasd);
   25360                 :          28 :         break;
   25361                 :          12 :       case CFN_MULH:
   25362                 :          12 :         stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   25363                 :          12 :         break;
   25364                 :             :       default:
   25365                 :             :         break;
   25366                 :             :       }
   25367                 :             : 
   25368                 :             :   /* If we do elementwise loads into a vector then we are bound by
   25369                 :             :      latency and execution resources for the many scalar loads
   25370                 :             :      (AGU and load ports).  Try to account for this by scaling the
   25371                 :             :      construction cost by the number of elements involved.  */
   25372                 :     6396478 :   if ((kind == vec_construct || kind == vec_to_scalar)
   25373                 :      409834 :       && ((stmt_info
   25374                 :      182709 :            && (STMT_VINFO_TYPE (stmt_info) == load_vec_info_type
   25375                 :      182709 :                || STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
   25376                 :       73057 :            && ((STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_ELEMENTWISE
   25377                 :           0 :                 && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
   25378                 :             :                     != INTEGER_CST))
   25379                 :       73057 :                || (STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info)
   25380                 :             :                    == VMAT_GATHER_SCATTER)))
   25381                 :      405162 :           || (node
   25382                 :      250427 :               && (((SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_ELEMENTWISE
   25383                 :      249472 :                     || (SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_STRIDED_SLP
   25384                 :       40360 :                         && SLP_TREE_LANES (node) == 1))
   25385                 :       37985 :                    && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF
   25386                 :             :                                              (SLP_TREE_REPRESENTATIVE (node))))
   25387                 :             :                       != INTEGER_CST))
   25388                 :      224606 :                   || (SLP_TREE_MEMORY_ACCESS_TYPE (node)
   25389                 :             :                       == VMAT_GATHER_SCATTER)))))
   25390                 :             :     {
   25391                 :       34877 :       stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   25392                 :       34877 :       stmt_cost *= (TYPE_VECTOR_SUBPARTS (vectype) + 1);
   25393                 :             :     }
   25394                 :     6361601 :   else if ((kind == vec_construct || kind == scalar_to_vec)
   25395                 :      466887 :            && node
   25396                 :      299925 :            && SLP_TREE_DEF_TYPE (node) == vect_external_def)
   25397                 :             :     {
   25398                 :      295810 :       stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   25399                 :      295810 :       unsigned i;
   25400                 :      295810 :       tree op;
   25401                 :     1260097 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   25402                 :      668477 :         if (TREE_CODE (op) == SSA_NAME)
   25403                 :      439549 :           TREE_VISITED (op) = 0;
   25404                 :      964287 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   25405                 :             :         {
   25406                 :      929238 :           if (TREE_CODE (op) != SSA_NAME
   25407                 :      668477 :               || TREE_VISITED (op))
   25408                 :      260761 :             continue;
   25409                 :      407716 :           TREE_VISITED (op) = 1;
   25410                 :      407716 :           gimple *def = SSA_NAME_DEF_STMT (op);
   25411                 :      407716 :           tree tem;
   25412                 :      407716 :           if (is_gimple_assign (def)
   25413                 :      191288 :               && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
   25414                 :       30801 :               && ((tem = gimple_assign_rhs1 (def)), true)
   25415                 :       30801 :               && TREE_CODE (tem) == SSA_NAME
   25416                 :             :               /* A sign-change expands to nothing.  */
   25417                 :      438332 :               && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (def)),
   25418                 :       30616 :                                         TREE_TYPE (tem)))
   25419                 :        7710 :             def = SSA_NAME_DEF_STMT (tem);
   25420                 :             :           /* When the component is loaded from memory we can directly
   25421                 :             :              move it to a vector register, otherwise we have to go
   25422                 :             :              via a GPR or via vpinsr which involves similar cost.
   25423                 :             :              Likewise with a BIT_FIELD_REF extracting from a vector
   25424                 :             :              register we can hope to avoid using a GPR.  */
   25425                 :      407716 :           if (!is_gimple_assign (def)
   25426                 :      407716 :               || ((!gimple_assign_load_p (def)
   25427                 :       77864 :                    || (!TARGET_SSE4_1
   25428                 :      147924 :                        && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) == 1))
   25429                 :      115348 :                   && (gimple_assign_rhs_code (def) != BIT_FIELD_REF
   25430                 :        3003 :                       || !VECTOR_TYPE_P (TREE_TYPE
   25431                 :             :                                 (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))))
   25432                 :             :             {
   25433                 :      330518 :               if (fp)
   25434                 :       13963 :                 m_num_sse_needed[where]++;
   25435                 :             :               else
   25436                 :             :                 {
   25437                 :      316555 :                   m_num_gpr_needed[where]++;
   25438                 :      316555 :                   stmt_cost += ix86_cost->sse_to_integer;
   25439                 :             :                 }
   25440                 :             :             }
   25441                 :             :         }
   25442                 :      964287 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   25443                 :      668477 :         if (TREE_CODE (op) == SSA_NAME)
   25444                 :      439549 :           TREE_VISITED (op) = 0;
   25445                 :             :     }
   25446                 :     6396478 :   if (stmt_cost == -1)
   25447                 :     5157945 :     stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   25448                 :             : 
   25449                 :     6396478 :   if (kind == vec_perm && vectype
   25450                 :     6474429 :       && GET_MODE_SIZE (TYPE_MODE (vectype)) == 32)
   25451                 :        4282 :     m_num_avx256_vec_perm[where]++;
   25452                 :             : 
   25453                 :             :   /* Penalize DFmode vector operations for Bonnell.  */
   25454                 :     6396478 :   if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
   25455                 :     6396555 :       && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
   25456                 :          12 :     stmt_cost *= 5;  /* FIXME: The value here is arbitrary.  */
   25457                 :             : 
   25458                 :             :   /* Statements in an inner loop relative to the loop being
   25459                 :             :      vectorized are weighted more heavily.  The value here is
   25460                 :             :      arbitrary and could potentially be improved with analysis.  */
   25461                 :     6396478 :   retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
   25462                 :             : 
   25463                 :             :   /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
   25464                 :             :      for Silvermont as it has out of order integer pipeline and can execute
   25465                 :             :      2 scalar instruction per tick, but has in order SIMD pipeline.  */
   25466                 :     6396478 :   if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
   25467                 :     6396478 :        || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
   25468                 :        1774 :       && stmt_info && stmt_info->stmt)
   25469                 :             :     {
   25470                 :        1543 :       tree lhs_op = gimple_get_lhs (stmt_info->stmt);
   25471                 :        1543 :       if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
   25472                 :        1109 :         retval = (retval * 17) / 10;
   25473                 :             :     }
   25474                 :             : 
   25475                 :     6396478 :   m_costs[where] += retval;
   25476                 :             : 
   25477                 :     6396478 :   return retval;
   25478                 :             : }
   25479                 :             : 
   25480                 :             : void
   25481                 :     1589688 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
   25482                 :             : {
   25483                 :     1589688 :   unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
   25484                 :     1589688 :   unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
   25485                 :             : 
   25486                 :             :   /* Any better way to have target available fp registers, currently use SSE_REGS.  */
   25487                 :     1589688 :   unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
   25488                 :     6358752 :   for (unsigned i = 0; i != 3; i++)
   25489                 :             :     {
   25490                 :     4769064 :       if (m_num_gpr_needed[i] > target_avail_regs)
   25491                 :         603 :         m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
   25492                 :             :       /* Only measure sse registers pressure.  */
   25493                 :     4769064 :       if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
   25494                 :          92 :         m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
   25495                 :             :     }
   25496                 :     1589688 : }
   25497                 :             : 
   25498                 :             : void
   25499                 :     1589688 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
   25500                 :             : {
   25501                 :     1589688 :   loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
   25502                 :      293036 :   if (loop_vinfo && !m_costing_for_scalar)
   25503                 :             :     {
   25504                 :             :       /* We are currently not asking the vectorizer to compare costs
   25505                 :             :          between different vector mode sizes.  When using predication
   25506                 :             :          that will end up always choosing the prefered mode size even
   25507                 :             :          if there's a smaller mode covering all lanes.  Test for this
   25508                 :             :          situation and artificially reject the larger mode attempt.
   25509                 :             :          ???  We currently lack masked ops for sub-SSE sized modes,
   25510                 :             :          so we could restrict this rejection to AVX and AVX512 modes
   25511                 :             :          but error on the safe side for now.  */
   25512                 :       75312 :       if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
   25513                 :          13 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   25514                 :          13 :           && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   25515                 :       75320 :           && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
   25516                 :          16 :               > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
   25517                 :           6 :         m_costs[vect_body] = INT_MAX;
   25518                 :             :     }
   25519                 :             : 
   25520                 :     1589688 :   ix86_vect_estimate_reg_pressure ();
   25521                 :             : 
   25522                 :     6358752 :   for (int i = 0; i != 3; i++)
   25523                 :     4769064 :     if (m_num_avx256_vec_perm[i]
   25524                 :         487 :         && TARGET_AVX256_AVOID_VEC_PERM)
   25525                 :           2 :       m_costs[i] = INT_MAX;
   25526                 :             : 
   25527                 :             :   /* When X86_TUNE_AVX512_TWO_EPILOGUES is enabled arrange for both
   25528                 :             :      a AVX2 and a SSE epilogue for AVX512 vectorized loops.  */
   25529                 :     1589688 :   if (loop_vinfo
   25530                 :      293036 :       && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
   25531                 :             :     {
   25532                 :         528 :       if (GET_MODE_SIZE (loop_vinfo->vector_mode) == 64)
   25533                 :         112 :         m_suggested_epilogue_mode = V32QImode;
   25534                 :         152 :       else if (LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   25535                 :         173 :                && GET_MODE_SIZE (loop_vinfo->vector_mode) == 32)
   25536                 :          11 :         m_suggested_epilogue_mode = V16QImode;
   25537                 :             :     }
   25538                 :             :   /* When a 128bit SSE vectorized epilogue still has a VF of 16 or larger
   25539                 :             :      enable a 64bit SSE epilogue.  */
   25540                 :      293036 :   if (loop_vinfo
   25541                 :      293036 :       && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   25542                 :       59740 :       && GET_MODE_SIZE (loop_vinfo->vector_mode) == 16
   25543                 :       11655 :       && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () >= 16)
   25544                 :        1458 :     m_suggested_epilogue_mode = V8QImode;
   25545                 :             : 
   25546                 :     1589688 :   vector_costs::finish_cost (scalar_costs);
   25547                 :     1589688 : }
   25548                 :             : 
   25549                 :             : /* Validate target specific memory model bits in VAL. */
   25550                 :             : 
   25551                 :             : static unsigned HOST_WIDE_INT
   25552                 :      511696 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   25553                 :             : {
   25554                 :      511696 :   enum memmodel model = memmodel_from_int (val);
   25555                 :      511696 :   bool strong;
   25556                 :             : 
   25557                 :      511696 :   if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
   25558                 :             :                                       |MEMMODEL_MASK)
   25559                 :      511692 :       || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
   25560                 :             :     {
   25561                 :           4 :       warning (OPT_Winvalid_memory_model,
   25562                 :             :                "unknown architecture specific memory model");
   25563                 :           4 :       return MEMMODEL_SEQ_CST;
   25564                 :             :     }
   25565                 :      511692 :   strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
   25566                 :      511692 :   if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
   25567                 :             :     {
   25568                 :           0 :       warning (OPT_Winvalid_memory_model,
   25569                 :             :               "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
   25570                 :             :                "memory model");
   25571                 :           0 :       return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
   25572                 :             :     }
   25573                 :      511692 :   if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
   25574                 :             :     {
   25575                 :           0 :       warning (OPT_Winvalid_memory_model,
   25576                 :             :               "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
   25577                 :             :                "memory model");
   25578                 :           0 :       return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
   25579                 :             :     }
   25580                 :             :   return val;
   25581                 :             : }
   25582                 :             : 
   25583                 :             : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
   25584                 :             :    CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
   25585                 :             :    CLONEI->simdlen.  Return 0 if SIMD clones shouldn't be emitted,
   25586                 :             :    or number of vecsize_mangle variants that should be emitted.  */
   25587                 :             : 
   25588                 :             : static int
   25589                 :        7577 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
   25590                 :             :                                              struct cgraph_simd_clone *clonei,
   25591                 :             :                                              tree base_type, int num,
   25592                 :             :                                              bool explicit_p)
   25593                 :             : {
   25594                 :        7577 :   int ret = 1;
   25595                 :             : 
   25596                 :        7577 :   if (clonei->simdlen
   25597                 :        7577 :       && (clonei->simdlen < 2
   25598                 :        1289 :           || clonei->simdlen > 1024
   25599                 :        8866 :           || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
   25600                 :             :     {
   25601                 :           0 :       if (explicit_p)
   25602                 :           0 :         warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25603                 :             :                     "unsupported simdlen %wd", clonei->simdlen.to_constant ());
   25604                 :           0 :       return 0;
   25605                 :             :     }
   25606                 :             : 
   25607                 :        7577 :   tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
   25608                 :        7577 :   if (TREE_CODE (ret_type) != VOID_TYPE)
   25609                 :        6785 :     switch (TYPE_MODE (ret_type))
   25610                 :             :       {
   25611                 :        6785 :       case E_QImode:
   25612                 :        6785 :       case E_HImode:
   25613                 :        6785 :       case E_SImode:
   25614                 :        6785 :       case E_DImode:
   25615                 :        6785 :       case E_SFmode:
   25616                 :        6785 :       case E_DFmode:
   25617                 :             :       /* case E_SCmode: */
   25618                 :             :       /* case E_DCmode: */
   25619                 :        6785 :         if (!AGGREGATE_TYPE_P (ret_type))
   25620                 :             :           break;
   25621                 :             :         /* FALLTHRU */
   25622                 :           2 :       default:
   25623                 :           2 :         if (explicit_p)
   25624                 :           2 :           warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25625                 :             :                       "unsupported return type %qT for simd", ret_type);
   25626                 :           2 :         return 0;
   25627                 :             :       }
   25628                 :             : 
   25629                 :        7575 :   tree t;
   25630                 :        7575 :   int i;
   25631                 :        7575 :   tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
   25632                 :        7575 :   bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
   25633                 :             : 
   25634                 :        7575 :   for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
   25635                 :       20402 :        t && t != void_list_node; t = TREE_CHAIN (t), i++)
   25636                 :             :     {
   25637                 :       16630 :       tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
   25638                 :       12832 :       switch (TYPE_MODE (arg_type))
   25639                 :             :         {
   25640                 :       12813 :         case E_QImode:
   25641                 :       12813 :         case E_HImode:
   25642                 :       12813 :         case E_SImode:
   25643                 :       12813 :         case E_DImode:
   25644                 :       12813 :         case E_SFmode:
   25645                 :       12813 :         case E_DFmode:
   25646                 :             :         /* case E_SCmode: */
   25647                 :             :         /* case E_DCmode: */
   25648                 :       12813 :           if (!AGGREGATE_TYPE_P (arg_type))
   25649                 :             :             break;
   25650                 :             :           /* FALLTHRU */
   25651                 :          41 :         default:
   25652                 :          41 :           if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
   25653                 :             :             break;
   25654                 :           5 :           if (explicit_p)
   25655                 :           5 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25656                 :             :                         "unsupported argument type %qT for simd", arg_type);
   25657                 :             :           return 0;
   25658                 :             :         }
   25659                 :             :     }
   25660                 :             : 
   25661                 :        7570 :   if (!TREE_PUBLIC (node->decl) || !explicit_p)
   25662                 :             :     {
   25663                 :             :       /* If the function isn't exported, we can pick up just one ISA
   25664                 :             :          for the clones.  */
   25665                 :         114 :       if (TARGET_AVX512F && TARGET_EVEX512)
   25666                 :           0 :         clonei->vecsize_mangle = 'e';
   25667                 :         114 :       else if (TARGET_AVX2)
   25668                 :           1 :         clonei->vecsize_mangle = 'd';
   25669                 :         113 :       else if (TARGET_AVX)
   25670                 :          88 :         clonei->vecsize_mangle = 'c';
   25671                 :             :       else
   25672                 :          25 :         clonei->vecsize_mangle = 'b';
   25673                 :             :       ret = 1;
   25674                 :             :     }
   25675                 :             :   else
   25676                 :             :     {
   25677                 :        7456 :       clonei->vecsize_mangle = "bcde"[num];
   25678                 :        7456 :       ret = 4;
   25679                 :             :     }
   25680                 :        7570 :   clonei->mask_mode = VOIDmode;
   25681                 :        7570 :   switch (clonei->vecsize_mangle)
   25682                 :             :     {
   25683                 :        1889 :     case 'b':
   25684                 :        1889 :       clonei->vecsize_int = 128;
   25685                 :        1889 :       clonei->vecsize_float = 128;
   25686                 :        1889 :       break;
   25687                 :        1952 :     case 'c':
   25688                 :        1952 :       clonei->vecsize_int = 128;
   25689                 :        1952 :       clonei->vecsize_float = 256;
   25690                 :        1952 :       break;
   25691                 :        1865 :     case 'd':
   25692                 :        1865 :       clonei->vecsize_int = 256;
   25693                 :        1865 :       clonei->vecsize_float = 256;
   25694                 :        1865 :       break;
   25695                 :        1864 :     case 'e':
   25696                 :        1864 :       clonei->vecsize_int = 512;
   25697                 :        1864 :       clonei->vecsize_float = 512;
   25698                 :        1864 :       if (TYPE_MODE (base_type) == QImode)
   25699                 :          15 :         clonei->mask_mode = DImode;
   25700                 :             :       else
   25701                 :        1849 :         clonei->mask_mode = SImode;
   25702                 :             :       break;
   25703                 :             :     }
   25704                 :        7570 :   if (clonei->simdlen == 0)
   25705                 :             :     {
   25706                 :        6281 :       if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
   25707                 :        3265 :         clonei->simdlen = clonei->vecsize_int;
   25708                 :             :       else
   25709                 :        3016 :         clonei->simdlen = clonei->vecsize_float;
   25710                 :        6281 :       clonei->simdlen = clonei->simdlen
   25711                 :       12562 :                         / GET_MODE_BITSIZE (TYPE_MODE (base_type));
   25712                 :             :     }
   25713                 :        1289 :   else if (clonei->simdlen > 16)
   25714                 :             :     {
   25715                 :             :       /* For compatibility with ICC, use the same upper bounds
   25716                 :             :          for simdlen.  In particular, for CTYPE below, use the return type,
   25717                 :             :          unless the function returns void, in that case use the characteristic
   25718                 :             :          type.  If it is possible for given SIMDLEN to pass CTYPE value
   25719                 :             :          in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
   25720                 :             :          for 64-bit code), accept that SIMDLEN, otherwise warn and don't
   25721                 :             :          emit corresponding clone.  */
   25722                 :           4 :       tree ctype = ret_type;
   25723                 :           4 :       if (VOID_TYPE_P (ret_type))
   25724                 :           0 :         ctype = base_type;
   25725                 :           8 :       int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
   25726                 :           4 :       if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
   25727                 :           0 :         cnt /= clonei->vecsize_int;
   25728                 :             :       else
   25729                 :           4 :         cnt /= clonei->vecsize_float;
   25730                 :           4 :       if (cnt > (TARGET_64BIT ? 16 : 8))
   25731                 :             :         {
   25732                 :           0 :           if (explicit_p)
   25733                 :           0 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25734                 :             :                         "unsupported simdlen %wd",
   25735                 :             :                         clonei->simdlen.to_constant ());
   25736                 :           0 :           return 0;
   25737                 :             :         }
   25738                 :             :       }
   25739                 :             :   return ret;
   25740                 :             : }
   25741                 :             : 
   25742                 :             : /* If SIMD clone NODE can't be used in a vectorized loop
   25743                 :             :    in current function, return -1, otherwise return a badness of using it
   25744                 :             :    (0 if it is most desirable from vecsize_mangle point of view, 1
   25745                 :             :    slightly less desirable, etc.).  */
   25746                 :             : 
   25747                 :             : static int
   25748                 :        1840 : ix86_simd_clone_usable (struct cgraph_node *node, machine_mode)
   25749                 :             : {
   25750                 :        1840 :   switch (node->simdclone->vecsize_mangle)
   25751                 :             :     {
   25752                 :         660 :     case 'b':
   25753                 :         660 :       if (!TARGET_SSE2)
   25754                 :             :         return -1;
   25755                 :         660 :       if (!TARGET_AVX)
   25756                 :             :         return 0;
   25757                 :         549 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 3 : TARGET_AVX2 ? 2 : 1;
   25758                 :         663 :     case 'c':
   25759                 :         663 :       if (!TARGET_AVX)
   25760                 :             :         return -1;
   25761                 :         629 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 2 : TARGET_AVX2 ? 1 : 0;
   25762                 :         325 :     case 'd':
   25763                 :         325 :       if (!TARGET_AVX2)
   25764                 :             :         return -1;
   25765                 :         126 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 1 : 0;
   25766                 :         192 :     case 'e':
   25767                 :         192 :       if (!TARGET_AVX512F || !TARGET_EVEX512)
   25768                 :         154 :         return -1;
   25769                 :             :       return 0;
   25770                 :           0 :     default:
   25771                 :           0 :       gcc_unreachable ();
   25772                 :             :     }
   25773                 :             : }
   25774                 :             : 
   25775                 :             : /* This function adjusts the unroll factor based on
   25776                 :             :    the hardware capabilities. For ex, bdver3 has
   25777                 :             :    a loop buffer which makes unrolling of smaller
   25778                 :             :    loops less important. This function decides the
   25779                 :             :    unroll factor using number of memory references
   25780                 :             :    (value 32 is used) as a heuristic. */
   25781                 :             : 
   25782                 :             : static unsigned
   25783                 :      724137 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
   25784                 :             : {
   25785                 :      724137 :   basic_block *bbs;
   25786                 :      724137 :   rtx_insn *insn;
   25787                 :      724137 :   unsigned i;
   25788                 :      724137 :   unsigned mem_count = 0;
   25789                 :             : 
   25790                 :             :   /* Unroll small size loop when unroll factor is not explicitly
   25791                 :             :      specified.  */
   25792                 :      724137 :   if (ix86_unroll_only_small_loops && !loop->unroll)
   25793                 :             :     {
   25794                 :      681387 :       if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
   25795                 :       66963 :         return MIN (nunroll, ix86_cost->small_unroll_factor);
   25796                 :             :       else
   25797                 :             :         return 1;
   25798                 :             :     }
   25799                 :             : 
   25800                 :       42750 :   if (!TARGET_ADJUST_UNROLL)
   25801                 :             :      return nunroll;
   25802                 :             : 
   25803                 :             :   /* Count the number of memory references within the loop body.
   25804                 :             :      This value determines the unrolling factor for bdver3 and bdver4
   25805                 :             :      architectures. */
   25806                 :           7 :   subrtx_iterator::array_type array;
   25807                 :           7 :   bbs = get_loop_body (loop);
   25808                 :          21 :   for (i = 0; i < loop->num_nodes; i++)
   25809                 :         102 :     FOR_BB_INSNS (bbs[i], insn)
   25810                 :          88 :       if (NONDEBUG_INSN_P (insn))
   25811                 :         464 :         FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   25812                 :         404 :           if (const_rtx x = *iter)
   25813                 :         404 :             if (MEM_P (x))
   25814                 :             :               {
   25815                 :          25 :                 machine_mode mode = GET_MODE (x);
   25816                 :          50 :                 unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
   25817                 :          25 :                 if (n_words > 4)
   25818                 :           0 :                   mem_count += 2;
   25819                 :             :                 else
   25820                 :          25 :                   mem_count += 1;
   25821                 :             :               }
   25822                 :           7 :   free (bbs);
   25823                 :             : 
   25824                 :           7 :   if (mem_count && mem_count <=32)
   25825                 :           7 :     return MIN (nunroll, 32 / mem_count);
   25826                 :             : 
   25827                 :             :   return nunroll;
   25828                 :           7 : }
   25829                 :             : 
   25830                 :             : 
   25831                 :             : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P.  */
   25832                 :             : 
   25833                 :             : static bool
   25834                 :      407602 : ix86_float_exceptions_rounding_supported_p (void)
   25835                 :             : {
   25836                 :             :   /* For x87 floating point with standard excess precision handling,
   25837                 :             :      there is no adddf3 pattern (since x87 floating point only has
   25838                 :             :      XFmode operations) so the default hook implementation gets this
   25839                 :             :      wrong.  */
   25840                 :      407602 :   return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
   25841                 :             : }
   25842                 :             : 
   25843                 :             : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
   25844                 :             : 
   25845                 :             : static void
   25846                 :        7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   25847                 :             : {
   25848                 :        7054 :   if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
   25849                 :             :     return;
   25850                 :        7054 :   tree exceptions_var = create_tmp_var_raw (integer_type_node);
   25851                 :        7054 :   if (TARGET_80387)
   25852                 :             :     {
   25853                 :        7054 :       tree fenv_index_type = build_index_type (size_int (6));
   25854                 :        7054 :       tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
   25855                 :        7054 :       tree fenv_var = create_tmp_var_raw (fenv_type);
   25856                 :        7054 :       TREE_ADDRESSABLE (fenv_var) = 1;
   25857                 :        7054 :       tree fenv_ptr = build_pointer_type (fenv_type);
   25858                 :        7054 :       tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
   25859                 :        7054 :       fenv_addr = fold_convert (ptr_type_node, fenv_addr);
   25860                 :        7054 :       tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
   25861                 :        7054 :       tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
   25862                 :        7054 :       tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
   25863                 :        7054 :       tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
   25864                 :        7054 :       tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
   25865                 :        7054 :       tree hold_fnclex = build_call_expr (fnclex, 0);
   25866                 :        7054 :       fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
   25867                 :             :                          NULL_TREE, NULL_TREE);
   25868                 :        7054 :       *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
   25869                 :             :                       hold_fnclex);
   25870                 :        7054 :       *clear = build_call_expr (fnclex, 0);
   25871                 :        7054 :       tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
   25872                 :        7054 :       tree fnstsw_call = build_call_expr (fnstsw, 0);
   25873                 :        7054 :       tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
   25874                 :             :                             fnstsw_call, NULL_TREE, NULL_TREE);
   25875                 :        7054 :       tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
   25876                 :        7054 :       tree update_mod = build4 (TARGET_EXPR, integer_type_node,
   25877                 :             :                                 exceptions_var, exceptions_x87,
   25878                 :             :                                 NULL_TREE, NULL_TREE);
   25879                 :        7054 :       *update = build2 (COMPOUND_EXPR, integer_type_node,
   25880                 :             :                         sw_mod, update_mod);
   25881                 :        7054 :       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
   25882                 :        7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
   25883                 :             :     }
   25884                 :        7054 :   if (TARGET_SSE && TARGET_SSE_MATH)
   25885                 :             :     {
   25886                 :        7054 :       tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
   25887                 :        7054 :       tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
   25888                 :        7054 :       tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
   25889                 :        7054 :       tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
   25890                 :        7054 :       tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
   25891                 :        7054 :       tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
   25892                 :             :                                       mxcsr_orig_var, stmxcsr_hold_call,
   25893                 :             :                                       NULL_TREE, NULL_TREE);
   25894                 :        7054 :       tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
   25895                 :             :                                   mxcsr_orig_var,
   25896                 :        7054 :                                   build_int_cst (unsigned_type_node, 0x1f80));
   25897                 :        7054 :       hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
   25898                 :        7054 :                              build_int_cst (unsigned_type_node, 0xffffffc0));
   25899                 :        7054 :       tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
   25900                 :             :                                      mxcsr_mod_var, hold_mod_val,
   25901                 :             :                                      NULL_TREE, NULL_TREE);
   25902                 :        7054 :       tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   25903                 :        7054 :       tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
   25904                 :             :                               hold_assign_orig, hold_assign_mod);
   25905                 :        7054 :       hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
   25906                 :             :                          ldmxcsr_hold_call);
   25907                 :        7054 :       if (*hold)
   25908                 :        7054 :         *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
   25909                 :             :       else
   25910                 :           0 :         *hold = hold_all;
   25911                 :        7054 :       tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   25912                 :        7054 :       if (*clear)
   25913                 :        7054 :         *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
   25914                 :             :                          ldmxcsr_clear_call);
   25915                 :             :       else
   25916                 :           0 :         *clear = ldmxcsr_clear_call;
   25917                 :        7054 :       tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
   25918                 :        7054 :       tree exceptions_sse = fold_convert (integer_type_node,
   25919                 :             :                                           stxmcsr_update_call);
   25920                 :        7054 :       if (*update)
   25921                 :             :         {
   25922                 :        7054 :           tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
   25923                 :             :                                         exceptions_var, exceptions_sse);
   25924                 :        7054 :           tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
   25925                 :             :                                            exceptions_var, exceptions_mod);
   25926                 :        7054 :           *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
   25927                 :             :                             exceptions_assign);
   25928                 :             :         }
   25929                 :             :       else
   25930                 :           0 :         *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
   25931                 :             :                           exceptions_sse, NULL_TREE, NULL_TREE);
   25932                 :        7054 :       tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
   25933                 :        7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   25934                 :             :                         ldmxcsr_update_call);
   25935                 :             :     }
   25936                 :        7054 :   tree atomic_feraiseexcept
   25937                 :        7054 :     = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
   25938                 :        7054 :   tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
   25939                 :             :                                                     1, exceptions_var);
   25940                 :        7054 :   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   25941                 :             :                     atomic_feraiseexcept_call);
   25942                 :             : }
   25943                 :             : 
   25944                 :             : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   25945                 :             : /* For i386, common symbol is local only for non-PIE binaries.  For
   25946                 :             :    x86-64, common symbol is local only for non-PIE binaries or linker
   25947                 :             :    supports copy reloc in PIE binaries.   */
   25948                 :             : 
   25949                 :             : static bool
   25950                 :   721931883 : ix86_binds_local_p (const_tree exp)
   25951                 :             : {
   25952                 :   721931883 :   bool direct_extern_access
   25953                 :   721931883 :     = (ix86_direct_extern_access
   25954                 :  1440387532 :        && !(VAR_OR_FUNCTION_DECL_P (exp)
   25955                 :   718455649 :             && lookup_attribute ("nodirect_extern_access",
   25956                 :   718455649 :                                  DECL_ATTRIBUTES (exp))));
   25957                 :   721931883 :   if (!direct_extern_access)
   25958                 :        1003 :     ix86_has_no_direct_extern_access = true;
   25959                 :   721931883 :   return default_binds_local_p_3 (exp, flag_shlib != 0, true,
   25960                 :             :                                   direct_extern_access,
   25961                 :             :                                   (direct_extern_access
   25962                 :   721930880 :                                    && (!flag_pic
   25963                 :   129296938 :                                        || (TARGET_64BIT
   25964                 :   721931883 :                                            && HAVE_LD_PIE_COPYRELOC != 0))));
   25965                 :             : }
   25966                 :             : 
   25967                 :             : /* If flag_pic or ix86_direct_extern_access is false, then neither
   25968                 :             :    local nor global relocs should be placed in readonly memory.  */
   25969                 :             : 
   25970                 :             : static int
   25971                 :     5115716 : ix86_reloc_rw_mask (void)
   25972                 :             : {
   25973                 :     5115716 :   return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
   25974                 :             : }
   25975                 :             : #endif
   25976                 :             : 
   25977                 :             : /* Return true iff ADDR can be used as a symbolic base address.  */
   25978                 :             : 
   25979                 :             : static bool
   25980                 :        3700 : symbolic_base_address_p (rtx addr)
   25981                 :             : {
   25982                 :           0 :   if (GET_CODE (addr) == SYMBOL_REF)
   25983                 :             :     return true;
   25984                 :             : 
   25985                 :        3629 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
   25986                 :           0 :     return true;
   25987                 :             : 
   25988                 :             :   return false;
   25989                 :             : }
   25990                 :             : 
   25991                 :             : /* Return true iff ADDR can be used as a base address.  */
   25992                 :             : 
   25993                 :             : static bool
   25994                 :        5636 : base_address_p (rtx addr)
   25995                 :             : {
   25996                 :           0 :   if (REG_P (addr))
   25997                 :             :     return true;
   25998                 :             : 
   25999                 :        3437 :   if (symbolic_base_address_p (addr))
   26000                 :           0 :     return true;
   26001                 :             : 
   26002                 :             :   return false;
   26003                 :             : }
   26004                 :             : 
   26005                 :             : /* If MEM is in the form of [(base+symbase)+offset], extract the three
   26006                 :             :    parts of address and set to BASE, SYMBASE and OFFSET, otherwise
   26007                 :             :    return false.  */
   26008                 :             : 
   26009                 :             : static bool
   26010                 :        3506 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
   26011                 :             : {
   26012                 :        3506 :   rtx addr;
   26013                 :             : 
   26014                 :        3506 :   gcc_assert (MEM_P (mem));
   26015                 :             : 
   26016                 :        3506 :   addr = XEXP (mem, 0);
   26017                 :             : 
   26018                 :        3506 :   if (GET_CODE (addr) == CONST)
   26019                 :          52 :     addr = XEXP (addr, 0);
   26020                 :             : 
   26021                 :        3506 :   if (base_address_p (addr))
   26022                 :             :     {
   26023                 :        1376 :       *base = addr;
   26024                 :        1376 :       *symbase = const0_rtx;
   26025                 :        1376 :       *offset = const0_rtx;
   26026                 :        1376 :       return true;
   26027                 :             :     }
   26028                 :             : 
   26029                 :        2130 :   if (GET_CODE (addr) == PLUS
   26030                 :        2130 :       && base_address_p (XEXP (addr, 0)))
   26031                 :             :     {
   26032                 :         894 :       rtx addend = XEXP (addr, 1);
   26033                 :             : 
   26034                 :         894 :       if (GET_CODE (addend) == CONST)
   26035                 :           0 :         addend = XEXP (addend, 0);
   26036                 :             : 
   26037                 :         894 :       if (CONST_INT_P (addend))
   26038                 :             :         {
   26039                 :         631 :           *base = XEXP (addr, 0);
   26040                 :         631 :           *symbase = const0_rtx;
   26041                 :         631 :           *offset = addend;
   26042                 :         631 :           return true;
   26043                 :             :         }
   26044                 :             : 
   26045                 :             :       /* Also accept REG + symbolic ref, with or without a CONST_INT
   26046                 :             :          offset.  */
   26047                 :         263 :       if (REG_P (XEXP (addr, 0)))
   26048                 :             :         {
   26049                 :         263 :           if (symbolic_base_address_p (addend))
   26050                 :             :             {
   26051                 :           0 :               *base = XEXP (addr, 0);
   26052                 :           0 :               *symbase = addend;
   26053                 :           0 :               *offset = const0_rtx;
   26054                 :           0 :               return true;
   26055                 :             :             }
   26056                 :             : 
   26057                 :         263 :           if (GET_CODE (addend) == PLUS
   26058                 :           0 :               && symbolic_base_address_p (XEXP (addend, 0))
   26059                 :         263 :               && CONST_INT_P (XEXP (addend, 1)))
   26060                 :             :             {
   26061                 :           0 :               *base = XEXP (addr, 0);
   26062                 :           0 :               *symbase = XEXP (addend, 0);
   26063                 :           0 :               *offset = XEXP (addend, 1);
   26064                 :           0 :               return true;
   26065                 :             :             }
   26066                 :             :         }
   26067                 :             :     }
   26068                 :             : 
   26069                 :             :   return false;
   26070                 :             : }
   26071                 :             : 
   26072                 :             : /* Given OPERANDS of consecutive load/store, check if we can merge
   26073                 :             :    them into move multiple.  LOAD is true if they are load instructions.
   26074                 :             :    MODE is the mode of memory operands.  */
   26075                 :             : 
   26076                 :             : bool
   26077                 :        1939 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
   26078                 :             :                                     machine_mode mode)
   26079                 :             : {
   26080                 :        1939 :   HOST_WIDE_INT offval_1, offval_2, msize;
   26081                 :        1939 :   rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
   26082                 :             :     symbase_1, symbase_2, offset_1, offset_2;
   26083                 :             : 
   26084                 :        1939 :   if (load)
   26085                 :             :     {
   26086                 :        1590 :       mem_1 = operands[1];
   26087                 :        1590 :       mem_2 = operands[3];
   26088                 :        1590 :       reg_1 = operands[0];
   26089                 :        1590 :       reg_2 = operands[2];
   26090                 :             :     }
   26091                 :             :   else
   26092                 :             :     {
   26093                 :         349 :       mem_1 = operands[0];
   26094                 :         349 :       mem_2 = operands[2];
   26095                 :         349 :       reg_1 = operands[1];
   26096                 :         349 :       reg_2 = operands[3];
   26097                 :             :     }
   26098                 :             : 
   26099                 :        1939 :   gcc_assert (REG_P (reg_1) && REG_P (reg_2));
   26100                 :             : 
   26101                 :        1939 :   if (REGNO (reg_1) != REGNO (reg_2))
   26102                 :             :     return false;
   26103                 :             : 
   26104                 :             :   /* Check if the addresses are in the form of [base+offset].  */
   26105                 :        1939 :   if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
   26106                 :             :     return false;
   26107                 :        1567 :   if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
   26108                 :             :     return false;
   26109                 :             : 
   26110                 :             :   /* Check if the bases are the same.  */
   26111                 :         440 :   if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
   26112                 :         102 :     return false;
   26113                 :             : 
   26114                 :         338 :   offval_1 = INTVAL (offset_1);
   26115                 :         338 :   offval_2 = INTVAL (offset_2);
   26116                 :         338 :   msize = GET_MODE_SIZE (mode);
   26117                 :             :   /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address.  */
   26118                 :         338 :   if (offval_1 + msize != offval_2)
   26119                 :             :     return false;
   26120                 :             : 
   26121                 :             :   return true;
   26122                 :             : }
   26123                 :             : 
   26124                 :             : /* Implement the TARGET_OPTAB_SUPPORTED_P hook.  */
   26125                 :             : 
   26126                 :             : static bool
   26127                 :      293702 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
   26128                 :             :                         optimization_type opt_type)
   26129                 :             : {
   26130                 :      293702 :   switch (op)
   26131                 :             :     {
   26132                 :         227 :     case asin_optab:
   26133                 :         227 :     case acos_optab:
   26134                 :         227 :     case log1p_optab:
   26135                 :         227 :     case exp_optab:
   26136                 :         227 :     case exp10_optab:
   26137                 :         227 :     case exp2_optab:
   26138                 :         227 :     case expm1_optab:
   26139                 :         227 :     case ldexp_optab:
   26140                 :         227 :     case scalb_optab:
   26141                 :         227 :     case round_optab:
   26142                 :         227 :     case lround_optab:
   26143                 :         227 :       return opt_type == OPTIMIZE_FOR_SPEED;
   26144                 :             : 
   26145                 :         268 :     case rint_optab:
   26146                 :         268 :       if (SSE_FLOAT_MODE_P (mode1)
   26147                 :         145 :           && TARGET_SSE_MATH
   26148                 :         129 :           && !flag_trapping_math
   26149                 :          21 :           && !TARGET_SSE4_1
   26150                 :             :           && mode1 != HFmode)
   26151                 :          21 :         return opt_type == OPTIMIZE_FOR_SPEED;
   26152                 :             :       return true;
   26153                 :             : 
   26154                 :        1814 :     case floor_optab:
   26155                 :        1814 :     case ceil_optab:
   26156                 :        1814 :     case btrunc_optab:
   26157                 :        1814 :       if (((SSE_FLOAT_MODE_P (mode1)
   26158                 :        1508 :             && TARGET_SSE_MATH
   26159                 :        1429 :             && TARGET_SSE4_1)
   26160                 :        1765 :            || mode1 == HFmode)
   26161                 :         118 :           && !flag_trapping_math)
   26162                 :             :         return true;
   26163                 :        1754 :       return opt_type == OPTIMIZE_FOR_SPEED;
   26164                 :             : 
   26165                 :          82 :     case rsqrt_optab:
   26166                 :          82 :       return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
   26167                 :             : 
   26168                 :             :     default:
   26169                 :             :       return true;
   26170                 :             :     }
   26171                 :             : }
   26172                 :             : 
   26173                 :             : /* Address space support.
   26174                 :             : 
   26175                 :             :    This is not "far pointers" in the 16-bit sense, but an easy way
   26176                 :             :    to use %fs and %gs segment prefixes.  Therefore:
   26177                 :             : 
   26178                 :             :     (a) All address spaces have the same modes,
   26179                 :             :     (b) All address spaces have the same addresss forms,
   26180                 :             :     (c) While %fs and %gs are technically subsets of the generic
   26181                 :             :         address space, they are probably not subsets of each other.
   26182                 :             :     (d) Since we have no access to the segment base register values
   26183                 :             :         without resorting to a system call, we cannot convert a
   26184                 :             :         non-default address space to a default address space.
   26185                 :             :         Therefore we do not claim %fs or %gs are subsets of generic.
   26186                 :             : 
   26187                 :             :    Therefore we can (mostly) use the default hooks.  */
   26188                 :             : 
   26189                 :             : /* All use of segmentation is assumed to make address 0 valid.  */
   26190                 :             : 
   26191                 :             : static bool
   26192                 :    58416000 : ix86_addr_space_zero_address_valid (addr_space_t as)
   26193                 :             : {
   26194                 :    58416000 :   return as != ADDR_SPACE_GENERIC;
   26195                 :             : }
   26196                 :             : 
   26197                 :             : static void
   26198                 :      831501 : ix86_init_libfuncs (void)
   26199                 :             : {
   26200                 :      831501 :   if (TARGET_64BIT)
   26201                 :             :     {
   26202                 :      816173 :       set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
   26203                 :      816173 :       set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
   26204                 :             :     }
   26205                 :             :   else
   26206                 :             :     {
   26207                 :       15328 :       set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
   26208                 :       15328 :       set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
   26209                 :             :     }
   26210                 :             : 
   26211                 :             : #if TARGET_MACHO
   26212                 :             :   darwin_rename_builtins ();
   26213                 :             : #endif
   26214                 :      831501 : }
   26215                 :             : 
   26216                 :             : /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
   26217                 :             :    FPU, assume that the fpcw is set to extended precision; when using
   26218                 :             :    only SSE, rounding is correct; when using both SSE and the FPU,
   26219                 :             :    the rounding precision is indeterminate, since either may be chosen
   26220                 :             :    apparently at random.  */
   26221                 :             : 
   26222                 :             : static enum flt_eval_method
   26223                 :    89661983 : ix86_get_excess_precision (enum excess_precision_type type)
   26224                 :             : {
   26225                 :    89661983 :   switch (type)
   26226                 :             :     {
   26227                 :    85821861 :       case EXCESS_PRECISION_TYPE_FAST:
   26228                 :             :         /* The fastest type to promote to will always be the native type,
   26229                 :             :            whether that occurs with implicit excess precision or
   26230                 :             :            otherwise.  */
   26231                 :    85821861 :         return TARGET_AVX512FP16
   26232                 :    85821861 :                ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
   26233                 :    85821861 :                : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   26234                 :     3840041 :       case EXCESS_PRECISION_TYPE_STANDARD:
   26235                 :     3840041 :       case EXCESS_PRECISION_TYPE_IMPLICIT:
   26236                 :             :         /* Otherwise, the excess precision we want when we are
   26237                 :             :            in a standards compliant mode, and the implicit precision we
   26238                 :             :            provide would be identical were it not for the unpredictable
   26239                 :             :            cases.  */
   26240                 :     3840041 :         if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
   26241                 :             :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   26242                 :     3834266 :         else if (!TARGET_80387)
   26243                 :             :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   26244                 :     3828174 :         else if (!TARGET_MIX_SSE_I387)
   26245                 :             :           {
   26246                 :     3828002 :             if (!(TARGET_SSE && TARGET_SSE_MATH))
   26247                 :             :               return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
   26248                 :     2841712 :             else if (TARGET_SSE2)
   26249                 :             :               return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   26250                 :             :           }
   26251                 :             : 
   26252                 :             :         /* If we are in standards compliant mode, but we know we will
   26253                 :             :            calculate in unpredictable precision, return
   26254                 :             :            FLT_EVAL_METHOD_FLOAT.  There is no reason to introduce explicit
   26255                 :             :            excess precision if the target can't guarantee it will honor
   26256                 :             :            it.  */
   26257                 :         318 :         return (type == EXCESS_PRECISION_TYPE_STANDARD
   26258                 :         318 :                 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
   26259                 :             :                 : FLT_EVAL_METHOD_UNPREDICTABLE);
   26260                 :          81 :       case EXCESS_PRECISION_TYPE_FLOAT16:
   26261                 :          81 :         if (TARGET_80387
   26262                 :          75 :             && !(TARGET_SSE_MATH && TARGET_SSE))
   26263                 :           4 :           error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
   26264                 :             :         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   26265                 :           0 :       default:
   26266                 :           0 :         gcc_unreachable ();
   26267                 :             :     }
   26268                 :             : 
   26269                 :             :   return FLT_EVAL_METHOD_UNPREDICTABLE;
   26270                 :             : }
   26271                 :             : 
   26272                 :             : /* Return true if _BitInt(N) is supported and fill its details into *INFO.  */
   26273                 :             : bool
   26274                 :     1696738 : ix86_bitint_type_info (int n, struct bitint_info *info)
   26275                 :             : {
   26276                 :     1696738 :   if (n <= 8)
   26277                 :        3720 :     info->limb_mode = QImode;
   26278                 :     1693018 :   else if (n <= 16)
   26279                 :         851 :     info->limb_mode = HImode;
   26280                 :     1692167 :   else if (n <= 32 || (!TARGET_64BIT && n > 64))
   26281                 :       18633 :     info->limb_mode = SImode;
   26282                 :             :   else
   26283                 :     1673534 :     info->limb_mode = DImode;
   26284                 :     1696738 :   info->abi_limb_mode = info->limb_mode;
   26285                 :     1696738 :   info->big_endian = false;
   26286                 :     1696738 :   info->extended = false;
   26287                 :     1696738 :   return true;
   26288                 :             : }
   26289                 :             : 
   26290                 :             : /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return DFmode, TFmode
   26291                 :             :    or XFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
   26292                 :             :    based on long double bits, go with the default one for the others.  */
   26293                 :             : 
   26294                 :             : static machine_mode
   26295                 :     3583059 : ix86_c_mode_for_floating_type (enum tree_index ti)
   26296                 :             : {
   26297                 :     3583059 :   if (ti == TI_LONG_DOUBLE_TYPE)
   26298                 :     1195856 :     return (TARGET_LONG_DOUBLE_64 ? DFmode
   26299                 :      597918 :                                   : (TARGET_LONG_DOUBLE_128 ? TFmode : XFmode));
   26300                 :     2985109 :   return default_mode_for_floating_type (ti);
   26301                 :             : }
   26302                 :             : 
   26303                 :             : /* Returns modified FUNCTION_TYPE for cdtor callabi.  */
   26304                 :             : tree
   26305                 :       13327 : ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
   26306                 :             : {
   26307                 :       13327 :   if (TARGET_64BIT
   26308                 :          65 :       || TARGET_RTD
   26309                 :       13392 :       || ix86_function_type_abi (fntype) != MS_ABI)
   26310                 :       13327 :     return fntype;
   26311                 :             :   /* For 32-bit MS ABI add thiscall attribute.  */
   26312                 :           0 :   tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE,
   26313                 :           0 :                             TYPE_ATTRIBUTES (fntype));
   26314                 :           0 :   return build_type_attribute_variant (fntype, attribs);
   26315                 :             : }
   26316                 :             : 
   26317                 :             : /* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
   26318                 :             :    decrements by exactly 2 no matter what the position was, there is no pushb.
   26319                 :             : 
   26320                 :             :    But as CIE data alignment factor on this arch is -4 for 32bit targets
   26321                 :             :    and -8 for 64bit targets, we need to make sure all stack pointer adjustments
   26322                 :             :    are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
   26323                 :             : 
   26324                 :             : poly_int64
   26325                 :   257132604 : ix86_push_rounding (poly_int64 bytes)
   26326                 :             : {
   26327                 :   335417318 :   return ROUND_UP (bytes, UNITS_PER_WORD);
   26328                 :             : }
   26329                 :             : 
   26330                 :             : /* Use 8 bits metadata start from bit48 for LAM_U48,
   26331                 :             :    6 bits metadat start from bit57 for LAM_U57.  */
   26332                 :             : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48             \
   26333                 :             :                            ? 48                                 \
   26334                 :             :                            : (ix86_lam_type == lam_u57 ? 57 : 0))
   26335                 :             : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48          \
   26336                 :             :                               ? 8                               \
   26337                 :             :                               : (ix86_lam_type == lam_u57 ? 6 : 0))
   26338                 :             : 
   26339                 :             : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  */
   26340                 :             : bool
   26341                 :     6008244 : ix86_memtag_can_tag_addresses ()
   26342                 :             : {
   26343                 :     6008244 :   return ix86_lam_type != lam_none && TARGET_LP64;
   26344                 :             : }
   26345                 :             : 
   26346                 :             : /* Implement TARGET_MEMTAG_TAG_SIZE.  */
   26347                 :             : unsigned char
   26348                 :         440 : ix86_memtag_tag_size ()
   26349                 :             : {
   26350                 :         440 :   return IX86_HWASAN_TAG_SIZE;
   26351                 :             : }
   26352                 :             : 
   26353                 :             : /* Implement TARGET_MEMTAG_SET_TAG.  */
   26354                 :             : rtx
   26355                 :         104 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
   26356                 :             : {
   26357                 :             :   /* default_memtag_insert_random_tag may
   26358                 :             :      generate tag with value more than 6 bits.  */
   26359                 :         104 :   if (ix86_lam_type == lam_u57)
   26360                 :             :     {
   26361                 :         104 :       unsigned HOST_WIDE_INT and_imm
   26362                 :             :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   26363                 :             : 
   26364                 :         104 :       emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
   26365                 :             :     }
   26366                 :         104 :   tag = expand_simple_binop (Pmode, ASHIFT, tag,
   26367                 :         104 :                              GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
   26368                 :             :                              /* unsignedp = */1, OPTAB_WIDEN);
   26369                 :         104 :   rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
   26370                 :             :                                  /* unsignedp = */1, OPTAB_DIRECT);
   26371                 :         104 :   return ret;
   26372                 :             : }
   26373                 :             : 
   26374                 :             : /* Implement TARGET_MEMTAG_EXTRACT_TAG.  */
   26375                 :             : rtx
   26376                 :         176 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
   26377                 :             : {
   26378                 :         176 :   rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
   26379                 :         176 :                                  GEN_INT (IX86_HWASAN_SHIFT), target,
   26380                 :             :                                  /* unsignedp = */0,
   26381                 :             :                                  OPTAB_DIRECT);
   26382                 :         176 :   rtx ret = gen_reg_rtx (QImode);
   26383                 :             :   /* Mask off bit63 when LAM_U57.  */
   26384                 :         176 :   if (ix86_lam_type == lam_u57)
   26385                 :             :     {
   26386                 :         176 :       unsigned HOST_WIDE_INT and_imm
   26387                 :             :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   26388                 :         176 :       emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
   26389                 :         176 :                              gen_int_mode (and_imm, QImode)));
   26390                 :             :     }
   26391                 :             :   else
   26392                 :           0 :     emit_move_insn (ret, gen_lowpart (QImode, tag));
   26393                 :         176 :   return ret;
   26394                 :             : }
   26395                 :             : 
   26396                 :             : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER.  */
   26397                 :             : rtx
   26398                 :         112 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
   26399                 :             : {
   26400                 :             :   /* Leave bit63 alone.  */
   26401                 :         112 :   rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
   26402                 :         112 :                                 + (HOST_WIDE_INT_1U << 63) - 1),
   26403                 :         112 :                                Pmode);
   26404                 :         112 :   rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
   26405                 :             :                                            tag_mask, target, true,
   26406                 :             :                                            OPTAB_DIRECT);
   26407                 :         112 :   gcc_assert (untagged_base);
   26408                 :         112 :   return untagged_base;
   26409                 :             : }
   26410                 :             : 
   26411                 :             : /* Implement TARGET_MEMTAG_ADD_TAG.  */
   26412                 :             : rtx
   26413                 :          88 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
   26414                 :             : {
   26415                 :          88 :   rtx base_tag = gen_reg_rtx (QImode);
   26416                 :          88 :   rtx base_addr = gen_reg_rtx (Pmode);
   26417                 :          88 :   rtx tagged_addr = gen_reg_rtx (Pmode);
   26418                 :          88 :   rtx new_tag = gen_reg_rtx (QImode);
   26419                 :         176 :   unsigned HOST_WIDE_INT and_imm
   26420                 :          88 :     = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
   26421                 :             : 
   26422                 :             :   /* When there's "overflow" in tag adding,
   26423                 :             :      need to mask the most significant bit off.  */
   26424                 :          88 :   emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
   26425                 :          88 :   emit_move_insn (base_addr,
   26426                 :             :                   ix86_memtag_untagged_pointer (base, NULL_RTX));
   26427                 :          88 :   emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
   26428                 :          88 :   emit_move_insn (new_tag, base_tag);
   26429                 :          88 :   emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
   26430                 :          88 :   emit_move_insn (tagged_addr,
   26431                 :             :                   ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
   26432                 :          88 :   return plus_constant (Pmode, tagged_addr, offset);
   26433                 :             : }
   26434                 :             : 
   26435                 :             : /* Implement TARGET_HAVE_CCMP.  */
   26436                 :             : static bool
   26437                 :     7454661 : ix86_have_ccmp ()
   26438                 :             : {
   26439                 :     7454661 :   return (bool) TARGET_APX_CCMP;
   26440                 :             : }
   26441                 :             : 
   26442                 :             : /* Implement TARGET_MODE_CAN_TRANSFER_BITS.  */
   26443                 :             : static bool
   26444                 :     4382177 : ix86_mode_can_transfer_bits (machine_mode mode)
   26445                 :             : {
   26446                 :     4382177 :   if (GET_MODE_CLASS (mode) == MODE_FLOAT
   26447                 :     4339930 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
   26448                 :      103260 :     switch (GET_MODE_INNER (mode))
   26449                 :             :       {
   26450                 :       49414 :       case E_SFmode:
   26451                 :       49414 :       case E_DFmode:
   26452                 :             :         /* These suffer from normalization upon load when not using SSE.  */
   26453                 :       49414 :         return !(ix86_fpmath & FPMATH_387);
   26454                 :             :       default:
   26455                 :             :         return true;
   26456                 :             :       }
   26457                 :             : 
   26458                 :             :   return true;
   26459                 :             : }
   26460                 :             : 
   26461                 :             : /* Implement TARGET_REDZONE_CLOBBER.  */
   26462                 :             : static rtx
   26463                 :           2 : ix86_redzone_clobber ()
   26464                 :             : {
   26465                 :           2 :   cfun->machine->asm_redzone_clobber_seen = true;
   26466                 :           2 :   if (ix86_using_red_zone ())
   26467                 :             :     {
   26468                 :           2 :       rtx base = plus_constant (Pmode, stack_pointer_rtx,
   26469                 :           2 :                                 GEN_INT (-RED_ZONE_SIZE));
   26470                 :           2 :       rtx mem = gen_rtx_MEM (BLKmode, base);
   26471                 :           2 :       set_mem_size (mem, RED_ZONE_SIZE);
   26472                 :           2 :       return mem;
   26473                 :             :     }
   26474                 :             :   return NULL_RTX;
   26475                 :             : }
   26476                 :             : 
   26477                 :             : /* Target-specific selftests.  */
   26478                 :             : 
   26479                 :             : #if CHECKING_P
   26480                 :             : 
   26481                 :             : namespace selftest {
   26482                 :             : 
   26483                 :             : /* Verify that hard regs are dumped as expected (in compact mode).  */
   26484                 :             : 
   26485                 :             : static void
   26486                 :           4 : ix86_test_dumping_hard_regs ()
   26487                 :             : {
   26488                 :           4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
   26489                 :           4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
   26490                 :           4 : }
   26491                 :             : 
   26492                 :             : /* Test dumping an insn with repeated references to the same SCRATCH,
   26493                 :             :    to verify the rtx_reuse code.  */
   26494                 :             : 
   26495                 :             : static void
   26496                 :           4 : ix86_test_dumping_memory_blockage ()
   26497                 :             : {
   26498                 :           4 :   set_new_first_and_last_insn (NULL, NULL);
   26499                 :             : 
   26500                 :           4 :   rtx pat = gen_memory_blockage ();
   26501                 :           4 :   rtx_reuse_manager r;
   26502                 :           4 :   r.preprocess (pat);
   26503                 :             : 
   26504                 :             :   /* Verify that the repeated references to the SCRATCH show use
   26505                 :             :      reuse IDS.  The first should be prefixed with a reuse ID,
   26506                 :             :      and the second should be dumped as a "reuse_rtx" of that ID.
   26507                 :             :      The expected string assumes Pmode == DImode.  */
   26508                 :           4 :   if (Pmode == DImode)
   26509                 :           4 :     ASSERT_RTL_DUMP_EQ_WITH_REUSE
   26510                 :             :       ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0  A8])\n"
   26511                 :             :        "        (unspec:BLK [\n"
   26512                 :             :        "                (mem/v:BLK (reuse_rtx 0) [0  A8])\n"
   26513                 :             :        "            ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
   26514                 :           4 : }
   26515                 :             : 
   26516                 :             : /* Verify loading an RTL dump; specifically a dump of copying
   26517                 :             :    a param on x86_64 from a hard reg into the frame.
   26518                 :             :    This test is target-specific since the dump contains target-specific
   26519                 :             :    hard reg names.  */
   26520                 :             : 
   26521                 :             : static void
   26522                 :           4 : ix86_test_loading_dump_fragment_1 ()
   26523                 :             : {
   26524                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION,
   26525                 :           4 :                    locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
   26526                 :             : 
   26527                 :           4 :   rtx_insn *insn = get_insn_by_uid (1);
   26528                 :             : 
   26529                 :             :   /* The block structure and indentation here is purely for
   26530                 :             :      readability; it mirrors the structure of the rtx.  */
   26531                 :           4 :   tree mem_expr;
   26532                 :           4 :   {
   26533                 :           4 :     rtx pat = PATTERN (insn);
   26534                 :           4 :     ASSERT_EQ (SET, GET_CODE (pat));
   26535                 :           4 :     {
   26536                 :           4 :       rtx dest = SET_DEST (pat);
   26537                 :           4 :       ASSERT_EQ (MEM, GET_CODE (dest));
   26538                 :             :       /* Verify the "/c" was parsed.  */
   26539                 :           4 :       ASSERT_TRUE (RTX_FLAG (dest, call));
   26540                 :           4 :       ASSERT_EQ (SImode, GET_MODE (dest));
   26541                 :           4 :       {
   26542                 :           4 :         rtx addr = XEXP (dest, 0);
   26543                 :           4 :         ASSERT_EQ (PLUS, GET_CODE (addr));
   26544                 :           4 :         ASSERT_EQ (DImode, GET_MODE (addr));
   26545                 :           4 :         {
   26546                 :           4 :           rtx lhs = XEXP (addr, 0);
   26547                 :             :           /* Verify that the "frame" REG was consolidated.  */
   26548                 :           4 :           ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
   26549                 :             :         }
   26550                 :           4 :         {
   26551                 :           4 :           rtx rhs = XEXP (addr, 1);
   26552                 :           4 :           ASSERT_EQ (CONST_INT, GET_CODE (rhs));
   26553                 :           4 :           ASSERT_EQ (-4, INTVAL (rhs));
   26554                 :             :         }
   26555                 :             :       }
   26556                 :             :       /* Verify the "[1 i+0 S4 A32]" was parsed.  */
   26557                 :           4 :       ASSERT_EQ (1, MEM_ALIAS_SET (dest));
   26558                 :             :       /* "i" should have been handled by synthesizing a global int
   26559                 :             :          variable named "i".  */
   26560                 :           4 :       mem_expr = MEM_EXPR (dest);
   26561                 :           4 :       ASSERT_NE (mem_expr, NULL);
   26562                 :           4 :       ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
   26563                 :           4 :       ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
   26564                 :           4 :       ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
   26565                 :           4 :       ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
   26566                 :             :       /* "+0".  */
   26567                 :           4 :       ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
   26568                 :           4 :       ASSERT_EQ (0, MEM_OFFSET (dest));
   26569                 :             :       /* "S4".  */
   26570                 :           4 :       ASSERT_EQ (4, MEM_SIZE (dest));
   26571                 :             :       /* "A32.  */
   26572                 :           4 :       ASSERT_EQ (32, MEM_ALIGN (dest));
   26573                 :             :     }
   26574                 :           4 :     {
   26575                 :           4 :       rtx src = SET_SRC (pat);
   26576                 :           4 :       ASSERT_EQ (REG, GET_CODE (src));
   26577                 :           4 :       ASSERT_EQ (SImode, GET_MODE (src));
   26578                 :           4 :       ASSERT_EQ (5, REGNO (src));
   26579                 :           4 :       tree reg_expr = REG_EXPR (src);
   26580                 :             :       /* "i" here should point to the same var as for the MEM_EXPR.  */
   26581                 :           4 :       ASSERT_EQ (reg_expr, mem_expr);
   26582                 :             :     }
   26583                 :             :   }
   26584                 :           4 : }
   26585                 :             : 
   26586                 :             : /* Verify that the RTL loader copes with a call_insn dump.
   26587                 :             :    This test is target-specific since the dump contains a target-specific
   26588                 :             :    hard reg name.  */
   26589                 :             : 
   26590                 :             : static void
   26591                 :           4 : ix86_test_loading_call_insn ()
   26592                 :             : {
   26593                 :             :   /* The test dump includes register "xmm0", where requires TARGET_SSE
   26594                 :             :      to exist.  */
   26595                 :           4 :   if (!TARGET_SSE)
   26596                 :           0 :     return;
   26597                 :             : 
   26598                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
   26599                 :             : 
   26600                 :           4 :   rtx_insn *insn = get_insns ();
   26601                 :           4 :   ASSERT_EQ (CALL_INSN, GET_CODE (insn));
   26602                 :             : 
   26603                 :             :   /* "/j".  */
   26604                 :           4 :   ASSERT_TRUE (RTX_FLAG (insn, jump));
   26605                 :             : 
   26606                 :           4 :   rtx pat = PATTERN (insn);
   26607                 :           4 :   ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
   26608                 :             : 
   26609                 :             :   /* Verify REG_NOTES.  */
   26610                 :           4 :   {
   26611                 :             :     /* "(expr_list:REG_CALL_DECL".   */
   26612                 :           4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
   26613                 :           4 :     rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
   26614                 :           4 :     ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
   26615                 :             : 
   26616                 :             :     /* "(expr_list:REG_EH_REGION (const_int 0 [0])".  */
   26617                 :           4 :     rtx_expr_list *note1 = note0->next ();
   26618                 :           4 :     ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
   26619                 :             : 
   26620                 :           4 :     ASSERT_EQ (NULL, note1->next ());
   26621                 :             :   }
   26622                 :             : 
   26623                 :             :   /* Verify CALL_INSN_FUNCTION_USAGE.  */
   26624                 :           4 :   {
   26625                 :             :     /* "(expr_list:DF (use (reg:DF 21 xmm0))".  */
   26626                 :           4 :     rtx_expr_list *usage
   26627                 :           4 :       = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
   26628                 :           4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
   26629                 :           4 :     ASSERT_EQ (DFmode, GET_MODE (usage));
   26630                 :           4 :     ASSERT_EQ (USE, GET_CODE (usage->element ()));
   26631                 :           4 :     ASSERT_EQ (NULL, usage->next ());
   26632                 :             :   }
   26633                 :           4 : }
   26634                 :             : 
   26635                 :             : /* Verify that the RTL loader copes a dump from print_rtx_function.
   26636                 :             :    This test is target-specific since the dump contains target-specific
   26637                 :             :    hard reg names.  */
   26638                 :             : 
   26639                 :             : static void
   26640                 :           4 : ix86_test_loading_full_dump ()
   26641                 :             : {
   26642                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
   26643                 :             : 
   26644                 :           4 :   ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   26645                 :             : 
   26646                 :           4 :   rtx_insn *insn_1 = get_insn_by_uid (1);
   26647                 :           4 :   ASSERT_EQ (NOTE, GET_CODE (insn_1));
   26648                 :             : 
   26649                 :           4 :   rtx_insn *insn_7 = get_insn_by_uid (7);
   26650                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn_7));
   26651                 :           4 :   ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
   26652                 :             : 
   26653                 :           4 :   rtx_insn *insn_15 = get_insn_by_uid (15);
   26654                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn_15));
   26655                 :           4 :   ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
   26656                 :             : 
   26657                 :             :   /* Verify crtl->return_rtx.  */
   26658                 :           4 :   ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
   26659                 :           4 :   ASSERT_EQ (0, REGNO (crtl->return_rtx));
   26660                 :           4 :   ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
   26661                 :           4 : }
   26662                 :             : 
   26663                 :             : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
   26664                 :             :    In particular, verify that it correctly loads the 2nd operand.
   26665                 :             :    This test is target-specific since these are machine-specific
   26666                 :             :    operands (and enums).  */
   26667                 :             : 
   26668                 :             : static void
   26669                 :           4 : ix86_test_loading_unspec ()
   26670                 :             : {
   26671                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
   26672                 :             : 
   26673                 :           4 :   ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   26674                 :             : 
   26675                 :           4 :   ASSERT_TRUE (cfun);
   26676                 :             : 
   26677                 :             :   /* Test of an UNSPEC.  */
   26678                 :           4 :    rtx_insn *insn = get_insns ();
   26679                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   26680                 :           4 :   rtx set = single_set (insn);
   26681                 :           4 :   ASSERT_NE (NULL, set);
   26682                 :           4 :   rtx dst = SET_DEST (set);
   26683                 :           4 :   ASSERT_EQ (MEM, GET_CODE (dst));
   26684                 :           4 :   rtx src = SET_SRC (set);
   26685                 :           4 :   ASSERT_EQ (UNSPEC, GET_CODE (src));
   26686                 :           4 :   ASSERT_EQ (BLKmode, GET_MODE (src));
   26687                 :           4 :   ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
   26688                 :             : 
   26689                 :           4 :   rtx v0 = XVECEXP (src, 0, 0);
   26690                 :             : 
   26691                 :             :   /* Verify that the two uses of the first SCRATCH have pointer
   26692                 :             :      equality.  */
   26693                 :           4 :   rtx scratch_a = XEXP (dst, 0);
   26694                 :           4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
   26695                 :             : 
   26696                 :           4 :   rtx scratch_b = XEXP (v0, 0);
   26697                 :           4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
   26698                 :             : 
   26699                 :           4 :   ASSERT_EQ (scratch_a, scratch_b);
   26700                 :             : 
   26701                 :             :   /* Verify that the two mems are thus treated as equal.  */
   26702                 :           4 :   ASSERT_TRUE (rtx_equal_p (dst, v0));
   26703                 :             : 
   26704                 :             :   /* Verify that the insn is recognized.  */
   26705                 :           4 :   ASSERT_NE(-1, recog_memoized (insn));
   26706                 :             : 
   26707                 :             :   /* Test of an UNSPEC_VOLATILE, which has its own enum values.  */
   26708                 :           4 :   insn = NEXT_INSN (insn);
   26709                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   26710                 :             : 
   26711                 :           4 :   set = single_set (insn);
   26712                 :           4 :   ASSERT_NE (NULL, set);
   26713                 :             : 
   26714                 :           4 :   src = SET_SRC (set);
   26715                 :           4 :   ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
   26716                 :           4 :   ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
   26717                 :           4 : }
   26718                 :             : 
   26719                 :             : /* Run all target-specific selftests.  */
   26720                 :             : 
   26721                 :             : static void
   26722                 :           4 : ix86_run_selftests (void)
   26723                 :             : {
   26724                 :           4 :   ix86_test_dumping_hard_regs ();
   26725                 :           4 :   ix86_test_dumping_memory_blockage ();
   26726                 :             : 
   26727                 :             :   /* Various tests of loading RTL dumps, here because they contain
   26728                 :             :      ix86-isms (e.g. names of hard regs).  */
   26729                 :           4 :   ix86_test_loading_dump_fragment_1 ();
   26730                 :           4 :   ix86_test_loading_call_insn ();
   26731                 :           4 :   ix86_test_loading_full_dump ();
   26732                 :           4 :   ix86_test_loading_unspec ();
   26733                 :           4 : }
   26734                 :             : 
   26735                 :             : } // namespace selftest
   26736                 :             : 
   26737                 :             : #endif /* CHECKING_P */
   26738                 :             : 
   26739                 :             : static const scoped_attribute_specs *const ix86_attribute_table[] =
   26740                 :             : {
   26741                 :             :   &ix86_gnu_attribute_table
   26742                 :             : };
   26743                 :             : 
   26744                 :             : /* Initialize the GCC target structure.  */
   26745                 :             : #undef TARGET_RETURN_IN_MEMORY
   26746                 :             : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
   26747                 :             : 
   26748                 :             : #undef TARGET_LEGITIMIZE_ADDRESS
   26749                 :             : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
   26750                 :             : 
   26751                 :             : #undef TARGET_ATTRIBUTE_TABLE
   26752                 :             : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
   26753                 :             : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
   26754                 :             : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
   26755                 :             : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   26756                 :             : #  undef TARGET_MERGE_DECL_ATTRIBUTES
   26757                 :             : #  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
   26758                 :             : #endif
   26759                 :             : 
   26760                 :             : #undef TARGET_INVALID_CONVERSION
   26761                 :             : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
   26762                 :             : 
   26763                 :             : #undef TARGET_INVALID_UNARY_OP
   26764                 :             : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
   26765                 :             : 
   26766                 :             : #undef TARGET_INVALID_BINARY_OP
   26767                 :             : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
   26768                 :             : 
   26769                 :             : #undef TARGET_COMP_TYPE_ATTRIBUTES
   26770                 :             : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
   26771                 :             : 
   26772                 :             : #undef TARGET_INIT_BUILTINS
   26773                 :             : #define TARGET_INIT_BUILTINS ix86_init_builtins
   26774                 :             : #undef TARGET_BUILTIN_DECL
   26775                 :             : #define TARGET_BUILTIN_DECL ix86_builtin_decl
   26776                 :             : #undef TARGET_EXPAND_BUILTIN
   26777                 :             : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
   26778                 :             : 
   26779                 :             : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
   26780                 :             : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
   26781                 :             :   ix86_builtin_vectorized_function
   26782                 :             : 
   26783                 :             : #undef TARGET_VECTORIZE_BUILTIN_GATHER
   26784                 :             : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
   26785                 :             : 
   26786                 :             : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
   26787                 :             : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
   26788                 :             : 
   26789                 :             : #undef TARGET_BUILTIN_RECIPROCAL
   26790                 :             : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
   26791                 :             : 
   26792                 :             : #undef TARGET_ASM_FUNCTION_EPILOGUE
   26793                 :             : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
   26794                 :             : 
   26795                 :             : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
   26796                 :             : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
   26797                 :             :   ix86_print_patchable_function_entry
   26798                 :             : 
   26799                 :             : #undef TARGET_ENCODE_SECTION_INFO
   26800                 :             : #ifndef SUBTARGET_ENCODE_SECTION_INFO
   26801                 :             : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
   26802                 :             : #else
   26803                 :             : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
   26804                 :             : #endif
   26805                 :             : 
   26806                 :             : #undef TARGET_ASM_OPEN_PAREN
   26807                 :             : #define TARGET_ASM_OPEN_PAREN ""
   26808                 :             : #undef TARGET_ASM_CLOSE_PAREN
   26809                 :             : #define TARGET_ASM_CLOSE_PAREN ""
   26810                 :             : 
   26811                 :             : #undef TARGET_ASM_BYTE_OP
   26812                 :             : #define TARGET_ASM_BYTE_OP ASM_BYTE
   26813                 :             : 
   26814                 :             : #undef TARGET_ASM_ALIGNED_HI_OP
   26815                 :             : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
   26816                 :             : #undef TARGET_ASM_ALIGNED_SI_OP
   26817                 :             : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
   26818                 :             : #ifdef ASM_QUAD
   26819                 :             : #undef TARGET_ASM_ALIGNED_DI_OP
   26820                 :             : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
   26821                 :             : #endif
   26822                 :             : 
   26823                 :             : #undef TARGET_PROFILE_BEFORE_PROLOGUE
   26824                 :             : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
   26825                 :             : 
   26826                 :             : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
   26827                 :             : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
   26828                 :             : 
   26829                 :             : #undef TARGET_ASM_UNALIGNED_HI_OP
   26830                 :             : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
   26831                 :             : #undef TARGET_ASM_UNALIGNED_SI_OP
   26832                 :             : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
   26833                 :             : #undef TARGET_ASM_UNALIGNED_DI_OP
   26834                 :             : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
   26835                 :             : 
   26836                 :             : #undef TARGET_PRINT_OPERAND
   26837                 :             : #define TARGET_PRINT_OPERAND ix86_print_operand
   26838                 :             : #undef TARGET_PRINT_OPERAND_ADDRESS
   26839                 :             : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
   26840                 :             : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   26841                 :             : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
   26842                 :             : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
   26843                 :             : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
   26844                 :             : 
   26845                 :             : #undef TARGET_SCHED_INIT_GLOBAL
   26846                 :             : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
   26847                 :             : #undef TARGET_SCHED_ADJUST_COST
   26848                 :             : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
   26849                 :             : #undef TARGET_SCHED_ISSUE_RATE
   26850                 :             : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
   26851                 :             : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   26852                 :             : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   26853                 :             :   ia32_multipass_dfa_lookahead
   26854                 :             : #undef TARGET_SCHED_MACRO_FUSION_P
   26855                 :             : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
   26856                 :             : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
   26857                 :             : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
   26858                 :             : 
   26859                 :             : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   26860                 :             : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
   26861                 :             : 
   26862                 :             : #undef TARGET_MEMMODEL_CHECK
   26863                 :             : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
   26864                 :             : 
   26865                 :             : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   26866                 :             : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
   26867                 :             : 
   26868                 :             : #ifdef HAVE_AS_TLS
   26869                 :             : #undef TARGET_HAVE_TLS
   26870                 :             : #define TARGET_HAVE_TLS true
   26871                 :             : #endif
   26872                 :             : #undef TARGET_CANNOT_FORCE_CONST_MEM
   26873                 :             : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
   26874                 :             : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   26875                 :             : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   26876                 :             : 
   26877                 :             : #undef TARGET_DELEGITIMIZE_ADDRESS
   26878                 :             : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
   26879                 :             : 
   26880                 :             : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
   26881                 :             : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
   26882                 :             : 
   26883                 :             : #undef TARGET_MS_BITFIELD_LAYOUT_P
   26884                 :             : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
   26885                 :             : 
   26886                 :             : #if TARGET_MACHO
   26887                 :             : #undef TARGET_BINDS_LOCAL_P
   26888                 :             : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
   26889                 :             : #else
   26890                 :             : #undef TARGET_BINDS_LOCAL_P
   26891                 :             : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
   26892                 :             : #endif
   26893                 :             : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   26894                 :             : #undef TARGET_BINDS_LOCAL_P
   26895                 :             : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
   26896                 :             : #endif
   26897                 :             : 
   26898                 :             : #undef TARGET_ASM_OUTPUT_MI_THUNK
   26899                 :             : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
   26900                 :             : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   26901                 :             : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
   26902                 :             : 
   26903                 :             : #undef TARGET_ASM_FILE_START
   26904                 :             : #define TARGET_ASM_FILE_START x86_file_start
   26905                 :             : 
   26906                 :             : #undef TARGET_OPTION_OVERRIDE
   26907                 :             : #define TARGET_OPTION_OVERRIDE ix86_option_override
   26908                 :             : 
   26909                 :             : #undef TARGET_REGISTER_MOVE_COST
   26910                 :             : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
   26911                 :             : #undef TARGET_MEMORY_MOVE_COST
   26912                 :             : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
   26913                 :             : #undef TARGET_RTX_COSTS
   26914                 :             : #define TARGET_RTX_COSTS ix86_rtx_costs
   26915                 :             : #undef TARGET_INSN_COST
   26916                 :             : #define TARGET_INSN_COST ix86_insn_cost
   26917                 :             : #undef TARGET_ADDRESS_COST
   26918                 :             : #define TARGET_ADDRESS_COST ix86_address_cost
   26919                 :             : 
   26920                 :             : #undef TARGET_OVERLAP_OP_BY_PIECES_P
   26921                 :             : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
   26922                 :             : 
   26923                 :             : #undef TARGET_FLAGS_REGNUM
   26924                 :             : #define TARGET_FLAGS_REGNUM FLAGS_REG
   26925                 :             : #undef TARGET_FIXED_CONDITION_CODE_REGS
   26926                 :             : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
   26927                 :             : #undef TARGET_CC_MODES_COMPATIBLE
   26928                 :             : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
   26929                 :             : 
   26930                 :             : #undef TARGET_MACHINE_DEPENDENT_REORG
   26931                 :             : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
   26932                 :             : 
   26933                 :             : #undef TARGET_BUILD_BUILTIN_VA_LIST
   26934                 :             : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
   26935                 :             : 
   26936                 :             : #undef TARGET_FOLD_BUILTIN
   26937                 :             : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
   26938                 :             : 
   26939                 :             : #undef TARGET_GIMPLE_FOLD_BUILTIN
   26940                 :             : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
   26941                 :             : 
   26942                 :             : #undef TARGET_COMPARE_VERSION_PRIORITY
   26943                 :             : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
   26944                 :             : 
   26945                 :             : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
   26946                 :             : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
   26947                 :             :   ix86_generate_version_dispatcher_body
   26948                 :             : 
   26949                 :             : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
   26950                 :             : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
   26951                 :             :   ix86_get_function_versions_dispatcher
   26952                 :             : 
   26953                 :             : #undef TARGET_ENUM_VA_LIST_P
   26954                 :             : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
   26955                 :             : 
   26956                 :             : #undef TARGET_FN_ABI_VA_LIST
   26957                 :             : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
   26958                 :             : 
   26959                 :             : #undef TARGET_CANONICAL_VA_LIST_TYPE
   26960                 :             : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
   26961                 :             : 
   26962                 :             : #undef TARGET_EXPAND_BUILTIN_VA_START
   26963                 :             : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
   26964                 :             : 
   26965                 :             : #undef TARGET_MD_ASM_ADJUST
   26966                 :             : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
   26967                 :             : 
   26968                 :             : #undef TARGET_C_EXCESS_PRECISION
   26969                 :             : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
   26970                 :             : #undef TARGET_C_BITINT_TYPE_INFO
   26971                 :             : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
   26972                 :             : #undef TARGET_C_MODE_FOR_FLOATING_TYPE
   26973                 :             : #define TARGET_C_MODE_FOR_FLOATING_TYPE ix86_c_mode_for_floating_type
   26974                 :             : #undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE
   26975                 :             : #define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype
   26976                 :             : #undef TARGET_PROMOTE_PROTOTYPES
   26977                 :             : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
   26978                 :             : #undef TARGET_PUSH_ARGUMENT
   26979                 :             : #define TARGET_PUSH_ARGUMENT ix86_push_argument
   26980                 :             : #undef TARGET_SETUP_INCOMING_VARARGS
   26981                 :             : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
   26982                 :             : #undef TARGET_MUST_PASS_IN_STACK
   26983                 :             : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
   26984                 :             : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
   26985                 :             : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
   26986                 :             : #undef TARGET_FUNCTION_ARG_ADVANCE
   26987                 :             : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
   26988                 :             : #undef TARGET_FUNCTION_ARG
   26989                 :             : #define TARGET_FUNCTION_ARG ix86_function_arg
   26990                 :             : #undef TARGET_INIT_PIC_REG
   26991                 :             : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
   26992                 :             : #undef TARGET_USE_PSEUDO_PIC_REG
   26993                 :             : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
   26994                 :             : #undef TARGET_FUNCTION_ARG_BOUNDARY
   26995                 :             : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
   26996                 :             : #undef TARGET_PASS_BY_REFERENCE
   26997                 :             : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
   26998                 :             : #undef TARGET_INTERNAL_ARG_POINTER
   26999                 :             : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
   27000                 :             : #undef TARGET_UPDATE_STACK_BOUNDARY
   27001                 :             : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
   27002                 :             : #undef TARGET_GET_DRAP_RTX
   27003                 :             : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
   27004                 :             : #undef TARGET_STRICT_ARGUMENT_NAMING
   27005                 :             : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   27006                 :             : #undef TARGET_STATIC_CHAIN
   27007                 :             : #define TARGET_STATIC_CHAIN ix86_static_chain
   27008                 :             : #undef TARGET_TRAMPOLINE_INIT
   27009                 :             : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
   27010                 :             : #undef TARGET_RETURN_POPS_ARGS
   27011                 :             : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
   27012                 :             : 
   27013                 :             : #undef TARGET_WARN_FUNC_RETURN
   27014                 :             : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
   27015                 :             : 
   27016                 :             : #undef TARGET_LEGITIMATE_COMBINED_INSN
   27017                 :             : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
   27018                 :             : 
   27019                 :             : #undef TARGET_ASAN_SHADOW_OFFSET
   27020                 :             : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
   27021                 :             : 
   27022                 :             : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
   27023                 :             : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
   27024                 :             : 
   27025                 :             : #undef TARGET_SCALAR_MODE_SUPPORTED_P
   27026                 :             : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
   27027                 :             : 
   27028                 :             : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
   27029                 :             : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
   27030                 :             : ix86_libgcc_floating_mode_supported_p
   27031                 :             : 
   27032                 :             : #undef TARGET_VECTOR_MODE_SUPPORTED_P
   27033                 :             : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
   27034                 :             : 
   27035                 :             : #undef TARGET_C_MODE_FOR_SUFFIX
   27036                 :             : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
   27037                 :             : 
   27038                 :             : #ifdef HAVE_AS_TLS
   27039                 :             : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   27040                 :             : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
   27041                 :             : #endif
   27042                 :             : 
   27043                 :             : #ifdef SUBTARGET_INSERT_ATTRIBUTES
   27044                 :             : #undef TARGET_INSERT_ATTRIBUTES
   27045                 :             : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
   27046                 :             : #endif
   27047                 :             : 
   27048                 :             : #undef TARGET_MANGLE_TYPE
   27049                 :             : #define TARGET_MANGLE_TYPE ix86_mangle_type
   27050                 :             : 
   27051                 :             : #undef TARGET_EMIT_SUPPORT_TINFOS
   27052                 :             : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
   27053                 :             : 
   27054                 :             : #undef TARGET_STACK_PROTECT_GUARD
   27055                 :             : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
   27056                 :             : 
   27057                 :             : #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
   27058                 :             : #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \
   27059                 :             :   ix86_stack_protect_runtime_enabled_p
   27060                 :             : 
   27061                 :             : #if !TARGET_MACHO
   27062                 :             : #undef TARGET_STACK_PROTECT_FAIL
   27063                 :             : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
   27064                 :             : #endif
   27065                 :             : 
   27066                 :             : #undef TARGET_FUNCTION_VALUE
   27067                 :             : #define TARGET_FUNCTION_VALUE ix86_function_value
   27068                 :             : 
   27069                 :             : #undef TARGET_FUNCTION_VALUE_REGNO_P
   27070                 :             : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
   27071                 :             : 
   27072                 :             : #undef TARGET_ZERO_CALL_USED_REGS
   27073                 :             : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
   27074                 :             : 
   27075                 :             : #undef TARGET_PROMOTE_FUNCTION_MODE
   27076                 :             : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
   27077                 :             : 
   27078                 :             : #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
   27079                 :             : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
   27080                 :             : 
   27081                 :             : #undef TARGET_MEMBER_TYPE_FORCES_BLK
   27082                 :             : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
   27083                 :             : 
   27084                 :             : #undef TARGET_INSTANTIATE_DECLS
   27085                 :             : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
   27086                 :             : 
   27087                 :             : #undef TARGET_SECONDARY_RELOAD
   27088                 :             : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
   27089                 :             : #undef TARGET_SECONDARY_MEMORY_NEEDED
   27090                 :             : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
   27091                 :             : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
   27092                 :             : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
   27093                 :             : 
   27094                 :             : #undef TARGET_CLASS_MAX_NREGS
   27095                 :             : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
   27096                 :             : 
   27097                 :             : #undef TARGET_PREFERRED_RELOAD_CLASS
   27098                 :             : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
   27099                 :             : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
   27100                 :             : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
   27101                 :             : /* When this hook returns true for MODE, the compiler allows
   27102                 :             :    registers explicitly used in the rtl to be used as spill registers
   27103                 :             :    but prevents the compiler from extending the lifetime of these
   27104                 :             :    registers.  */
   27105                 :             : #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
   27106                 :             : #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
   27107                 :             : #undef TARGET_CLASS_LIKELY_SPILLED_P
   27108                 :             : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
   27109                 :             : #undef TARGET_CALLEE_SAVE_COST
   27110                 :             : #define TARGET_CALLEE_SAVE_COST ix86_callee_save_cost
   27111                 :             : 
   27112                 :             : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
   27113                 :             : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   27114                 :             :   ix86_builtin_vectorization_cost
   27115                 :             : #undef TARGET_VECTORIZE_VEC_PERM_CONST
   27116                 :             : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
   27117                 :             : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
   27118                 :             : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
   27119                 :             :   ix86_preferred_simd_mode
   27120                 :             : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
   27121                 :             : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
   27122                 :             :   ix86_split_reduction
   27123                 :             : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
   27124                 :             : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
   27125                 :             :   ix86_autovectorize_vector_modes
   27126                 :             : #undef TARGET_VECTORIZE_GET_MASK_MODE
   27127                 :             : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
   27128                 :             : #undef TARGET_VECTORIZE_CREATE_COSTS
   27129                 :             : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
   27130                 :             : 
   27131                 :             : #undef TARGET_SET_CURRENT_FUNCTION
   27132                 :             : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
   27133                 :             : 
   27134                 :             : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
   27135                 :             : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
   27136                 :             : 
   27137                 :             : #undef TARGET_OPTION_SAVE
   27138                 :             : #define TARGET_OPTION_SAVE ix86_function_specific_save
   27139                 :             : 
   27140                 :             : #undef TARGET_OPTION_RESTORE
   27141                 :             : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
   27142                 :             : 
   27143                 :             : #undef TARGET_OPTION_POST_STREAM_IN
   27144                 :             : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
   27145                 :             : 
   27146                 :             : #undef TARGET_OPTION_PRINT
   27147                 :             : #define TARGET_OPTION_PRINT ix86_function_specific_print
   27148                 :             : 
   27149                 :             : #undef TARGET_OPTION_FUNCTION_VERSIONS
   27150                 :             : #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
   27151                 :             : 
   27152                 :             : #undef TARGET_CAN_INLINE_P
   27153                 :             : #define TARGET_CAN_INLINE_P ix86_can_inline_p
   27154                 :             : 
   27155                 :             : #undef TARGET_LEGITIMATE_ADDRESS_P
   27156                 :             : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
   27157                 :             : 
   27158                 :             : #undef TARGET_REGISTER_PRIORITY
   27159                 :             : #define TARGET_REGISTER_PRIORITY ix86_register_priority
   27160                 :             : 
   27161                 :             : #undef TARGET_REGISTER_USAGE_LEVELING_P
   27162                 :             : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
   27163                 :             : 
   27164                 :             : #undef TARGET_LEGITIMATE_CONSTANT_P
   27165                 :             : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
   27166                 :             : 
   27167                 :             : #undef TARGET_COMPUTE_FRAME_LAYOUT
   27168                 :             : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
   27169                 :             : 
   27170                 :             : #undef TARGET_FRAME_POINTER_REQUIRED
   27171                 :             : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
   27172                 :             : 
   27173                 :             : #undef TARGET_CAN_ELIMINATE
   27174                 :             : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
   27175                 :             : 
   27176                 :             : #undef TARGET_EXTRA_LIVE_ON_ENTRY
   27177                 :             : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
   27178                 :             : 
   27179                 :             : #undef TARGET_ASM_CODE_END
   27180                 :             : #define TARGET_ASM_CODE_END ix86_code_end
   27181                 :             : 
   27182                 :             : #undef TARGET_CONDITIONAL_REGISTER_USAGE
   27183                 :             : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
   27184                 :             : 
   27185                 :             : #undef TARGET_CANONICALIZE_COMPARISON
   27186                 :             : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
   27187                 :             : 
   27188                 :             : #undef TARGET_LOOP_UNROLL_ADJUST
   27189                 :             : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
   27190                 :             : 
   27191                 :             : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   27192                 :             : #undef TARGET_SPILL_CLASS
   27193                 :             : #define TARGET_SPILL_CLASS ix86_spill_class
   27194                 :             : 
   27195                 :             : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
   27196                 :             : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
   27197                 :             :   ix86_simd_clone_compute_vecsize_and_simdlen
   27198                 :             : 
   27199                 :             : #undef TARGET_SIMD_CLONE_ADJUST
   27200                 :             : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
   27201                 :             : 
   27202                 :             : #undef TARGET_SIMD_CLONE_USABLE
   27203                 :             : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
   27204                 :             : 
   27205                 :             : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
   27206                 :             : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
   27207                 :             : 
   27208                 :             : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
   27209                 :             : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
   27210                 :             :   ix86_float_exceptions_rounding_supported_p
   27211                 :             : 
   27212                 :             : #undef TARGET_MODE_EMIT
   27213                 :             : #define TARGET_MODE_EMIT ix86_emit_mode_set
   27214                 :             : 
   27215                 :             : #undef TARGET_MODE_NEEDED
   27216                 :             : #define TARGET_MODE_NEEDED ix86_mode_needed
   27217                 :             : 
   27218                 :             : #undef TARGET_MODE_AFTER
   27219                 :             : #define TARGET_MODE_AFTER ix86_mode_after
   27220                 :             : 
   27221                 :             : #undef TARGET_MODE_ENTRY
   27222                 :             : #define TARGET_MODE_ENTRY ix86_mode_entry
   27223                 :             : 
   27224                 :             : #undef TARGET_MODE_EXIT
   27225                 :             : #define TARGET_MODE_EXIT ix86_mode_exit
   27226                 :             : 
   27227                 :             : #undef TARGET_MODE_PRIORITY
   27228                 :             : #define TARGET_MODE_PRIORITY ix86_mode_priority
   27229                 :             : 
   27230                 :             : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
   27231                 :             : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
   27232                 :             : 
   27233                 :             : #undef TARGET_OFFLOAD_OPTIONS
   27234                 :             : #define TARGET_OFFLOAD_OPTIONS \
   27235                 :             :   ix86_offload_options
   27236                 :             : 
   27237                 :             : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
   27238                 :             : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
   27239                 :             : 
   27240                 :             : #undef TARGET_OPTAB_SUPPORTED_P
   27241                 :             : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
   27242                 :             : 
   27243                 :             : #undef TARGET_HARD_REGNO_SCRATCH_OK
   27244                 :             : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
   27245                 :             : 
   27246                 :             : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
   27247                 :             : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
   27248                 :             : 
   27249                 :             : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
   27250                 :             : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
   27251                 :             : 
   27252                 :             : #undef TARGET_INIT_LIBFUNCS
   27253                 :             : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
   27254                 :             : 
   27255                 :             : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
   27256                 :             : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
   27257                 :             : 
   27258                 :             : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
   27259                 :             : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
   27260                 :             : 
   27261                 :             : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
   27262                 :             : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
   27263                 :             : 
   27264                 :             : #undef TARGET_HARD_REGNO_NREGS
   27265                 :             : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
   27266                 :             : #undef TARGET_HARD_REGNO_MODE_OK
   27267                 :             : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
   27268                 :             : 
   27269                 :             : #undef TARGET_MODES_TIEABLE_P
   27270                 :             : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
   27271                 :             : 
   27272                 :             : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
   27273                 :             : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
   27274                 :             :   ix86_hard_regno_call_part_clobbered
   27275                 :             : 
   27276                 :             : #undef TARGET_INSN_CALLEE_ABI
   27277                 :             : #define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi
   27278                 :             : 
   27279                 :             : #undef TARGET_CAN_CHANGE_MODE_CLASS
   27280                 :             : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
   27281                 :             : 
   27282                 :             : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
   27283                 :             : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
   27284                 :             : 
   27285                 :             : #undef TARGET_STATIC_RTX_ALIGNMENT
   27286                 :             : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
   27287                 :             : #undef TARGET_CONSTANT_ALIGNMENT
   27288                 :             : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
   27289                 :             : 
   27290                 :             : #undef TARGET_EMPTY_RECORD_P
   27291                 :             : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
   27292                 :             : 
   27293                 :             : #undef TARGET_WARN_PARAMETER_PASSING_ABI
   27294                 :             : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
   27295                 :             : 
   27296                 :             : #undef TARGET_GET_MULTILIB_ABI_NAME
   27297                 :             : #define TARGET_GET_MULTILIB_ABI_NAME \
   27298                 :             :   ix86_get_multilib_abi_name
   27299                 :             : 
   27300                 :             : #undef TARGET_IFUNC_REF_LOCAL_OK
   27301                 :             : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
   27302                 :             : 
   27303                 :             : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   27304                 :             : # undef TARGET_ASM_RELOC_RW_MASK
   27305                 :             : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
   27306                 :             : #endif
   27307                 :             : 
   27308                 :             : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
   27309                 :             : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
   27310                 :             : 
   27311                 :             : #undef TARGET_MEMTAG_ADD_TAG
   27312                 :             : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
   27313                 :             : 
   27314                 :             : #undef TARGET_MEMTAG_SET_TAG
   27315                 :             : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
   27316                 :             : 
   27317                 :             : #undef TARGET_MEMTAG_EXTRACT_TAG
   27318                 :             : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
   27319                 :             : 
   27320                 :             : #undef TARGET_MEMTAG_UNTAGGED_POINTER
   27321                 :             : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
   27322                 :             : 
   27323                 :             : #undef TARGET_MEMTAG_TAG_SIZE
   27324                 :             : #define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size
   27325                 :             : 
   27326                 :             : #undef TARGET_GEN_CCMP_FIRST
   27327                 :             : #define TARGET_GEN_CCMP_FIRST ix86_gen_ccmp_first
   27328                 :             : 
   27329                 :             : #undef TARGET_GEN_CCMP_NEXT
   27330                 :             : #define TARGET_GEN_CCMP_NEXT ix86_gen_ccmp_next
   27331                 :             : 
   27332                 :             : #undef TARGET_HAVE_CCMP
   27333                 :             : #define TARGET_HAVE_CCMP ix86_have_ccmp
   27334                 :             : 
   27335                 :             : #undef TARGET_MODE_CAN_TRANSFER_BITS
   27336                 :             : #define TARGET_MODE_CAN_TRANSFER_BITS ix86_mode_can_transfer_bits
   27337                 :             : 
   27338                 :             : #undef TARGET_REDZONE_CLOBBER
   27339                 :             : #define TARGET_REDZONE_CLOBBER ix86_redzone_clobber
   27340                 :             : 
   27341                 :             : static bool
   27342                 :       73978 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
   27343                 :             : {
   27344                 :             : #ifdef OPTION_GLIBC
   27345                 :       73978 :   if (OPTION_GLIBC)
   27346                 :       73978 :     return (built_in_function)fcode == BUILT_IN_MEMPCPY;
   27347                 :             :   else
   27348                 :             :     return false;
   27349                 :             : #else
   27350                 :             :   return false;
   27351                 :             : #endif
   27352                 :             : }
   27353                 :             : 
   27354                 :             : #undef TARGET_LIBC_HAS_FAST_FUNCTION
   27355                 :             : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
   27356                 :             : 
   27357                 :             : static unsigned
   27358                 :       70405 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
   27359                 :             :                               bool boundary_p)
   27360                 :             : {
   27361                 :             : #ifdef OPTION_GLIBC
   27362                 :       70405 :   bool glibc_p = OPTION_GLIBC;
   27363                 :             : #else
   27364                 :             :   bool glibc_p = false;
   27365                 :             : #endif
   27366                 :       70405 :   if (glibc_p)
   27367                 :             :     {
   27368                 :             :       /* If __FAST_MATH__ is defined, glibc provides libmvec.  */
   27369                 :       70405 :       unsigned int libmvec_ret = 0;
   27370                 :       70405 :       if (!flag_trapping_math
   27371                 :        8023 :           && flag_unsafe_math_optimizations
   27372                 :        3390 :           && flag_finite_math_only
   27373                 :        3364 :           && !flag_signed_zeros
   27374                 :        3364 :           && !flag_errno_math)
   27375                 :        3364 :         switch (cfn)
   27376                 :             :           {
   27377                 :        1408 :           CASE_CFN_COS:
   27378                 :        1408 :           CASE_CFN_COS_FN:
   27379                 :        1408 :           CASE_CFN_SIN:
   27380                 :        1408 :           CASE_CFN_SIN_FN:
   27381                 :        1408 :             if (!boundary_p)
   27382                 :             :               {
   27383                 :             :                 /* With non-default rounding modes, libmvec provides
   27384                 :             :                    complete garbage in results.  E.g.
   27385                 :             :                    _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
   27386                 :             :                    returns 0.00333309174f rather than 1.40129846e-45f.  */
   27387                 :         593 :                 if (flag_rounding_math)
   27388                 :             :                   return ~0U;
   27389                 :             :                 /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
   27390                 :             :                    claims libmvec maximum error is 4ulps.
   27391                 :             :                    My own random testing indicates 2ulps for SFmode and
   27392                 :             :                    0.5ulps for DFmode, but let's go with the 4ulps.  */
   27393                 :             :                 libmvec_ret = 4;
   27394                 :             :               }
   27395                 :             :             break;
   27396                 :             :           default:
   27397                 :             :             break;
   27398                 :             :           }
   27399                 :       70405 :       unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
   27400                 :             :                                                               boundary_p);
   27401                 :       70405 :       return MAX (ret, libmvec_ret);
   27402                 :             :     }
   27403                 :           0 :   return default_libm_function_max_error (cfn, mode, boundary_p);
   27404                 :             : }
   27405                 :             : 
   27406                 :             : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
   27407                 :             : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
   27408                 :             : 
   27409                 :             : #if TARGET_MACHO
   27410                 :             : static bool
   27411                 :             : ix86_cannot_copy_insn_p (rtx_insn *insn)
   27412                 :             : {
   27413                 :             :   if (TARGET_64BIT)
   27414                 :             :     return false;
   27415                 :             : 
   27416                 :             :   rtx set = single_set (insn);
   27417                 :             :   if (set)
   27418                 :             :     {
   27419                 :             :       rtx src = SET_SRC (set);
   27420                 :             :       if (GET_CODE (src) == UNSPEC
   27421                 :             :           && XINT (src, 1) == UNSPEC_SET_GOT)
   27422                 :             :         return true;
   27423                 :             :     }
   27424                 :             :   return false;
   27425                 :             : }
   27426                 :             : 
   27427                 :             : #undef TARGET_CANNOT_COPY_INSN_P
   27428                 :             : #define TARGET_CANNOT_COPY_INSN_P ix86_cannot_copy_insn_p
   27429                 :             : 
   27430                 :             : #endif
   27431                 :             : 
   27432                 :             : #if CHECKING_P
   27433                 :             : #undef TARGET_RUN_TARGET_SELFTESTS
   27434                 :             : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
   27435                 :             : #endif /* #if CHECKING_P */
   27436                 :             : 
   27437                 :             : #undef TARGET_DOCUMENTATION_NAME
   27438                 :             : #define TARGET_DOCUMENTATION_NAME "x86"
   27439                 :             : 
   27440                 :             : struct gcc_target targetm = TARGET_INITIALIZER;
   27441                 :             : 
   27442                 :             : #include "gt-i386.h"
        

Generated by: LCOV version 2.1-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.