LCOV - code coverage report
Current view: top level - gcc/config/i386 - i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.4 % 11969 10584
Test Date: 2024-04-13 14:00:49 Functions: 94.8 % 441 418
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-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify
       7                 :             : it under the terms of the GNU General Public License as published by
       8                 :             : the Free Software Foundation; either version 3, or (at your option)
       9                 :             : any later version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful,
      12                 :             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :             : GNU General Public License for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #define INCLUDE_STRING
      21                 :             : #define IN_TARGET_CODE 1
      22                 :             : 
      23                 :             : #include "config.h"
      24                 :             : #include "system.h"
      25                 :             : #include "coretypes.h"
      26                 :             : #include "backend.h"
      27                 :             : #include "rtl.h"
      28                 :             : #include "tree.h"
      29                 :             : #include "memmodel.h"
      30                 :             : #include "gimple.h"
      31                 :             : #include "cfghooks.h"
      32                 :             : #include "cfgloop.h"
      33                 :             : #include "df.h"
      34                 :             : #include "tm_p.h"
      35                 :             : #include "stringpool.h"
      36                 :             : #include "expmed.h"
      37                 :             : #include "optabs.h"
      38                 :             : #include "regs.h"
      39                 :             : #include "emit-rtl.h"
      40                 :             : #include "recog.h"
      41                 :             : #include "cgraph.h"
      42                 :             : #include "diagnostic.h"
      43                 :             : #include "cfgbuild.h"
      44                 :             : #include "alias.h"
      45                 :             : #include "fold-const.h"
      46                 :             : #include "attribs.h"
      47                 :             : #include "calls.h"
      48                 :             : #include "stor-layout.h"
      49                 :             : #include "varasm.h"
      50                 :             : #include "output.h"
      51                 :             : #include "insn-attr.h"
      52                 :             : #include "flags.h"
      53                 :             : #include "except.h"
      54                 :             : #include "explow.h"
      55                 :             : #include "expr.h"
      56                 :             : #include "cfgrtl.h"
      57                 :             : #include "common/common-target.h"
      58                 :             : #include "langhooks.h"
      59                 :             : #include "reload.h"
      60                 :             : #include "gimplify.h"
      61                 :             : #include "dwarf2.h"
      62                 :             : #include "tm-constrs.h"
      63                 :             : #include "cselib.h"
      64                 :             : #include "sched-int.h"
      65                 :             : #include "opts.h"
      66                 :             : #include "tree-pass.h"
      67                 :             : #include "context.h"
      68                 :             : #include "pass_manager.h"
      69                 :             : #include "target-globals.h"
      70                 :             : #include "gimple-iterator.h"
      71                 :             : #include "gimple-fold.h"
      72                 :             : #include "tree-vectorizer.h"
      73                 :             : #include "shrink-wrap.h"
      74                 :             : #include "builtins.h"
      75                 :             : #include "rtl-iter.h"
      76                 :             : #include "tree-iterator.h"
      77                 :             : #include "dbgcnt.h"
      78                 :             : #include "case-cfn-macros.h"
      79                 :             : #include "dojump.h"
      80                 :             : #include "fold-const-call.h"
      81                 :             : #include "tree-vrp.h"
      82                 :             : #include "tree-ssanames.h"
      83                 :             : #include "selftest.h"
      84                 :             : #include "selftest-rtl.h"
      85                 :             : #include "print-rtl.h"
      86                 :             : #include "intl.h"
      87                 :             : #include "ifcvt.h"
      88                 :             : #include "symbol-summary.h"
      89                 :             : #include "sreal.h"
      90                 :             : #include "ipa-cp.h"
      91                 :             : #include "ipa-prop.h"
      92                 :             : #include "ipa-fnsummary.h"
      93                 :             : #include "wide-int-bitmask.h"
      94                 :             : #include "tree-vector-builder.h"
      95                 :             : #include "debug.h"
      96                 :             : #include "dwarf2out.h"
      97                 :             : #include "i386-options.h"
      98                 :             : #include "i386-builtins.h"
      99                 :             : #include "i386-expand.h"
     100                 :             : #include "i386-features.h"
     101                 :             : #include "function-abi.h"
     102                 :             : #include "rtl-error.h"
     103                 :             : 
     104                 :             : /* This file should be included last.  */
     105                 :             : #include "target-def.h"
     106                 :             : 
     107                 :             : static rtx legitimize_dllimport_symbol (rtx, bool);
     108                 :             : static rtx legitimize_pe_coff_extern_decl (rtx, bool);
     109                 :             : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
     110                 :             : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
     111                 :             : 
     112                 :             : 
     113                 :             : #ifndef CHECK_STACK_LIMIT
     114                 :             : #define CHECK_STACK_LIMIT (-1)
     115                 :             : #endif
     116                 :             : 
     117                 :             : /* Return index of given mode in mult and division cost tables.  */
     118                 :             : #define MODE_INDEX(mode)                                        \
     119                 :             :   ((mode) == QImode ? 0                                         \
     120                 :             :    : (mode) == HImode ? 1                                       \
     121                 :             :    : (mode) == SImode ? 2                                       \
     122                 :             :    : (mode) == DImode ? 3                                       \
     123                 :             :    : 4)
     124                 :             : 
     125                 :             : 
     126                 :             : /* Set by -mtune.  */
     127                 :             : const struct processor_costs *ix86_tune_cost = NULL;
     128                 :             : 
     129                 :             : /* Set by -mtune or -Os.  */
     130                 :             : const struct processor_costs *ix86_cost = NULL;
     131                 :             : 
     132                 :             : /* In case the average insn count for single function invocation is
     133                 :             :    lower than this constant, emit fast (but longer) prologue and
     134                 :             :    epilogue code.  */
     135                 :             : #define FAST_PROLOGUE_INSN_COUNT 20
     136                 :             : 
     137                 :             : /* Names for 8 (low), 8 (high), and 16-bit registers, respectively.  */
     138                 :             : static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
     139                 :             : static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
     140                 :             : static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
     141                 :             : 
     142                 :             : /* Array of the smallest class containing reg number REGNO, indexed by
     143                 :             :    REGNO.  Used by REGNO_REG_CLASS in i386.h.  */
     144                 :             : 
     145                 :             : enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
     146                 :             : {
     147                 :             :   /* ax, dx, cx, bx */
     148                 :             :   AREG, DREG, CREG, BREG,
     149                 :             :   /* si, di, bp, sp */
     150                 :             :   SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
     151                 :             :   /* FP registers */
     152                 :             :   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
     153                 :             :   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
     154                 :             :   /* arg pointer, flags, fpsr, frame */
     155                 :             :   NON_Q_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
     156                 :             :   /* SSE registers */
     157                 :             :   SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS,
     158                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     159                 :             :   /* MMX registers */
     160                 :             :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     161                 :             :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     162                 :             :   /* REX registers */
     163                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     164                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     165                 :             :   /* SSE REX registers */
     166                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     167                 :             :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     168                 :             :   /* AVX-512 SSE registers */
     169                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     170                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     171                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     172                 :             :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     173                 :             :   /* Mask registers.  */
     174                 :             :   ALL_MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     175                 :             :   MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     176                 :             :   /* REX2 registers */
     177                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     178                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     179                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     180                 :             :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     181                 :             : };
     182                 :             : 
     183                 :             : /* The "default" register map used in 32bit mode.  */
     184                 :             : 
     185                 :             : int const debugger_register_map[FIRST_PSEUDO_REGISTER] =
     186                 :             : {
     187                 :             :   /* general regs */
     188                 :             :   0, 2, 1, 3, 6, 7, 4, 5,
     189                 :             :   /* fp regs */
     190                 :             :   12, 13, 14, 15, 16, 17, 18, 19,
     191                 :             :   /* arg, flags, fpsr, frame */
     192                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     193                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     194                 :             :   /* SSE */
     195                 :             :   21, 22, 23, 24, 25, 26, 27, 28,
     196                 :             :   /* MMX */
     197                 :             :   29, 30, 31, 32, 33, 34, 35, 36,
     198                 :             :   /* extended integer registers */
     199                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     200                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     201                 :             :   /* extended sse registers */
     202                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     203                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     204                 :             :   /* AVX-512 registers 16-23 */
     205                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     206                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     207                 :             :   /* AVX-512 registers 24-31 */
     208                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     209                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     210                 :             :   /* Mask registers */
     211                 :             :   93, 94, 95, 96, 97, 98, 99, 100
     212                 :             : };
     213                 :             : 
     214                 :             : /* The "default" register map used in 64bit mode.  */
     215                 :             : 
     216                 :             : int const debugger64_register_map[FIRST_PSEUDO_REGISTER] =
     217                 :             : {
     218                 :             :   /* general regs */
     219                 :             :   0, 1, 2, 3, 4, 5, 6, 7,
     220                 :             :   /* fp regs */
     221                 :             :   33, 34, 35, 36, 37, 38, 39, 40,
     222                 :             :   /* arg, flags, fpsr, frame */
     223                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     224                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     225                 :             :   /* SSE */
     226                 :             :   17, 18, 19, 20, 21, 22, 23, 24,
     227                 :             :   /* MMX */
     228                 :             :   41, 42, 43, 44, 45, 46, 47, 48,
     229                 :             :   /* extended integer registers */
     230                 :             :   8, 9, 10, 11, 12, 13, 14, 15,
     231                 :             :   /* extended SSE registers */
     232                 :             :   25, 26, 27, 28, 29, 30, 31, 32,
     233                 :             :   /* AVX-512 registers 16-23 */
     234                 :             :   67, 68, 69, 70, 71, 72, 73, 74,
     235                 :             :   /* AVX-512 registers 24-31 */
     236                 :             :   75, 76, 77, 78, 79, 80, 81, 82,
     237                 :             :   /* Mask registers */
     238                 :             :   118, 119, 120, 121, 122, 123, 124, 125,
     239                 :             :   /* rex2 extend interger registers */
     240                 :             :   130, 131, 132, 133, 134, 135, 136, 137,
     241                 :             :   138, 139, 140, 141, 142, 143, 144, 145
     242                 :             : };
     243                 :             : 
     244                 :             : /* Define the register numbers to be used in Dwarf debugging information.
     245                 :             :    The SVR4 reference port C compiler uses the following register numbers
     246                 :             :    in its Dwarf output code:
     247                 :             :         0 for %eax (gcc regno = 0)
     248                 :             :         1 for %ecx (gcc regno = 2)
     249                 :             :         2 for %edx (gcc regno = 1)
     250                 :             :         3 for %ebx (gcc regno = 3)
     251                 :             :         4 for %esp (gcc regno = 7)
     252                 :             :         5 for %ebp (gcc regno = 6)
     253                 :             :         6 for %esi (gcc regno = 4)
     254                 :             :         7 for %edi (gcc regno = 5)
     255                 :             :    The following three DWARF register numbers are never generated by
     256                 :             :    the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
     257                 :             :    believed these numbers have these meanings.
     258                 :             :         8  for %eip    (no gcc equivalent)
     259                 :             :         9  for %eflags (gcc regno = 17)
     260                 :             :         10 for %trapno (no gcc equivalent)
     261                 :             :    It is not at all clear how we should number the FP stack registers
     262                 :             :    for the x86 architecture.  If the version of SDB on x86/svr4 were
     263                 :             :    a bit less brain dead with respect to floating-point then we would
     264                 :             :    have a precedent to follow with respect to DWARF register numbers
     265                 :             :    for x86 FP registers, but the SDB on x86/svr4 was so completely
     266                 :             :    broken with respect to FP registers that it is hardly worth thinking
     267                 :             :    of it as something to strive for compatibility with.
     268                 :             :    The version of x86/svr4 SDB I had does (partially)
     269                 :             :    seem to believe that DWARF register number 11 is associated with
     270                 :             :    the x86 register %st(0), but that's about all.  Higher DWARF
     271                 :             :    register numbers don't seem to be associated with anything in
     272                 :             :    particular, and even for DWARF regno 11, SDB only seemed to under-
     273                 :             :    stand that it should say that a variable lives in %st(0) (when
     274                 :             :    asked via an `=' command) if we said it was in DWARF regno 11,
     275                 :             :    but SDB still printed garbage when asked for the value of the
     276                 :             :    variable in question (via a `/' command).
     277                 :             :    (Also note that the labels SDB printed for various FP stack regs
     278                 :             :    when doing an `x' command were all wrong.)
     279                 :             :    Note that these problems generally don't affect the native SVR4
     280                 :             :    C compiler because it doesn't allow the use of -O with -g and
     281                 :             :    because when it is *not* optimizing, it allocates a memory
     282                 :             :    location for each floating-point variable, and the memory
     283                 :             :    location is what gets described in the DWARF AT_location
     284                 :             :    attribute for the variable in question.
     285                 :             :    Regardless of the severe mental illness of the x86/svr4 SDB, we
     286                 :             :    do something sensible here and we use the following DWARF
     287                 :             :    register numbers.  Note that these are all stack-top-relative
     288                 :             :    numbers.
     289                 :             :         11 for %st(0) (gcc regno = 8)
     290                 :             :         12 for %st(1) (gcc regno = 9)
     291                 :             :         13 for %st(2) (gcc regno = 10)
     292                 :             :         14 for %st(3) (gcc regno = 11)
     293                 :             :         15 for %st(4) (gcc regno = 12)
     294                 :             :         16 for %st(5) (gcc regno = 13)
     295                 :             :         17 for %st(6) (gcc regno = 14)
     296                 :             :         18 for %st(7) (gcc regno = 15)
     297                 :             : */
     298                 :             : int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER] =
     299                 :             : {
     300                 :             :   /* general regs */
     301                 :             :   0, 2, 1, 3, 6, 7, 5, 4,
     302                 :             :   /* fp regs */
     303                 :             :   11, 12, 13, 14, 15, 16, 17, 18,
     304                 :             :   /* arg, flags, fpsr, frame */
     305                 :             :   IGNORED_DWARF_REGNUM, 9,
     306                 :             :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     307                 :             :   /* SSE registers */
     308                 :             :   21, 22, 23, 24, 25, 26, 27, 28,
     309                 :             :   /* MMX registers */
     310                 :             :   29, 30, 31, 32, 33, 34, 35, 36,
     311                 :             :   /* extended integer registers */
     312                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     313                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     314                 :             :   /* extended sse registers */
     315                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     316                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     317                 :             :   /* AVX-512 registers 16-23 */
     318                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     319                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     320                 :             :   /* AVX-512 registers 24-31 */
     321                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     322                 :             :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     323                 :             :   /* Mask registers */
     324                 :             :   93, 94, 95, 96, 97, 98, 99, 100
     325                 :             : };
     326                 :             : 
     327                 :             : /* Define parameter passing and return registers.  */
     328                 :             : 
     329                 :             : static int const x86_64_int_parameter_registers[6] =
     330                 :             : {
     331                 :             :   DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
     332                 :             : };
     333                 :             : 
     334                 :             : static int const x86_64_ms_abi_int_parameter_registers[4] =
     335                 :             : {
     336                 :             :   CX_REG, DX_REG, R8_REG, R9_REG
     337                 :             : };
     338                 :             : 
     339                 :             : static int const x86_64_int_return_registers[4] =
     340                 :             : {
     341                 :             :   AX_REG, DX_REG, DI_REG, SI_REG
     342                 :             : };
     343                 :             : 
     344                 :             : /* Define the structure for the machine field in struct function.  */
     345                 :             : 
     346                 :             : struct GTY(()) stack_local_entry {
     347                 :             :   unsigned short mode;
     348                 :             :   unsigned short n;
     349                 :             :   rtx rtl;
     350                 :             :   struct stack_local_entry *next;
     351                 :             : };
     352                 :             : 
     353                 :             : /* Which cpu are we scheduling for.  */
     354                 :             : enum attr_cpu ix86_schedule;
     355                 :             : 
     356                 :             : /* Which cpu are we optimizing for.  */
     357                 :             : enum processor_type ix86_tune;
     358                 :             : 
     359                 :             : /* Which instruction set architecture to use.  */
     360                 :             : enum processor_type ix86_arch;
     361                 :             : 
     362                 :             : /* True if processor has SSE prefetch instruction.  */
     363                 :             : unsigned char ix86_prefetch_sse;
     364                 :             : 
     365                 :             : /* Preferred alignment for stack boundary in bits.  */
     366                 :             : unsigned int ix86_preferred_stack_boundary;
     367                 :             : 
     368                 :             : /* Alignment for incoming stack boundary in bits specified at
     369                 :             :    command line.  */
     370                 :             : unsigned int ix86_user_incoming_stack_boundary;
     371                 :             : 
     372                 :             : /* Default alignment for incoming stack boundary in bits.  */
     373                 :             : unsigned int ix86_default_incoming_stack_boundary;
     374                 :             : 
     375                 :             : /* Alignment for incoming stack boundary in bits.  */
     376                 :             : unsigned int ix86_incoming_stack_boundary;
     377                 :             : 
     378                 :             : /* True if there is no direct access to extern symbols.  */
     379                 :             : bool ix86_has_no_direct_extern_access;
     380                 :             : 
     381                 :             : /* Calling abi specific va_list type nodes.  */
     382                 :             : tree sysv_va_list_type_node;
     383                 :             : tree ms_va_list_type_node;
     384                 :             : 
     385                 :             : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
     386                 :             : char internal_label_prefix[16];
     387                 :             : int internal_label_prefix_len;
     388                 :             : 
     389                 :             : /* Fence to use after loop using movnt.  */
     390                 :             : tree x86_mfence;
     391                 :             : 
     392                 :             : /* Register class used for passing given 64bit part of the argument.
     393                 :             :    These represent classes as documented by the PS ABI, with the exception
     394                 :             :    of SSESF, SSEDF classes, that are basically SSE class, just gcc will
     395                 :             :    use SF or DFmode move instead of DImode to avoid reformatting penalties.
     396                 :             : 
     397                 :             :    Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
     398                 :             :    whenever possible (upper half does contain padding).  */
     399                 :             : enum x86_64_reg_class
     400                 :             :   {
     401                 :             :     X86_64_NO_CLASS,
     402                 :             :     X86_64_INTEGER_CLASS,
     403                 :             :     X86_64_INTEGERSI_CLASS,
     404                 :             :     X86_64_SSE_CLASS,
     405                 :             :     X86_64_SSEHF_CLASS,
     406                 :             :     X86_64_SSESF_CLASS,
     407                 :             :     X86_64_SSEDF_CLASS,
     408                 :             :     X86_64_SSEUP_CLASS,
     409                 :             :     X86_64_X87_CLASS,
     410                 :             :     X86_64_X87UP_CLASS,
     411                 :             :     X86_64_COMPLEX_X87_CLASS,
     412                 :             :     X86_64_MEMORY_CLASS
     413                 :             :   };
     414                 :             : 
     415                 :             : #define MAX_CLASSES 8
     416                 :             : 
     417                 :             : /* Table of constants used by fldpi, fldln2, etc....  */
     418                 :             : static REAL_VALUE_TYPE ext_80387_constants_table [5];
     419                 :             : static bool ext_80387_constants_init;
     420                 :             : 
     421                 :             : 
     422                 :             : static rtx ix86_function_value (const_tree, const_tree, bool);
     423                 :             : static bool ix86_function_value_regno_p (const unsigned int);
     424                 :             : static unsigned int ix86_function_arg_boundary (machine_mode,
     425                 :             :                                                 const_tree);
     426                 :             : static rtx ix86_static_chain (const_tree, bool);
     427                 :             : static int ix86_function_regparm (const_tree, const_tree);
     428                 :             : static void ix86_compute_frame_layout (void);
     429                 :             : static tree ix86_canonical_va_list_type (tree);
     430                 :             : static unsigned int split_stack_prologue_scratch_regno (void);
     431                 :             : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
     432                 :             : 
     433                 :             : static bool ix86_can_inline_p (tree, tree);
     434                 :             : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
     435                 :             : 
     436                 :             : 
     437                 :             : /* Whether -mtune= or -march= were specified */
     438                 :             : int ix86_tune_defaulted;
     439                 :             : int ix86_arch_specified;
     440                 :             : 
     441                 :             : /* Return true if a red-zone is in use.  We can't use red-zone when
     442                 :             :    there are local indirect jumps, like "indirect_jump" or "tablejump",
     443                 :             :    which jumps to another place in the function, since "call" in the
     444                 :             :    indirect thunk pushes the return address onto stack, destroying
     445                 :             :    red-zone.
     446                 :             : 
     447                 :             :    TODO: If we can reserve the first 2 WORDs, for PUSH and, another
     448                 :             :    for CALL, in red-zone, we can allow local indirect jumps with
     449                 :             :    indirect thunk.  */
     450                 :             : 
     451                 :             : bool
     452                 :     9071470 : ix86_using_red_zone (void)
     453                 :             : {
     454                 :     9071470 :   return (TARGET_RED_ZONE
     455                 :     8168031 :           && !TARGET_64BIT_MS_ABI
     456                 :    16940462 :           && (!cfun->machine->has_local_indirect_jump
     457                 :      106889 :               || cfun->machine->indirect_branch_type == indirect_branch_keep));
     458                 :             : }
     459                 :             : 
     460                 :             : /* Return true, if profiling code should be emitted before
     461                 :             :    prologue. Otherwise it returns false.
     462                 :             :    Note: For x86 with "hotfix" it is sorried.  */
     463                 :             : static bool
     464                 :     4185326 : ix86_profile_before_prologue (void)
     465                 :             : {
     466                 :     4185326 :   return flag_fentry != 0;
     467                 :             : }
     468                 :             : 
     469                 :             : /* Update register usage after having seen the compiler flags.  */
     470                 :             : 
     471                 :             : static void
     472                 :      819042 : ix86_conditional_register_usage (void)
     473                 :             : {
     474                 :      819042 :   int i, c_mask;
     475                 :             : 
     476                 :             :   /* If there are no caller-saved registers, preserve all registers.
     477                 :             :      except fixed_regs and registers used for function return value
     478                 :             :      since aggregate_value_p checks call_used_regs[regno] on return
     479                 :             :      value.  */
     480                 :      819042 :   if (cfun
     481                 :       61113 :       && (cfun->machine->call_saved_registers
     482                 :       61113 :           == TYPE_NO_CALLER_SAVED_REGISTERS))
     483                 :      378510 :     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     484                 :      374440 :       if (!fixed_regs[i] && !ix86_function_value_regno_p (i))
     485                 :      337800 :         call_used_regs[i] = 0;
     486                 :             : 
     487                 :             :   /* For 32-bit targets, disable the REX registers.  */
     488                 :      819042 :   if (! TARGET_64BIT)
     489                 :             :     {
     490                 :      133533 :       for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
     491                 :      118696 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     492                 :      133533 :       for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
     493                 :      118696 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     494                 :      252229 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     495                 :      237392 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     496                 :             :     }
     497                 :             : 
     498                 :             :   /*  See the definition of CALL_USED_REGISTERS in i386.h.  */
     499                 :      819042 :   c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT_MS_ABI);
     500                 :             :   
     501                 :      819042 :   CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
     502                 :             : 
     503                 :    76170906 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     504                 :             :     {
     505                 :             :       /* Set/reset conditionally defined registers from
     506                 :             :          CALL_USED_REGISTERS initializer.  */
     507                 :    75351864 :       if (call_used_regs[i] > 1)
     508                 :    13047634 :         call_used_regs[i] = !!(call_used_regs[i] & c_mask);
     509                 :             : 
     510                 :             :       /* Calculate registers of CLOBBERED_REGS register set
     511                 :             :          as call used registers from GENERAL_REGS register set.  */
     512                 :    75351864 :       if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
     513                 :    75351864 :           && call_used_regs[i])
     514                 :    22839964 :         SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
     515                 :             :     }
     516                 :             : 
     517                 :             :   /* If MMX is disabled, disable the registers.  */
     518                 :      819042 :   if (! TARGET_MMX)
     519                 :      384640 :     accessible_reg_set &= ~reg_class_contents[MMX_REGS];
     520                 :             : 
     521                 :             :   /* If SSE is disabled, disable the registers.  */
     522                 :      819042 :   if (! TARGET_SSE)
     523                 :      379436 :     accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
     524                 :             : 
     525                 :             :   /* If the FPU is disabled, disable the registers.  */
     526                 :      819042 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
     527                 :      379890 :     accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
     528                 :             : 
     529                 :             :   /* If AVX512F is disabled, disable the registers.  */
     530                 :      819042 :   if (! TARGET_AVX512F)
     531                 :             :     {
     532                 :     9533532 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     533                 :     8972736 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     534                 :             : 
     535                 :     1121592 :       accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
     536                 :             :     }
     537                 :             : 
     538                 :             :   /* If APX is disabled, disable the registers.  */
     539                 :      819042 :   if (! (TARGET_APX_EGPR && TARGET_64BIT))
     540                 :             :     {
     541                 :    13919175 :       for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
     542                 :    13100400 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     543                 :             :     }
     544                 :      819042 : }
     545                 :             : 
     546                 :             : /* Canonicalize a comparison from one we don't have to one we do have.  */
     547                 :             : 
     548                 :             : static void
     549                 :    19151279 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
     550                 :             :                               bool op0_preserve_value)
     551                 :             : {
     552                 :             :   /* The order of operands in x87 ficom compare is forced by combine in
     553                 :             :      simplify_comparison () function. Float operator is treated as RTX_OBJ
     554                 :             :      with a precedence over other operators and is always put in the first
     555                 :             :      place. Swap condition and operands to match ficom instruction.  */
     556                 :    19151279 :   if (!op0_preserve_value
     557                 :    18452142 :       && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
     558                 :             :     {
     559                 :           6 :       enum rtx_code scode = swap_condition ((enum rtx_code) *code);
     560                 :             : 
     561                 :             :       /* We are called only for compares that are split to SAHF instruction.
     562                 :             :          Ensure that we have setcc/jcc insn for the swapped condition.  */
     563                 :           6 :       if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
     564                 :             :         {
     565                 :           6 :           std::swap (*op0, *op1);
     566                 :           6 :           *code = (int) scode;
     567                 :             :         }
     568                 :             :     }
     569                 :    19151279 : }
     570                 :             : 
     571                 :             : 
     572                 :             : /* Hook to determine if one function can safely inline another.  */
     573                 :             : 
     574                 :             : static bool
     575                 :     7964609 : ix86_can_inline_p (tree caller, tree callee)
     576                 :             : {
     577                 :     7964609 :   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
     578                 :     7964609 :   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
     579                 :             : 
     580                 :             :   /* Changes of those flags can be tolerated for always inlines. Lets hope
     581                 :             :      user knows what he is doing.  */
     582                 :     7964609 :   unsigned HOST_WIDE_INT always_inline_safe_mask
     583                 :             :          = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
     584                 :             :             | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
     585                 :             :             | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
     586                 :             :             | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
     587                 :             :             | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
     588                 :             :             | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
     589                 :             :             | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
     590                 :             : 
     591                 :             : 
     592                 :     7964609 :   if (!callee_tree)
     593                 :     7334789 :     callee_tree = target_option_default_node;
     594                 :     7964609 :   if (!caller_tree)
     595                 :     7343475 :     caller_tree = target_option_default_node;
     596                 :     7964609 :   if (callee_tree == caller_tree)
     597                 :             :     return true;
     598                 :             : 
     599                 :       12807 :   struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
     600                 :       12807 :   struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
     601                 :       12807 :   bool ret = false;
     602                 :       12807 :   bool always_inline
     603                 :       12807 :     = (DECL_DISREGARD_INLINE_LIMITS (callee)
     604                 :       24883 :        && lookup_attribute ("always_inline",
     605                 :       12076 :                             DECL_ATTRIBUTES (callee)));
     606                 :             : 
     607                 :             :   /* If callee only uses GPRs, ignore MASK_80387.  */
     608                 :       12807 :   if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
     609                 :        1016 :     always_inline_safe_mask |= MASK_80387;
     610                 :             : 
     611                 :       12807 :   cgraph_node *callee_node = cgraph_node::get (callee);
     612                 :             :   /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
     613                 :             :      function can inline a SSE2 function but a SSE2 function can't inline
     614                 :             :      a SSE4 function.  */
     615                 :       12807 :   if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
     616                 :             :        != callee_opts->x_ix86_isa_flags)
     617                 :       12573 :       || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
     618                 :             :           != callee_opts->x_ix86_isa_flags2))
     619                 :             :     ret = false;
     620                 :             : 
     621                 :             :   /* See if we have the same non-isa options.  */
     622                 :       12554 :   else if ((!always_inline
     623                 :         493 :             && caller_opts->x_target_flags != callee_opts->x_target_flags)
     624                 :       12510 :            || (caller_opts->x_target_flags & ~always_inline_safe_mask)
     625                 :       12510 :                != (callee_opts->x_target_flags & ~always_inline_safe_mask))
     626                 :             :     ret = false;
     627                 :             : 
     628                 :       12510 :   else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
     629                 :             :            /* If the calle doesn't use FP expressions differences in
     630                 :             :               ix86_fpmath can be ignored.  We are called from FEs
     631                 :             :               for multi-versioning call optimization, so beware of
     632                 :             :               ipa_fn_summaries not available.  */
     633                 :        1233 :            && (! ipa_fn_summaries
     634                 :        1233 :                || ipa_fn_summaries->get (callee_node) == NULL
     635                 :        1233 :                || ipa_fn_summaries->get (callee_node)->fp_expressions))
     636                 :             :     ret = false;
     637                 :             : 
     638                 :             :   /* At this point we cannot identify whether arch or tune setting
     639                 :             :      comes from target attribute or not. So the most conservative way
     640                 :             :      is to allow the callee that uses default arch and tune string to
     641                 :             :      be inlined.  */
     642                 :       12236 :   else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
     643                 :        9534 :            && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
     644                 :             :     ret = true;
     645                 :             : 
     646                 :             :   /* See if arch, tune, etc. are the same. As previous ISA flags already
     647                 :             :      checks if callee's ISA is subset of caller's, do not block
     648                 :             :      always_inline attribute for callee even it has different arch. */
     649                 :        2710 :   else if (!always_inline && caller_opts->arch != callee_opts->arch)
     650                 :             :     ret = false;
     651                 :             : 
     652                 :           4 :   else if (!always_inline && caller_opts->tune != callee_opts->tune)
     653                 :             :     ret = false;
     654                 :             : 
     655                 :        2710 :   else if (!always_inline
     656                 :           4 :            && caller_opts->branch_cost != callee_opts->branch_cost)
     657                 :             :     ret = false;
     658                 :             : 
     659                 :             :   else
     660                 :     7964038 :     ret = true;
     661                 :             : 
     662                 :             :   return ret;
     663                 :             : }
     664                 :             : 
     665                 :             : /* Return true if this goes in large data/bss.  */
     666                 :             : 
     667                 :             : static bool
     668                 :    64271708 : ix86_in_large_data_p (tree exp)
     669                 :             : {
     670                 :    64271708 :   if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
     671                 :    64271457 :       && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
     672                 :             :     return false;
     673                 :             : 
     674                 :        1137 :   if (exp == NULL_TREE)
     675                 :             :     return false;
     676                 :             : 
     677                 :             :   /* Functions are never large data.  */
     678                 :        1137 :   if (TREE_CODE (exp) == FUNCTION_DECL)
     679                 :             :     return false;
     680                 :             : 
     681                 :             :   /* Automatic variables are never large data.  */
     682                 :         309 :   if (VAR_P (exp) && !is_global_var (exp))
     683                 :             :     return false;
     684                 :             : 
     685                 :         309 :   if (VAR_P (exp) && DECL_SECTION_NAME (exp))
     686                 :             :     {
     687                 :          67 :       const char *section = DECL_SECTION_NAME (exp);
     688                 :          67 :       if (strcmp (section, ".ldata") == 0
     689                 :          67 :           || strcmp (section, ".lbss") == 0)
     690                 :             :         return true;
     691                 :             :       return false;
     692                 :             :     }
     693                 :             :   else
     694                 :             :     {
     695                 :         242 :       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
     696                 :             : 
     697                 :             :       /* If this is an incomplete type with size 0, then we can't put it
     698                 :             :          in data because it might be too big when completed.  Also,
     699                 :             :          int_size_in_bytes returns -1 if size can vary or is larger than
     700                 :             :          an integer in which case also it is safer to assume that it goes in
     701                 :             :          large data.  */
     702                 :         242 :       if (size <= 0 || size > ix86_section_threshold)
     703                 :             :         return true;
     704                 :             :     }
     705                 :             : 
     706                 :             :   return false;
     707                 :             : }
     708                 :             : 
     709                 :             : /* i386-specific section flag to mark large sections.  */
     710                 :             : #define SECTION_LARGE SECTION_MACH_DEP
     711                 :             : 
     712                 :             : /* Switch to the appropriate section for output of DECL.
     713                 :             :    DECL is either a `VAR_DECL' node or a constant of some sort.
     714                 :             :    RELOC indicates whether forming the initial value of DECL requires
     715                 :             :    link-time relocations.  */
     716                 :             : 
     717                 :             : ATTRIBUTE_UNUSED static section *
     718                 :     1616433 : x86_64_elf_select_section (tree decl, int reloc,
     719                 :             :                            unsigned HOST_WIDE_INT align)
     720                 :             : {
     721                 :     1616433 :   if (ix86_in_large_data_p (decl))
     722                 :             :     {
     723                 :           6 :       const char *sname = NULL;
     724                 :           6 :       unsigned int flags = SECTION_WRITE | SECTION_LARGE;
     725                 :           6 :       switch (categorize_decl_for_section (decl, reloc))
     726                 :             :         {
     727                 :           1 :         case SECCAT_DATA:
     728                 :           1 :           sname = ".ldata";
     729                 :           1 :           break;
     730                 :           0 :         case SECCAT_DATA_REL:
     731                 :           0 :           sname = ".ldata.rel";
     732                 :           0 :           break;
     733                 :           0 :         case SECCAT_DATA_REL_LOCAL:
     734                 :           0 :           sname = ".ldata.rel.local";
     735                 :           0 :           break;
     736                 :           0 :         case SECCAT_DATA_REL_RO:
     737                 :           0 :           sname = ".ldata.rel.ro";
     738                 :           0 :           break;
     739                 :           0 :         case SECCAT_DATA_REL_RO_LOCAL:
     740                 :           0 :           sname = ".ldata.rel.ro.local";
     741                 :           0 :           break;
     742                 :           0 :         case SECCAT_BSS:
     743                 :           0 :           sname = ".lbss";
     744                 :           0 :           flags |= SECTION_BSS;
     745                 :           0 :           break;
     746                 :             :         case SECCAT_RODATA:
     747                 :             :         case SECCAT_RODATA_MERGE_STR:
     748                 :             :         case SECCAT_RODATA_MERGE_STR_INIT:
     749                 :             :         case SECCAT_RODATA_MERGE_CONST:
     750                 :             :           sname = ".lrodata";
     751                 :             :           flags &= ~SECTION_WRITE;
     752                 :             :           break;
     753                 :           0 :         case SECCAT_SRODATA:
     754                 :           0 :         case SECCAT_SDATA:
     755                 :           0 :         case SECCAT_SBSS:
     756                 :           0 :           gcc_unreachable ();
     757                 :             :         case SECCAT_TEXT:
     758                 :             :         case SECCAT_TDATA:
     759                 :             :         case SECCAT_TBSS:
     760                 :             :           /* We don't split these for medium model.  Place them into
     761                 :             :              default sections and hope for best.  */
     762                 :             :           break;
     763                 :             :         }
     764                 :           1 :       if (sname)
     765                 :             :         {
     766                 :             :           /* We might get called with string constants, but get_named_section
     767                 :             :              doesn't like them as they are not DECLs.  Also, we need to set
     768                 :             :              flags in that case.  */
     769                 :           6 :           if (!DECL_P (decl))
     770                 :           3 :             return get_section (sname, flags, NULL);
     771                 :           3 :           return get_named_section (decl, sname, reloc);
     772                 :             :         }
     773                 :             :     }
     774                 :     1616427 :   return default_elf_select_section (decl, reloc, align);
     775                 :             : }
     776                 :             : 
     777                 :             : /* Select a set of attributes for section NAME based on the properties
     778                 :             :    of DECL and whether or not RELOC indicates that DECL's initializer
     779                 :             :    might contain runtime relocations.  */
     780                 :             : 
     781                 :             : static unsigned int ATTRIBUTE_UNUSED
     782                 :    51259735 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
     783                 :             : {
     784                 :    51259735 :   unsigned int flags = default_section_type_flags (decl, name, reloc);
     785                 :             : 
     786                 :    51259735 :   if (ix86_in_large_data_p (decl))
     787                 :           7 :     flags |= SECTION_LARGE;
     788                 :             : 
     789                 :    51259735 :   if (decl == NULL_TREE
     790                 :         368 :       && (strcmp (name, ".ldata.rel.ro") == 0
     791                 :         368 :           || strcmp (name, ".ldata.rel.ro.local") == 0))
     792                 :           0 :     flags |= SECTION_RELRO;
     793                 :             : 
     794                 :    51259735 :   if (strcmp (name, ".lbss") == 0
     795                 :    51259731 :       || startswith (name, ".lbss.")
     796                 :   102519463 :       || startswith (name, ".gnu.linkonce.lb."))
     797                 :           7 :     flags |= SECTION_BSS;
     798                 :             : 
     799                 :    51259735 :   return flags;
     800                 :             : }
     801                 :             : 
     802                 :             : /* Build up a unique section name, expressed as a
     803                 :             :    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
     804                 :             :    RELOC indicates whether the initial value of EXP requires
     805                 :             :    link-time relocations.  */
     806                 :             : 
     807                 :             : static void ATTRIBUTE_UNUSED
     808                 :     1770238 : x86_64_elf_unique_section (tree decl, int reloc)
     809                 :             : {
     810                 :     1770238 :   if (ix86_in_large_data_p (decl))
     811                 :             :     {
     812                 :           3 :       const char *prefix = NULL;
     813                 :             :       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
     814                 :           3 :       bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
     815                 :             : 
     816                 :           3 :       switch (categorize_decl_for_section (decl, reloc))
     817                 :             :         {
     818                 :           0 :         case SECCAT_DATA:
     819                 :           0 :         case SECCAT_DATA_REL:
     820                 :           0 :         case SECCAT_DATA_REL_LOCAL:
     821                 :           0 :         case SECCAT_DATA_REL_RO:
     822                 :           0 :         case SECCAT_DATA_REL_RO_LOCAL:
     823                 :           0 :           prefix = one_only ? ".ld" : ".ldata";
     824                 :           0 :           break;
     825                 :           3 :         case SECCAT_BSS:
     826                 :           3 :           prefix = one_only ? ".lb" : ".lbss";
     827                 :           3 :           break;
     828                 :             :         case SECCAT_RODATA:
     829                 :             :         case SECCAT_RODATA_MERGE_STR:
     830                 :             :         case SECCAT_RODATA_MERGE_STR_INIT:
     831                 :             :         case SECCAT_RODATA_MERGE_CONST:
     832                 :             :           prefix = one_only ? ".lr" : ".lrodata";
     833                 :             :           break;
     834                 :           0 :         case SECCAT_SRODATA:
     835                 :           0 :         case SECCAT_SDATA:
     836                 :           0 :         case SECCAT_SBSS:
     837                 :           0 :           gcc_unreachable ();
     838                 :             :         case SECCAT_TEXT:
     839                 :             :         case SECCAT_TDATA:
     840                 :             :         case SECCAT_TBSS:
     841                 :             :           /* We don't split these for medium model.  Place them into
     842                 :             :              default sections and hope for best.  */
     843                 :             :           break;
     844                 :             :         }
     845                 :           3 :       if (prefix)
     846                 :             :         {
     847                 :           3 :           const char *name, *linkonce;
     848                 :           3 :           char *string;
     849                 :             : 
     850                 :           3 :           name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     851                 :           3 :           name = targetm.strip_name_encoding (name);
     852                 :             : 
     853                 :             :           /* If we're using one_only, then there needs to be a .gnu.linkonce
     854                 :             :              prefix to the section name.  */
     855                 :           3 :           linkonce = one_only ? ".gnu.linkonce" : "";
     856                 :             : 
     857                 :           3 :           string = ACONCAT ((linkonce, prefix, ".", name, NULL));
     858                 :             : 
     859                 :           3 :           set_decl_section_name (decl, string);
     860                 :           3 :           return;
     861                 :             :         }
     862                 :             :     }
     863                 :     1770235 :   default_unique_section (decl, reloc);
     864                 :             : }
     865                 :             : 
     866                 :             : #ifdef COMMON_ASM_OP
     867                 :             : 
     868                 :             : #ifndef LARGECOMM_SECTION_ASM_OP
     869                 :             : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
     870                 :             : #endif
     871                 :             : 
     872                 :             : /* This says how to output assembler code to declare an
     873                 :             :    uninitialized external linkage data object.
     874                 :             : 
     875                 :             :    For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
     876                 :             :    large objects.  */
     877                 :             : void
     878                 :      164638 : x86_elf_aligned_decl_common (FILE *file, tree decl,
     879                 :             :                         const char *name, unsigned HOST_WIDE_INT size,
     880                 :             :                         unsigned align)
     881                 :             : {
     882                 :      164638 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     883                 :      164631 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     884                 :           7 :       && size > (unsigned int)ix86_section_threshold)
     885                 :             :     {
     886                 :           1 :       switch_to_section (get_named_section (decl, ".lbss", 0));
     887                 :           1 :       fputs (LARGECOMM_SECTION_ASM_OP, file);
     888                 :             :     }
     889                 :             :   else
     890                 :      164637 :     fputs (COMMON_ASM_OP, file);
     891                 :      164638 :   assemble_name (file, name);
     892                 :      164638 :   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
     893                 :             :            size, align / BITS_PER_UNIT);
     894                 :      164638 : }
     895                 :             : #endif
     896                 :             : 
     897                 :             : /* Utility function for targets to use in implementing
     898                 :             :    ASM_OUTPUT_ALIGNED_BSS.  */
     899                 :             : 
     900                 :             : void
     901                 :      761455 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
     902                 :             :                         unsigned HOST_WIDE_INT size, unsigned align)
     903                 :             : {
     904                 :      761455 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     905                 :      761443 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     906                 :          38 :       && size > (unsigned int)ix86_section_threshold)
     907                 :           3 :     switch_to_section (get_named_section (decl, ".lbss", 0));
     908                 :             :   else
     909                 :      761452 :     switch_to_section (bss_section);
     910                 :     1522910 :   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
     911                 :             : #ifdef ASM_DECLARE_OBJECT_NAME
     912                 :      761455 :   last_assemble_variable_decl = decl;
     913                 :      761455 :   ASM_DECLARE_OBJECT_NAME (file, name, decl);
     914                 :             : #else
     915                 :             :   /* Standard thing is just output label for the object.  */
     916                 :             :   ASM_OUTPUT_LABEL (file, name);
     917                 :             : #endif /* ASM_DECLARE_OBJECT_NAME */
     918                 :      761455 :   ASM_OUTPUT_SKIP (file, size ? size : 1);
     919                 :      761455 : }
     920                 :             : 
     921                 :             : /* Decide whether we must probe the stack before any space allocation
     922                 :             :    on this target.  It's essentially TARGET_STACK_PROBE except when
     923                 :             :    -fstack-check causes the stack to be already probed differently.  */
     924                 :             : 
     925                 :             : bool
     926                 :      808320 : ix86_target_stack_probe (void)
     927                 :             : {
     928                 :             :   /* Do not probe the stack twice if static stack checking is enabled.  */
     929                 :      808320 :   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
     930                 :             :     return false;
     931                 :             : 
     932                 :      808320 :   return TARGET_STACK_PROBE;
     933                 :             : }
     934                 :             : 
     935                 :             : /* Decide whether we can make a sibling call to a function.  DECL is the
     936                 :             :    declaration of the function being targeted by the call and EXP is the
     937                 :             :    CALL_EXPR representing the call.  */
     938                 :             : 
     939                 :             : static bool
     940                 :      122803 : ix86_function_ok_for_sibcall (tree decl, tree exp)
     941                 :             : {
     942                 :      122803 :   tree type, decl_or_type;
     943                 :      122803 :   rtx a, b;
     944                 :      122803 :   bool bind_global = decl && !targetm.binds_local_p (decl);
     945                 :             : 
     946                 :      122803 :   if (ix86_function_naked (current_function_decl))
     947                 :             :     return false;
     948                 :             : 
     949                 :             :   /* Sibling call isn't OK if there are no caller-saved registers
     950                 :             :      since all registers must be preserved before return.  */
     951                 :      122801 :   if (cfun->machine->call_saved_registers
     952                 :      122801 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
     953                 :             :     return false;
     954                 :             : 
     955                 :             :   /* If we are generating position-independent code, we cannot sibcall
     956                 :             :      optimize direct calls to global functions, as the PLT requires
     957                 :             :      %ebx be live. (Darwin does not have a PLT.)  */
     958                 :      122778 :   if (!TARGET_MACHO
     959                 :      122778 :       && !TARGET_64BIT
     960                 :       10668 :       && flag_pic
     961                 :        7965 :       && flag_plt
     962                 :        7965 :       && bind_global)
     963                 :             :     return false;
     964                 :             : 
     965                 :             :   /* If we need to align the outgoing stack, then sibcalling would
     966                 :             :      unalign the stack, which may break the called function.  */
     967                 :      118509 :   if (ix86_minimum_incoming_stack_boundary (true)
     968                 :      118509 :       < PREFERRED_STACK_BOUNDARY)
     969                 :             :     return false;
     970                 :             : 
     971                 :      117929 :   if (decl)
     972                 :             :     {
     973                 :      108068 :       decl_or_type = decl;
     974                 :      108068 :       type = TREE_TYPE (decl);
     975                 :             :     }
     976                 :             :   else
     977                 :             :     {
     978                 :             :       /* We're looking at the CALL_EXPR, we need the type of the function.  */
     979                 :        9861 :       type = CALL_EXPR_FN (exp);                /* pointer expression */
     980                 :        9861 :       type = TREE_TYPE (type);                  /* pointer type */
     981                 :        9861 :       type = TREE_TYPE (type);                  /* function type */
     982                 :        9861 :       decl_or_type = type;
     983                 :             :     }
     984                 :             : 
     985                 :             :   /* Sibling call isn't OK if callee has no callee-saved registers
     986                 :             :      and the calling function has callee-saved registers.  */
     987                 :      117929 :   if (cfun->machine->call_saved_registers != TYPE_NO_CALLEE_SAVED_REGISTERS
     988                 :      117924 :       && (cfun->machine->call_saved_registers
     989                 :             :           != TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP)
     990                 :      235853 :       && lookup_attribute ("no_callee_saved_registers",
     991                 :      117924 :                            TYPE_ATTRIBUTES (type)))
     992                 :             :     return false;
     993                 :             : 
     994                 :             :   /* If outgoing reg parm stack space changes, we cannot do sibcall.  */
     995                 :      117921 :   if ((OUTGOING_REG_PARM_STACK_SPACE (type)
     996                 :      117921 :        != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
     997                 :      235095 :       || (REG_PARM_STACK_SPACE (decl_or_type)
     998                 :      117174 :           != REG_PARM_STACK_SPACE (current_function_decl)))
     999                 :             :     {
    1000                 :         747 :       maybe_complain_about_tail_call (exp,
    1001                 :             :                                       "inconsistent size of stack space"
    1002                 :             :                                       " allocated for arguments which are"
    1003                 :             :                                       " passed in registers");
    1004                 :         747 :       return false;
    1005                 :             :     }
    1006                 :             : 
    1007                 :             :   /* Check that the return value locations are the same.  Like
    1008                 :             :      if we are returning floats on the 80387 register stack, we cannot
    1009                 :             :      make a sibcall from a function that doesn't return a float to a
    1010                 :             :      function that does or, conversely, from a function that does return
    1011                 :             :      a float to a function that doesn't; the necessary stack adjustment
    1012                 :             :      would not be executed.  This is also the place we notice
    1013                 :             :      differences in the return value ABI.  Note that it is ok for one
    1014                 :             :      of the functions to have void return type as long as the return
    1015                 :             :      value of the other is passed in a register.  */
    1016                 :      117174 :   a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
    1017                 :      117174 :   b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
    1018                 :      117174 :                            cfun->decl, false);
    1019                 :      117174 :   if (STACK_REG_P (a) || STACK_REG_P (b))
    1020                 :             :     {
    1021                 :         686 :       if (!rtx_equal_p (a, b))
    1022                 :             :         return false;
    1023                 :             :     }
    1024                 :      116488 :   else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
    1025                 :             :     ;
    1026                 :       19629 :   else if (!rtx_equal_p (a, b))
    1027                 :             :     return false;
    1028                 :             : 
    1029                 :      116755 :   if (TARGET_64BIT)
    1030                 :             :     {
    1031                 :             :       /* The SYSV ABI has more call-clobbered registers;
    1032                 :             :          disallow sibcalls from MS to SYSV.  */
    1033                 :      110356 :       if (cfun->machine->call_abi == MS_ABI
    1034                 :      110356 :           && ix86_function_type_abi (type) == SYSV_ABI)
    1035                 :             :         return false;
    1036                 :             :     }
    1037                 :             :   else
    1038                 :             :     {
    1039                 :             :       /* If this call is indirect, we'll need to be able to use a
    1040                 :             :          call-clobbered register for the address of the target function.
    1041                 :             :          Make sure that all such registers are not used for passing
    1042                 :             :          parameters.  Note that DLLIMPORT functions and call to global
    1043                 :             :          function via GOT slot are indirect.  */
    1044                 :        6399 :       if (!decl
    1045                 :        4558 :           || (bind_global && flag_pic && !flag_plt)
    1046                 :             :           || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
    1047                 :        4558 :           || flag_force_indirect_call)
    1048                 :             :         {
    1049                 :             :           /* Check if regparm >= 3 since arg_reg_available is set to
    1050                 :             :              false if regparm == 0.  If regparm is 1 or 2, there is
    1051                 :             :              always a call-clobbered register available.
    1052                 :             : 
    1053                 :             :              ??? The symbol indirect call doesn't need a call-clobbered
    1054                 :             :              register.  But we don't know if this is a symbol indirect
    1055                 :             :              call or not here.  */
    1056                 :        1841 :           if (ix86_function_regparm (type, decl) >= 3
    1057                 :        1841 :               && !cfun->machine->arg_reg_available)
    1058                 :             :             return false;
    1059                 :             :         }
    1060                 :             :     }
    1061                 :             : 
    1062                 :      116755 :   if (decl && ix86_use_pseudo_pic_reg ())
    1063                 :             :     {
    1064                 :             :       /* When PIC register is used, it must be restored after ifunc
    1065                 :             :          function returns.  */
    1066                 :        2050 :        cgraph_node *node = cgraph_node::get (decl);
    1067                 :        2050 :        if (node && node->ifunc_resolver)
    1068                 :             :          return false;
    1069                 :             :     }
    1070                 :             : 
    1071                 :             :   /* Disable sibcall if callee has indirect_return attribute and
    1072                 :             :      caller doesn't since callee will return to the caller's caller
    1073                 :             :      via an indirect jump.  */
    1074                 :      116755 :   if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
    1075                 :             :        == (CF_RETURN | CF_BRANCH))
    1076                 :       44705 :       && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
    1077                 :      116759 :       && !lookup_attribute ("indirect_return",
    1078                 :           4 :                             TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
    1079                 :             :     return false;
    1080                 :             : 
    1081                 :             :   /* Otherwise okay.  That also includes certain types of indirect calls.  */
    1082                 :             :   return true;
    1083                 :             : }
    1084                 :             : 
    1085                 :             : /* This function determines from TYPE the calling-convention.  */
    1086                 :             : 
    1087                 :             : unsigned int
    1088                 :     6034828 : ix86_get_callcvt (const_tree type)
    1089                 :             : {
    1090                 :     6034828 :   unsigned int ret = 0;
    1091                 :     6034828 :   bool is_stdarg;
    1092                 :     6034828 :   tree attrs;
    1093                 :             : 
    1094                 :     6034828 :   if (TARGET_64BIT)
    1095                 :             :     return IX86_CALLCVT_CDECL;
    1096                 :             : 
    1097                 :     3214982 :   attrs = TYPE_ATTRIBUTES (type);
    1098                 :     3214982 :   if (attrs != NULL_TREE)
    1099                 :             :     {
    1100                 :       51617 :       if (lookup_attribute ("cdecl", attrs))
    1101                 :             :         ret |= IX86_CALLCVT_CDECL;
    1102                 :       51617 :       else if (lookup_attribute ("stdcall", attrs))
    1103                 :             :         ret |= IX86_CALLCVT_STDCALL;
    1104                 :       51617 :       else if (lookup_attribute ("fastcall", attrs))
    1105                 :             :         ret |= IX86_CALLCVT_FASTCALL;
    1106                 :       51608 :       else if (lookup_attribute ("thiscall", attrs))
    1107                 :           0 :         ret |= IX86_CALLCVT_THISCALL;
    1108                 :             : 
    1109                 :             :       /* Regparam isn't allowed for thiscall and fastcall.  */
    1110                 :       51617 :       if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
    1111                 :             :         {
    1112                 :       51608 :           if (lookup_attribute ("regparm", attrs))
    1113                 :        8304 :             ret |= IX86_CALLCVT_REGPARM;
    1114                 :       51608 :           if (lookup_attribute ("sseregparm", attrs))
    1115                 :           0 :             ret |= IX86_CALLCVT_SSEREGPARM;
    1116                 :             :         }
    1117                 :             : 
    1118                 :       51617 :       if (IX86_BASE_CALLCVT(ret) != 0)
    1119                 :             :         return ret;
    1120                 :             :     }
    1121                 :             : 
    1122                 :     3214973 :   is_stdarg = stdarg_p (type);
    1123                 :     3214973 :   if (TARGET_RTD && !is_stdarg)
    1124                 :           0 :     return IX86_CALLCVT_STDCALL | ret;
    1125                 :             : 
    1126                 :     3214973 :   if (ret != 0
    1127                 :     3214973 :       || is_stdarg
    1128                 :     3198509 :       || TREE_CODE (type) != METHOD_TYPE
    1129                 :     3339017 :       || ix86_function_type_abi (type) != MS_ABI)
    1130                 :     3214973 :     return IX86_CALLCVT_CDECL | ret;
    1131                 :             : 
    1132                 :             :   return IX86_CALLCVT_THISCALL;
    1133                 :             : }
    1134                 :             : 
    1135                 :             : /* Return 0 if the attributes for two types are incompatible, 1 if they
    1136                 :             :    are compatible, and 2 if they are nearly compatible (which causes a
    1137                 :             :    warning to be generated).  */
    1138                 :             : 
    1139                 :             : static int
    1140                 :     1419987 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
    1141                 :             : {
    1142                 :     1419987 :   unsigned int ccvt1, ccvt2;
    1143                 :             : 
    1144                 :     1419987 :   if (TREE_CODE (type1) != FUNCTION_TYPE
    1145                 :     1419987 :       && TREE_CODE (type1) != METHOD_TYPE)
    1146                 :             :     return 1;
    1147                 :             : 
    1148                 :     1413492 :   ccvt1 = ix86_get_callcvt (type1);
    1149                 :     1413492 :   ccvt2 = ix86_get_callcvt (type2);
    1150                 :     1413492 :   if (ccvt1 != ccvt2)
    1151                 :             :     return 0;
    1152                 :     2819886 :   if (ix86_function_regparm (type1, NULL)
    1153                 :     1409943 :       != ix86_function_regparm (type2, NULL))
    1154                 :             :     return 0;
    1155                 :             : 
    1156                 :      692604 :   if (lookup_attribute ("no_callee_saved_registers",
    1157                 :      692604 :                         TYPE_ATTRIBUTES (type1))
    1158                 :      692604 :       != lookup_attribute ("no_callee_saved_registers",
    1159                 :      692604 :                            TYPE_ATTRIBUTES (type2)))
    1160                 :             :     return 0;
    1161                 :             : 
    1162                 :             :   return 1;
    1163                 :             : }
    1164                 :             : 
    1165                 :             : /* Return the regparm value for a function with the indicated TYPE and DECL.
    1166                 :             :    DECL may be NULL when calling function indirectly
    1167                 :             :    or considering a libcall.  */
    1168                 :             : 
    1169                 :             : static int
    1170                 :     4075922 : ix86_function_regparm (const_tree type, const_tree decl)
    1171                 :             : {
    1172                 :     4075922 :   tree attr;
    1173                 :     4075922 :   int regparm;
    1174                 :     4075922 :   unsigned int ccvt;
    1175                 :             : 
    1176                 :     4075922 :   if (TARGET_64BIT)
    1177                 :     2819846 :     return (ix86_function_type_abi (type) == SYSV_ABI
    1178                 :     2819846 :             ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
    1179                 :     1256076 :   ccvt = ix86_get_callcvt (type);
    1180                 :     1256076 :   regparm = ix86_regparm;
    1181                 :             : 
    1182                 :     1256076 :   if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
    1183                 :             :     {
    1184                 :        2017 :       attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
    1185                 :        2017 :       if (attr)
    1186                 :             :         {
    1187                 :        2017 :           regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
    1188                 :        2017 :           return regparm;
    1189                 :             :         }
    1190                 :             :     }
    1191                 :     1254059 :   else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1192                 :             :     return 2;
    1193                 :     1254059 :   else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1194                 :             :     return 1;
    1195                 :             : 
    1196                 :             :   /* Use register calling convention for local functions when possible.  */
    1197                 :     1254059 :   if (decl
    1198                 :     1192803 :       && TREE_CODE (decl) == FUNCTION_DECL)
    1199                 :             :     {
    1200                 :     1182680 :       cgraph_node *target = cgraph_node::get (decl);
    1201                 :     1182680 :       if (target)
    1202                 :     1175918 :         target = target->function_symbol ();
    1203                 :             : 
    1204                 :             :       /* Caller and callee must agree on the calling convention, so
    1205                 :             :          checking here just optimize means that with
    1206                 :             :          __attribute__((optimize (...))) caller could use regparm convention
    1207                 :             :          and callee not, or vice versa.  Instead look at whether the callee
    1208                 :             :          is optimized or not.  */
    1209                 :     1175918 :       if (target && opt_for_fn (target->decl, optimize)
    1210                 :     2350991 :           && !(profile_flag && !flag_fentry))
    1211                 :             :         {
    1212                 :     1175073 :           if (target->local && target->can_change_signature)
    1213                 :             :             {
    1214                 :      135504 :               int local_regparm, globals = 0, regno;
    1215                 :             : 
    1216                 :             :               /* Make sure no regparm register is taken by a
    1217                 :             :                  fixed register variable.  */
    1218                 :      135504 :               for (local_regparm = 0; local_regparm < REGPARM_MAX;
    1219                 :             :                    local_regparm++)
    1220                 :      101628 :                 if (fixed_regs[local_regparm])
    1221                 :             :                   break;
    1222                 :             : 
    1223                 :             :               /* We don't want to use regparm(3) for nested functions as
    1224                 :             :                  these use a static chain pointer in the third argument.  */
    1225                 :       33876 :               if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
    1226                 :             :                 local_regparm = 2;
    1227                 :             : 
    1228                 :             :               /* Save a register for the split stack.  */
    1229                 :       33876 :               if (flag_split_stack)
    1230                 :             :                 {
    1231                 :       20947 :                   if (local_regparm == 3)
    1232                 :             :                     local_regparm = 2;
    1233                 :         713 :                   else if (local_regparm == 2
    1234                 :         713 :                            && DECL_STATIC_CHAIN (target->decl))
    1235                 :             :                     local_regparm = 1;
    1236                 :             :                 }
    1237                 :             : 
    1238                 :             :               /* Each fixed register usage increases register pressure,
    1239                 :             :                  so less registers should be used for argument passing.
    1240                 :             :                  This functionality can be overriden by an explicit
    1241                 :             :                  regparm value.  */
    1242                 :      237132 :               for (regno = AX_REG; regno <= DI_REG; regno++)
    1243                 :      203256 :                 if (fixed_regs[regno])
    1244                 :           0 :                   globals++;
    1245                 :             : 
    1246                 :       33876 :               local_regparm
    1247                 :       33876 :                 = globals < local_regparm ? local_regparm - globals : 0;
    1248                 :             : 
    1249                 :       33876 :               if (local_regparm > regparm)
    1250                 :     4075922 :                 regparm = local_regparm;
    1251                 :             :             }
    1252                 :             :         }
    1253                 :             :     }
    1254                 :             : 
    1255                 :             :   return regparm;
    1256                 :             : }
    1257                 :             : 
    1258                 :             : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
    1259                 :             :    DFmode (2) arguments in SSE registers for a function with the
    1260                 :             :    indicated TYPE and DECL.  DECL may be NULL when calling function
    1261                 :             :    indirectly or considering a libcall.  Return -1 if any FP parameter
    1262                 :             :    should be rejected by error.  This is used in siutation we imply SSE
    1263                 :             :    calling convetion but the function is called from another function with
    1264                 :             :    SSE disabled. Otherwise return 0.  */
    1265                 :             : 
    1266                 :             : static int
    1267                 :     1060290 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
    1268                 :             : {
    1269                 :     1060290 :   gcc_assert (!TARGET_64BIT);
    1270                 :             : 
    1271                 :             :   /* Use SSE registers to pass SFmode and DFmode arguments if requested
    1272                 :             :      by the sseregparm attribute.  */
    1273                 :     1060290 :   if (TARGET_SSEREGPARM
    1274                 :     1060290 :       || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
    1275                 :             :     {
    1276                 :           0 :       if (!TARGET_SSE)
    1277                 :             :         {
    1278                 :           0 :           if (warn)
    1279                 :             :             {
    1280                 :           0 :               if (decl)
    1281                 :           0 :                 error ("calling %qD with attribute sseregparm without "
    1282                 :             :                        "SSE/SSE2 enabled", decl);
    1283                 :             :               else
    1284                 :           0 :                 error ("calling %qT with attribute sseregparm without "
    1285                 :             :                        "SSE/SSE2 enabled", type);
    1286                 :             :             }
    1287                 :           0 :           return 0;
    1288                 :             :         }
    1289                 :             : 
    1290                 :             :       return 2;
    1291                 :             :     }
    1292                 :             : 
    1293                 :     1060290 :   if (!decl)
    1294                 :             :     return 0;
    1295                 :             : 
    1296                 :      966397 :   cgraph_node *target = cgraph_node::get (decl);
    1297                 :      966397 :   if (target)
    1298                 :      959642 :     target = target->function_symbol ();
    1299                 :             : 
    1300                 :             :   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
    1301                 :             :      (and DFmode for SSE2) arguments in SSE registers.  */
    1302                 :      959642 :   if (target
    1303                 :             :       /* TARGET_SSE_MATH */
    1304                 :      959642 :       && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
    1305                 :        1296 :       && opt_for_fn (target->decl, optimize)
    1306                 :      960938 :       && !(profile_flag && !flag_fentry))
    1307                 :             :     {
    1308                 :        1296 :       if (target->local && target->can_change_signature)
    1309                 :             :         {
    1310                 :             :           /* Refuse to produce wrong code when local function with SSE enabled
    1311                 :             :              is called from SSE disabled function.
    1312                 :             :              FIXME: We need a way to detect these cases cross-ltrans partition
    1313                 :             :              and avoid using SSE calling conventions on local functions called
    1314                 :             :              from function with SSE disabled.  For now at least delay the
    1315                 :             :              warning until we know we are going to produce wrong code.
    1316                 :             :              See PR66047  */
    1317                 :           0 :           if (!TARGET_SSE && warn)
    1318                 :             :             return -1;
    1319                 :           0 :           return TARGET_SSE2_P (target_opts_for_fn (target->decl)
    1320                 :           0 :                                 ->x_ix86_isa_flags) ? 2 : 1;
    1321                 :             :         }
    1322                 :             :     }
    1323                 :             : 
    1324                 :             :   return 0;
    1325                 :             : }
    1326                 :             : 
    1327                 :             : /* Return true if EAX is live at the start of the function.  Used by
    1328                 :             :    ix86_expand_prologue to determine if we need special help before
    1329                 :             :    calling allocate_stack_worker.  */
    1330                 :             : 
    1331                 :             : static bool
    1332                 :        7089 : ix86_eax_live_at_start_p (void)
    1333                 :             : {
    1334                 :             :   /* Cheat.  Don't bother working forward from ix86_function_regparm
    1335                 :             :      to the function type to whether an actual argument is located in
    1336                 :             :      eax.  Instead just look at cfg info, which is still close enough
    1337                 :             :      to correct at this point.  This gives false positives for broken
    1338                 :             :      functions that might use uninitialized data that happens to be
    1339                 :             :      allocated in eax, but who cares?  */
    1340                 :        7089 :   return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
    1341                 :             : }
    1342                 :             : 
    1343                 :             : static bool
    1344                 :      159071 : ix86_keep_aggregate_return_pointer (tree fntype)
    1345                 :             : {
    1346                 :      159071 :   tree attr;
    1347                 :             : 
    1348                 :      159071 :   if (!TARGET_64BIT)
    1349                 :             :     {
    1350                 :      159071 :       attr = lookup_attribute ("callee_pop_aggregate_return",
    1351                 :      159071 :                                TYPE_ATTRIBUTES (fntype));
    1352                 :      159071 :       if (attr)
    1353                 :           0 :         return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
    1354                 :             : 
    1355                 :             :       /* For 32-bit MS-ABI the default is to keep aggregate
    1356                 :             :          return pointer.  */
    1357                 :      159071 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    1358                 :             :         return true;
    1359                 :             :     }
    1360                 :             :   return KEEP_AGGREGATE_RETURN_POINTER != 0;
    1361                 :             : }
    1362                 :             : 
    1363                 :             : /* Value is the number of bytes of arguments automatically
    1364                 :             :    popped when returning from a subroutine call.
    1365                 :             :    FUNDECL is the declaration node of the function (as a tree),
    1366                 :             :    FUNTYPE is the data type of the function (as a tree),
    1367                 :             :    or for a library call it is an identifier node for the subroutine name.
    1368                 :             :    SIZE is the number of bytes of arguments passed on the stack.
    1369                 :             : 
    1370                 :             :    On the 80386, the RTD insn may be used to pop them if the number
    1371                 :             :      of args is fixed, but if the number is variable then the caller
    1372                 :             :      must pop them all.  RTD can't be used for library calls now
    1373                 :             :      because the library is compiled with the Unix compiler.
    1374                 :             :    Use of RTD is a selectable option, since it is incompatible with
    1375                 :             :    standard Unix calling sequences.  If the option is not selected,
    1376                 :             :    the caller must always pop the args.
    1377                 :             : 
    1378                 :             :    The attribute stdcall is equivalent to RTD on a per module basis.  */
    1379                 :             : 
    1380                 :             : static poly_int64
    1381                 :     7095267 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
    1382                 :             : {
    1383                 :     7095267 :   unsigned int ccvt;
    1384                 :             : 
    1385                 :             :   /* None of the 64-bit ABIs pop arguments.  */
    1386                 :     7095267 :   if (TARGET_64BIT)
    1387                 :     6231342 :     return 0;
    1388                 :             : 
    1389                 :      863925 :   ccvt = ix86_get_callcvt (funtype);
    1390                 :             : 
    1391                 :      863925 :   if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
    1392                 :             :                | IX86_CALLCVT_THISCALL)) != 0
    1393                 :      863925 :       && ! stdarg_p (funtype))
    1394                 :           3 :     return size;
    1395                 :             : 
    1396                 :             :   /* Lose any fake structure return argument if it is passed on the stack.  */
    1397                 :      863922 :   if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
    1398                 :      863922 :       && !ix86_keep_aggregate_return_pointer (funtype))
    1399                 :             :     {
    1400                 :      159071 :       int nregs = ix86_function_regparm (funtype, fundecl);
    1401                 :      159071 :       if (nregs == 0)
    1402                 :      304170 :         return GET_MODE_SIZE (Pmode);
    1403                 :             :     }
    1404                 :             : 
    1405                 :      711837 :   return 0;
    1406                 :             : }
    1407                 :             : 
    1408                 :             : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
    1409                 :             : 
    1410                 :             : static bool
    1411                 :     8682814 : ix86_legitimate_combined_insn (rtx_insn *insn)
    1412                 :             : {
    1413                 :     8682814 :   int i;
    1414                 :             : 
    1415                 :             :   /* Check operand constraints in case hard registers were propagated
    1416                 :             :      into insn pattern.  This check prevents combine pass from
    1417                 :             :      generating insn patterns with invalid hard register operands.
    1418                 :             :      These invalid insns can eventually confuse reload to error out
    1419                 :             :      with a spill failure.  See also PRs 46829 and 46843.  */
    1420                 :             : 
    1421                 :     8682814 :   gcc_assert (INSN_CODE (insn) >= 0);
    1422                 :             : 
    1423                 :     8682814 :   extract_insn (insn);
    1424                 :     8682814 :   preprocess_constraints (insn);
    1425                 :             : 
    1426                 :     8682814 :   int n_operands = recog_data.n_operands;
    1427                 :     8682814 :   int n_alternatives = recog_data.n_alternatives;
    1428                 :    29701168 :   for (i = 0; i < n_operands; i++)
    1429                 :             :     {
    1430                 :    21022130 :       rtx op = recog_data.operand[i];
    1431                 :    21022130 :       machine_mode mode = GET_MODE (op);
    1432                 :    21022130 :       const operand_alternative *op_alt;
    1433                 :    21022130 :       int offset = 0;
    1434                 :    21022130 :       bool win;
    1435                 :    21022130 :       int j;
    1436                 :             : 
    1437                 :             :       /* A unary operator may be accepted by the predicate, but it
    1438                 :             :          is irrelevant for matching constraints.  */
    1439                 :    21022130 :       if (UNARY_P (op))
    1440                 :       41570 :         op = XEXP (op, 0);
    1441                 :             : 
    1442                 :    21022130 :       if (SUBREG_P (op))
    1443                 :             :         {
    1444                 :      843745 :           if (REG_P (SUBREG_REG (op))
    1445                 :      843745 :               && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    1446                 :         189 :             offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    1447                 :         189 :                                           GET_MODE (SUBREG_REG (op)),
    1448                 :         189 :                                           SUBREG_BYTE (op),
    1449                 :         189 :                                           GET_MODE (op));
    1450                 :      843745 :           op = SUBREG_REG (op);
    1451                 :             :         }
    1452                 :             : 
    1453                 :    21022130 :       if (!(REG_P (op) && HARD_REGISTER_P (op)))
    1454                 :    20746754 :         continue;
    1455                 :             : 
    1456                 :      275376 :       op_alt = recog_op_alt;
    1457                 :             : 
    1458                 :             :       /* Operand has no constraints, anything is OK.  */
    1459                 :      275376 :       win = !n_alternatives;
    1460                 :             : 
    1461                 :      275376 :       alternative_mask preferred = get_preferred_alternatives (insn);
    1462                 :      752526 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    1463                 :             :         {
    1464                 :      473177 :           if (!TEST_BIT (preferred, j))
    1465                 :      134079 :             continue;
    1466                 :      339098 :           if (op_alt[i].anything_ok
    1467                 :      176307 :               || (op_alt[i].matches != -1
    1468                 :       23927 :                   && operands_match_p
    1469                 :       23927 :                   (recog_data.operand[i],
    1470                 :       23927 :                    recog_data.operand[op_alt[i].matches]))
    1471                 :      511270 :               || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
    1472                 :             :             {
    1473                 :             :               win = true;
    1474                 :             :               break;
    1475                 :             :             }
    1476                 :             :         }
    1477                 :             : 
    1478                 :      275376 :       if (!win)
    1479                 :             :         return false;
    1480                 :             :     }
    1481                 :             : 
    1482                 :             :   return true;
    1483                 :             : }
    1484                 :             : 
    1485                 :             : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
    1486                 :             : 
    1487                 :             : static unsigned HOST_WIDE_INT
    1488                 :        4493 : ix86_asan_shadow_offset (void)
    1489                 :             : {
    1490                 :        4493 :   return SUBTARGET_SHADOW_OFFSET;
    1491                 :             : }
    1492                 :             : 
    1493                 :             : /* Argument support functions.  */
    1494                 :             : 
    1495                 :             : /* Return true when register may be used to pass function parameters.  */
    1496                 :             : bool
    1497                 :  1326346105 : ix86_function_arg_regno_p (int regno)
    1498                 :             : {
    1499                 :  1326346105 :   int i;
    1500                 :  1326346105 :   enum calling_abi call_abi;
    1501                 :  1326346105 :   const int *parm_regs;
    1502                 :             : 
    1503                 :  1323115525 :   if (TARGET_SSE && SSE_REGNO_P (regno)
    1504                 :  2189118567 :       && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
    1505                 :             :     return true;
    1506                 :             : 
    1507                 :  1219906761 :    if (!TARGET_64BIT)
    1508                 :   125272062 :      return (regno < REGPARM_MAX
    1509                 :   125272062 :              || (TARGET_MMX && MMX_REGNO_P (regno)
    1510                 :    11259056 :                  && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
    1511                 :             : 
    1512                 :             :   /* TODO: The function should depend on current function ABI but
    1513                 :             :      builtins.cc would need updating then. Therefore we use the
    1514                 :             :      default ABI.  */
    1515                 :  1094634699 :   call_abi = ix86_cfun_abi ();
    1516                 :             : 
    1517                 :             :   /* RAX is used as hidden argument to va_arg functions.  */
    1518                 :  1094634699 :   if (call_abi == SYSV_ABI && regno == AX_REG)
    1519                 :             :     return true;
    1520                 :             : 
    1521                 :  1082017756 :   if (call_abi == MS_ABI)
    1522                 :             :     parm_regs = x86_64_ms_abi_int_parameter_registers;
    1523                 :             :   else
    1524                 :  1047413660 :     parm_regs = x86_64_int_parameter_registers;
    1525                 :             : 
    1526                 : 14471607866 :   for (i = 0; i < (call_abi == MS_ABI
    1527                 :  7235803933 :                    ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
    1528                 :  6231103816 :     if (regno == parm_regs[i])
    1529                 :             :       return true;
    1530                 :             :   return false;
    1531                 :             : }
    1532                 :             : 
    1533                 :             : /* Return if we do not know how to pass ARG solely in registers.  */
    1534                 :             : 
    1535                 :             : static bool
    1536                 :   336084376 : ix86_must_pass_in_stack (const function_arg_info &arg)
    1537                 :             : {
    1538                 :   336084376 :   if (must_pass_in_stack_var_size_or_pad (arg))
    1539                 :             :     return true;
    1540                 :             : 
    1541                 :             :   /* For 32-bit, we want TImode aggregates to go on the stack.  But watch out!
    1542                 :             :      The layout_type routine is crafty and tries to trick us into passing
    1543                 :             :      currently unsupported vector types on the stack by using TImode.  */
    1544                 :     1744654 :   return (!TARGET_64BIT && arg.mode == TImode
    1545                 :   336084370 :           && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
    1546                 :             : }
    1547                 :             : 
    1548                 :             : /* It returns the size, in bytes, of the area reserved for arguments passed
    1549                 :             :    in registers for the function represented by fndecl dependent to the used
    1550                 :             :    abi format.  */
    1551                 :             : int
    1552                 :     9880782 : ix86_reg_parm_stack_space (const_tree fndecl)
    1553                 :             : {
    1554                 :     9880782 :   enum calling_abi call_abi = SYSV_ABI;
    1555                 :     9880782 :   if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
    1556                 :     9573288 :     call_abi = ix86_function_abi (fndecl);
    1557                 :             :   else
    1558                 :      307494 :     call_abi = ix86_function_type_abi (fndecl);
    1559                 :     9880782 :   if (TARGET_64BIT && call_abi == MS_ABI)
    1560                 :      119298 :     return 32;
    1561                 :             :   return 0;
    1562                 :             : }
    1563                 :             : 
    1564                 :             : /* We add this as a workaround in order to use libc_has_function
    1565                 :             :    hook in i386.md.  */
    1566                 :             : bool
    1567                 :           0 : ix86_libc_has_function (enum function_class fn_class)
    1568                 :             : {
    1569                 :           0 :   return targetm.libc_has_function (fn_class, NULL_TREE);
    1570                 :             : }
    1571                 :             : 
    1572                 :             : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
    1573                 :             :    specifying the call abi used.  */
    1574                 :             : enum calling_abi
    1575                 :   368257252 : ix86_function_type_abi (const_tree fntype)
    1576                 :             : {
    1577                 :   368257252 :   enum calling_abi abi = ix86_abi;
    1578                 :             : 
    1579                 :   368257252 :   if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
    1580                 :             :     return abi;
    1581                 :             : 
    1582                 :    16170088 :   if (abi == SYSV_ABI
    1583                 :    16170088 :       && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
    1584                 :             :     {
    1585                 :     2564581 :       static int warned;
    1586                 :     2564581 :       if (TARGET_X32 && !warned)
    1587                 :             :         {
    1588                 :           1 :           error ("X32 does not support %<ms_abi%> attribute");
    1589                 :           1 :           warned = 1;
    1590                 :             :         }
    1591                 :             : 
    1592                 :             :       abi = MS_ABI;
    1593                 :             :     }
    1594                 :    13605507 :   else if (abi == MS_ABI
    1595                 :    13605507 :            && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
    1596                 :             :     abi = SYSV_ABI;
    1597                 :             : 
    1598                 :             :   return abi;
    1599                 :             : }
    1600                 :             : 
    1601                 :             : enum calling_abi
    1602                 :   180658153 : ix86_function_abi (const_tree fndecl)
    1603                 :             : {
    1604                 :   180658153 :   return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
    1605                 :             : }
    1606                 :             : 
    1607                 :             : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
    1608                 :             :    specifying the call abi used.  */
    1609                 :             : enum calling_abi
    1610                 :  1865343162 : ix86_cfun_abi (void)
    1611                 :             : {
    1612                 :  1865343162 :   return cfun ? cfun->machine->call_abi : ix86_abi;
    1613                 :             : }
    1614                 :             : 
    1615                 :             : bool
    1616                 :     4737367 : ix86_function_ms_hook_prologue (const_tree fn)
    1617                 :             : {
    1618                 :     4737367 :   if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
    1619                 :             :     {
    1620                 :          15 :       if (decl_function_context (fn) != NULL_TREE)
    1621                 :           0 :         error_at (DECL_SOURCE_LOCATION (fn),
    1622                 :             :                   "%<ms_hook_prologue%> attribute is not compatible "
    1623                 :             :                   "with nested function");
    1624                 :             :       else
    1625                 :             :         return true;
    1626                 :             :     }
    1627                 :             :   return false;
    1628                 :             : }
    1629                 :             : 
    1630                 :             : bool
    1631                 :   101118379 : ix86_function_naked (const_tree fn)
    1632                 :             : {
    1633                 :   101118379 :   if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
    1634                 :             :     return true;
    1635                 :             : 
    1636                 :             :   return false;
    1637                 :             : }
    1638                 :             : 
    1639                 :             : /* Write the extra assembler code needed to declare a function properly.  */
    1640                 :             : 
    1641                 :             : void
    1642                 :     1457572 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
    1643                 :             :                                 tree decl)
    1644                 :             : {
    1645                 :     1457572 :   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
    1646                 :             : 
    1647                 :     1457572 :   if (cfun)
    1648                 :     1453912 :     cfun->machine->function_label_emitted = true;
    1649                 :             : 
    1650                 :     1457572 :   if (is_ms_hook)
    1651                 :             :     {
    1652                 :           2 :       int i, filler_count = (TARGET_64BIT ? 32 : 16);
    1653                 :           2 :       unsigned int filler_cc = 0xcccccccc;
    1654                 :             : 
    1655                 :          18 :       for (i = 0; i < filler_count; i += 4)
    1656                 :          16 :         fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
    1657                 :             :     }
    1658                 :             : 
    1659                 :             : #ifdef SUBTARGET_ASM_UNWIND_INIT
    1660                 :             :   SUBTARGET_ASM_UNWIND_INIT (out_file);
    1661                 :             : #endif
    1662                 :             : 
    1663                 :     1457572 :   assemble_function_label_raw (out_file, fname);
    1664                 :             : 
    1665                 :             :   /* Output magic byte marker, if hot-patch attribute is set.  */
    1666                 :     1457572 :   if (is_ms_hook)
    1667                 :             :     {
    1668                 :           2 :       if (TARGET_64BIT)
    1669                 :             :         {
    1670                 :             :           /* leaq [%rsp + 0], %rsp  */
    1671                 :           2 :           fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
    1672                 :             :                  out_file);
    1673                 :             :         }
    1674                 :             :       else
    1675                 :             :         {
    1676                 :             :           /* movl.s %edi, %edi
    1677                 :             :              push   %ebp
    1678                 :             :              movl.s %esp, %ebp */
    1679                 :           0 :           fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
    1680                 :             :         }
    1681                 :             :     }
    1682                 :     1457572 : }
    1683                 :             : 
    1684                 :             : /* Implementation of call abi switching target hook. Specific to FNDECL
    1685                 :             :    the specific call register sets are set.  See also
    1686                 :             :    ix86_conditional_register_usage for more details.  */
    1687                 :             : void
    1688                 :   161732677 : ix86_call_abi_override (const_tree fndecl)
    1689                 :             : {
    1690                 :   161732677 :   cfun->machine->call_abi = ix86_function_abi (fndecl);
    1691                 :   161732677 : }
    1692                 :             : 
    1693                 :             : /* Return 1 if pseudo register should be created and used to hold
    1694                 :             :    GOT address for PIC code.  */
    1695                 :             : bool
    1696                 :   156269335 : ix86_use_pseudo_pic_reg (void)
    1697                 :             : {
    1698                 :   156269335 :   if ((TARGET_64BIT
    1699                 :   145571866 :        && (ix86_cmodel == CM_SMALL_PIC
    1700                 :             :            || TARGET_PECOFF))
    1701                 :   151204333 :       || !flag_pic)
    1702                 :   151735495 :     return false;
    1703                 :             :   return true;
    1704                 :             : }
    1705                 :             : 
    1706                 :             : /* Initialize large model PIC register.  */
    1707                 :             : 
    1708                 :             : static void
    1709                 :          55 : ix86_init_large_pic_reg (unsigned int tmp_regno)
    1710                 :             : {
    1711                 :          55 :   rtx_code_label *label;
    1712                 :          55 :   rtx tmp_reg;
    1713                 :             : 
    1714                 :          55 :   gcc_assert (Pmode == DImode);
    1715                 :          55 :   label = gen_label_rtx ();
    1716                 :          55 :   emit_label (label);
    1717                 :          55 :   LABEL_PRESERVE_P (label) = 1;
    1718                 :          55 :   tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
    1719                 :          55 :   gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
    1720                 :          55 :   emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
    1721                 :             :                                 label));
    1722                 :          55 :   emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
    1723                 :          55 :   emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
    1724                 :          55 :   const char *name = LABEL_NAME (label);
    1725                 :          55 :   PUT_CODE (label, NOTE);
    1726                 :          55 :   NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
    1727                 :          55 :   NOTE_DELETED_LABEL_NAME (label) = name;
    1728                 :          55 : }
    1729                 :             : 
    1730                 :             : /* Create and initialize PIC register if required.  */
    1731                 :             : static void
    1732                 :     1392359 : ix86_init_pic_reg (void)
    1733                 :             : {
    1734                 :     1392359 :   edge entry_edge;
    1735                 :     1392359 :   rtx_insn *seq;
    1736                 :             : 
    1737                 :     1392359 :   if (!ix86_use_pseudo_pic_reg ())
    1738                 :             :     return;
    1739                 :             : 
    1740                 :       39336 :   start_sequence ();
    1741                 :             : 
    1742                 :       39336 :   if (TARGET_64BIT)
    1743                 :             :     {
    1744                 :          68 :       if (ix86_cmodel == CM_LARGE_PIC)
    1745                 :          51 :         ix86_init_large_pic_reg (R11_REG);
    1746                 :             :       else
    1747                 :          17 :         emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
    1748                 :             :     }
    1749                 :             :   else
    1750                 :             :     {
    1751                 :             :       /*  If there is future mcount call in the function it is more profitable
    1752                 :             :           to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM.  */
    1753                 :       39268 :       rtx reg = crtl->profile
    1754                 :       39268 :                 ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
    1755                 :       39268 :                 : pic_offset_table_rtx;
    1756                 :       39268 :       rtx_insn *insn = emit_insn (gen_set_got (reg));
    1757                 :       39268 :       RTX_FRAME_RELATED_P (insn) = 1;
    1758                 :       39268 :       if (crtl->profile)
    1759                 :           0 :         emit_move_insn (pic_offset_table_rtx, reg);
    1760                 :       39268 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    1761                 :             :     }
    1762                 :             : 
    1763                 :       39336 :   seq = get_insns ();
    1764                 :       39336 :   end_sequence ();
    1765                 :             : 
    1766                 :       39336 :   entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1767                 :       39336 :   insert_insn_on_edge (seq, entry_edge);
    1768                 :       39336 :   commit_one_edge_insertion (entry_edge);
    1769                 :             : }
    1770                 :             : 
    1771                 :             : /* Initialize a variable CUM of type CUMULATIVE_ARGS
    1772                 :             :    for a call to a function whose data type is FNTYPE.
    1773                 :             :    For a library call, FNTYPE is 0.  */
    1774                 :             : 
    1775                 :             : void
    1776                 :     9628609 : init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
    1777                 :             :                       tree fntype,      /* tree ptr for function decl */
    1778                 :             :                       rtx libname,      /* SYMBOL_REF of library name or 0 */
    1779                 :             :                       tree fndecl,
    1780                 :             :                       int caller)
    1781                 :             : {
    1782                 :     9628609 :   struct cgraph_node *local_info_node = NULL;
    1783                 :     9628609 :   struct cgraph_node *target = NULL;
    1784                 :             : 
    1785                 :             :   /* Set silent_p to false to raise an error for invalid calls when
    1786                 :             :      expanding function body.  */
    1787                 :     9628609 :   cfun->machine->silent_p = false;
    1788                 :             : 
    1789                 :     9628609 :   memset (cum, 0, sizeof (*cum));
    1790                 :             : 
    1791                 :     9628609 :   if (fndecl)
    1792                 :             :     {
    1793                 :     9306464 :       target = cgraph_node::get (fndecl);
    1794                 :     9306464 :       if (target)
    1795                 :             :         {
    1796                 :     9199165 :           target = target->function_symbol ();
    1797                 :     9199165 :           local_info_node = cgraph_node::local_info_node (target->decl);
    1798                 :     9199165 :           cum->call_abi = ix86_function_abi (target->decl);
    1799                 :             :         }
    1800                 :             :       else
    1801                 :      107299 :         cum->call_abi = ix86_function_abi (fndecl);
    1802                 :             :     }
    1803                 :             :   else
    1804                 :      322145 :     cum->call_abi = ix86_function_type_abi (fntype);
    1805                 :             : 
    1806                 :     9628609 :   cum->caller = caller;
    1807                 :             : 
    1808                 :             :   /* Set up the number of registers to use for passing arguments.  */
    1809                 :     9628609 :   cum->nregs = ix86_regparm;
    1810                 :     9628609 :   if (TARGET_64BIT)
    1811                 :             :     {
    1812                 :     8608254 :       cum->nregs = (cum->call_abi == SYSV_ABI
    1813                 :     8608254 :                    ? X86_64_REGPARM_MAX
    1814                 :             :                    : X86_64_MS_REGPARM_MAX);
    1815                 :             :     }
    1816                 :     9628609 :   if (TARGET_SSE)
    1817                 :             :     {
    1818                 :     9619566 :       cum->sse_nregs = SSE_REGPARM_MAX;
    1819                 :     9619566 :       if (TARGET_64BIT)
    1820                 :             :         {
    1821                 :     8599322 :           cum->sse_nregs = (cum->call_abi == SYSV_ABI
    1822                 :     8599322 :                            ? X86_64_SSE_REGPARM_MAX
    1823                 :             :                            : X86_64_MS_SSE_REGPARM_MAX);
    1824                 :             :         }
    1825                 :             :     }
    1826                 :     9628609 :   if (TARGET_MMX)
    1827                 :    10441968 :     cum->mmx_nregs = MMX_REGPARM_MAX;
    1828                 :     9628609 :   cum->warn_avx512f = true;
    1829                 :     9628609 :   cum->warn_avx = true;
    1830                 :     9628609 :   cum->warn_sse = true;
    1831                 :     9628609 :   cum->warn_mmx = true;
    1832                 :             : 
    1833                 :             :   /* Because type might mismatch in between caller and callee, we need to
    1834                 :             :      use actual type of function for local calls.
    1835                 :             :      FIXME: cgraph_analyze can be told to actually record if function uses
    1836                 :             :      va_start so for local functions maybe_vaarg can be made aggressive
    1837                 :             :      helping K&R code.
    1838                 :             :      FIXME: once typesytem is fixed, we won't need this code anymore.  */
    1839                 :     9628609 :   if (local_info_node && local_info_node->local
    1840                 :     9199165 :       && local_info_node->can_change_signature)
    1841                 :      346454 :     fntype = TREE_TYPE (target->decl);
    1842                 :     9628609 :   cum->stdarg = stdarg_p (fntype);
    1843                 :    19257218 :   cum->maybe_vaarg = (fntype
    1844                 :    10165461 :                       ? (!prototype_p (fntype) || stdarg_p (fntype))
    1845                 :      120224 :                       : !libname);
    1846                 :             : 
    1847                 :     9628609 :   cum->decl = fndecl;
    1848                 :             : 
    1849                 :     9628609 :   cum->warn_empty = !warn_abi || cum->stdarg;
    1850                 :     9628609 :   if (!cum->warn_empty && fntype)
    1851                 :             :     {
    1852                 :      106506 :       function_args_iterator iter;
    1853                 :      106506 :       tree argtype;
    1854                 :      106506 :       bool seen_empty_type = false;
    1855                 :      305707 :       FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
    1856                 :             :         {
    1857                 :      305707 :           if (argtype == error_mark_node || VOID_TYPE_P (argtype))
    1858                 :             :             break;
    1859                 :      199655 :           if (TYPE_EMPTY_P (argtype))
    1860                 :             :             seen_empty_type = true;
    1861                 :      198751 :           else if (seen_empty_type)
    1862                 :             :             {
    1863                 :         454 :               cum->warn_empty = true;
    1864                 :         454 :               break;
    1865                 :             :             }
    1866                 :             :         }
    1867                 :             :     }
    1868                 :             : 
    1869                 :     9628609 :   if (!TARGET_64BIT)
    1870                 :             :     {
    1871                 :             :       /* If there are variable arguments, then we won't pass anything
    1872                 :             :          in registers in 32-bit mode. */
    1873                 :     1020355 :       if (stdarg_p (fntype))
    1874                 :             :         {
    1875                 :        8209 :           cum->nregs = 0;
    1876                 :             :           /* Since in 32-bit, variable arguments are always passed on
    1877                 :             :              stack, there is scratch register available for indirect
    1878                 :             :              sibcall.  */
    1879                 :        8209 :           cfun->machine->arg_reg_available = true;
    1880                 :        8209 :           cum->sse_nregs = 0;
    1881                 :        8209 :           cum->mmx_nregs = 0;
    1882                 :        8209 :           cum->warn_avx512f = false;
    1883                 :        8209 :           cum->warn_avx = false;
    1884                 :        8209 :           cum->warn_sse = false;
    1885                 :        8209 :           cum->warn_mmx = false;
    1886                 :        8209 :           return;
    1887                 :             :         }
    1888                 :             : 
    1889                 :             :       /* Use ecx and edx registers if function has fastcall attribute,
    1890                 :             :          else look for regparm information.  */
    1891                 :     1012146 :       if (fntype)
    1892                 :             :         {
    1893                 :      998900 :           unsigned int ccvt = ix86_get_callcvt (fntype);
    1894                 :      998900 :           if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1895                 :             :             {
    1896                 :           0 :               cum->nregs = 1;
    1897                 :           0 :               cum->fastcall = 1; /* Same first register as in fastcall.  */
    1898                 :             :             }
    1899                 :      998900 :           else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1900                 :             :             {
    1901                 :           4 :               cum->nregs = 2;
    1902                 :           4 :               cum->fastcall = 1;
    1903                 :             :             }
    1904                 :             :           else
    1905                 :      998896 :             cum->nregs = ix86_function_regparm (fntype, fndecl);
    1906                 :             :         }
    1907                 :             : 
    1908                 :             :       /* Set up the number of SSE registers used for passing SFmode
    1909                 :             :          and DFmode arguments.  Warn for mismatching ABI.  */
    1910                 :     1012146 :       cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
    1911                 :             :     }
    1912                 :             : 
    1913                 :     9620400 :   cfun->machine->arg_reg_available = (cum->nregs > 0);
    1914                 :             : }
    1915                 :             : 
    1916                 :             : /* Return the "natural" mode for TYPE.  In most cases, this is just TYPE_MODE.
    1917                 :             :    But in the case of vector types, it is some vector mode.
    1918                 :             : 
    1919                 :             :    When we have only some of our vector isa extensions enabled, then there
    1920                 :             :    are some modes for which vector_mode_supported_p is false.  For these
    1921                 :             :    modes, the generic vector support in gcc will choose some non-vector mode
    1922                 :             :    in order to implement the type.  By computing the natural mode, we'll
    1923                 :             :    select the proper ABI location for the operand and not depend on whatever
    1924                 :             :    the middle-end decides to do with these vector types.
    1925                 :             : 
    1926                 :             :    The midde-end can't deal with the vector types > 16 bytes.  In this
    1927                 :             :    case, we return the original mode and warn ABI change if CUM isn't
    1928                 :             :    NULL. 
    1929                 :             : 
    1930                 :             :    If INT_RETURN is true, warn ABI change if the vector mode isn't
    1931                 :             :    available for function return value.  */
    1932                 :             : 
    1933                 :             : static machine_mode
    1934                 :   193898152 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
    1935                 :             :                    bool in_return)
    1936                 :             : {
    1937                 :   193898152 :   machine_mode mode = TYPE_MODE (type);
    1938                 :             : 
    1939                 :   193898152 :   if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
    1940                 :             :     {
    1941                 :      417923 :       HOST_WIDE_INT size = int_size_in_bytes (type);
    1942                 :      417923 :       if ((size == 8 || size == 16 || size == 32 || size == 64)
    1943                 :             :           /* ??? Generic code allows us to create width 1 vectors.  Ignore.  */
    1944                 :      417923 :           && TYPE_VECTOR_SUBPARTS (type) > 1)
    1945                 :             :         {
    1946                 :      383394 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
    1947                 :             : 
    1948                 :             :           /* There are no XFmode vector modes ...  */
    1949                 :      383394 :           if (innermode == XFmode)
    1950                 :             :             return mode;
    1951                 :             : 
    1952                 :             :           /* ... and no decimal float vector modes.  */
    1953                 :      382843 :           if (DECIMAL_FLOAT_MODE_P (innermode))
    1954                 :             :             return mode;
    1955                 :             : 
    1956                 :      382600 :           if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
    1957                 :             :             mode = MIN_MODE_VECTOR_FLOAT;
    1958                 :             :           else
    1959                 :      317105 :             mode = MIN_MODE_VECTOR_INT;
    1960                 :             : 
    1961                 :             :           /* Get the mode which has this inner mode and number of units.  */
    1962                 :     7999883 :           FOR_EACH_MODE_FROM (mode, mode)
    1963                 :    16596146 :             if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
    1964                 :     8978863 :                 && GET_MODE_INNER (mode) == innermode)
    1965                 :             :               {
    1966                 :      382600 :                 if (size == 64 && (!TARGET_AVX512F || !TARGET_EVEX512)
    1967                 :      259296 :                     && !TARGET_IAMCU)
    1968                 :             :                   {
    1969                 :      259296 :                     static bool warnedavx512f;
    1970                 :      259296 :                     static bool warnedavx512f_ret;
    1971                 :             : 
    1972                 :      259296 :                     if (cum && cum->warn_avx512f && !warnedavx512f)
    1973                 :             :                       {
    1974                 :        1135 :                         if (warning (OPT_Wpsabi, "AVX512F vector argument "
    1975                 :             :                                      "without AVX512F enabled changes the ABI"))
    1976                 :           2 :                           warnedavx512f = true;
    1977                 :             :                       }
    1978                 :      258161 :                     else if (in_return && !warnedavx512f_ret)
    1979                 :             :                       {
    1980                 :      255547 :                         if (warning (OPT_Wpsabi, "AVX512F vector return "
    1981                 :             :                                      "without AVX512F enabled changes the ABI"))
    1982                 :           2 :                           warnedavx512f_ret = true;
    1983                 :             :                       }
    1984                 :             : 
    1985                 :      259296 :                     return TYPE_MODE (type);
    1986                 :             :                   }
    1987                 :      123304 :                 else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
    1988                 :             :                   {
    1989                 :      122760 :                     static bool warnedavx;
    1990                 :      122760 :                     static bool warnedavx_ret;
    1991                 :             : 
    1992                 :      122760 :                     if (cum && cum->warn_avx && !warnedavx)
    1993                 :             :                       {
    1994                 :         612 :                         if (warning (OPT_Wpsabi, "AVX vector argument "
    1995                 :             :                                      "without AVX enabled changes the ABI"))
    1996                 :           5 :                           warnedavx = true;
    1997                 :             :                       }
    1998                 :      122148 :                     else if (in_return && !warnedavx_ret)
    1999                 :             :                       {
    2000                 :      120165 :                         if (warning (OPT_Wpsabi, "AVX vector return "
    2001                 :             :                                      "without AVX enabled changes the ABI"))
    2002                 :           7 :                           warnedavx_ret = true;
    2003                 :             :                       }
    2004                 :             : 
    2005                 :      122760 :                     return TYPE_MODE (type);
    2006                 :             :                   }
    2007                 :         544 :                 else if (((size == 8 && TARGET_64BIT) || size == 16)
    2008                 :         541 :                          && !TARGET_SSE
    2009                 :         124 :                          && !TARGET_IAMCU)
    2010                 :             :                   {
    2011                 :         124 :                     static bool warnedsse;
    2012                 :         124 :                     static bool warnedsse_ret;
    2013                 :             : 
    2014                 :         124 :                     if (cum && cum->warn_sse && !warnedsse)
    2015                 :             :                       {
    2016                 :          19 :                         if (warning (OPT_Wpsabi, "SSE vector argument "
    2017                 :             :                                      "without SSE enabled changes the ABI"))
    2018                 :           6 :                           warnedsse = true;
    2019                 :             :                       }
    2020                 :         105 :                     else if (!TARGET_64BIT && in_return && !warnedsse_ret)
    2021                 :             :                       {
    2022                 :           0 :                         if (warning (OPT_Wpsabi, "SSE vector return "
    2023                 :             :                                      "without SSE enabled changes the ABI"))
    2024                 :           0 :                           warnedsse_ret = true;
    2025                 :             :                       }
    2026                 :             :                   }
    2027                 :         420 :                 else if ((size == 8 && !TARGET_64BIT)
    2028                 :           0 :                          && (!cfun
    2029                 :           0 :                              || cfun->machine->func_type == TYPE_NORMAL)
    2030                 :           0 :                          && !TARGET_MMX
    2031                 :           0 :                          && !TARGET_IAMCU)
    2032                 :             :                   {
    2033                 :           0 :                     static bool warnedmmx;
    2034                 :           0 :                     static bool warnedmmx_ret;
    2035                 :             : 
    2036                 :           0 :                     if (cum && cum->warn_mmx && !warnedmmx)
    2037                 :             :                       {
    2038                 :           0 :                         if (warning (OPT_Wpsabi, "MMX vector argument "
    2039                 :             :                                      "without MMX enabled changes the ABI"))
    2040                 :           0 :                           warnedmmx = true;
    2041                 :             :                       }
    2042                 :           0 :                     else if (in_return && !warnedmmx_ret)
    2043                 :             :                       {
    2044                 :           0 :                         if (warning (OPT_Wpsabi, "MMX vector return "
    2045                 :             :                                      "without MMX enabled changes the ABI"))
    2046                 :           0 :                           warnedmmx_ret = true;
    2047                 :             :                       }
    2048                 :             :                   }
    2049                 :         544 :                 return mode;
    2050                 :             :               }
    2051                 :             : 
    2052                 :           0 :           gcc_unreachable ();
    2053                 :             :         }
    2054                 :             :     }
    2055                 :             : 
    2056                 :             :   return mode;
    2057                 :             : }
    2058                 :             : 
    2059                 :             : /* We want to pass a value in REGNO whose "natural" mode is MODE.  However,
    2060                 :             :    this may not agree with the mode that the type system has chosen for the
    2061                 :             :    register, which is ORIG_MODE.  If ORIG_MODE is not BLKmode, then we can
    2062                 :             :    go ahead and use it.  Otherwise we have to build a PARALLEL instead.  */
    2063                 :             : 
    2064                 :             : static rtx
    2065                 :    31704403 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
    2066                 :             :                      unsigned int regno)
    2067                 :             : {
    2068                 :    31704403 :   rtx tmp;
    2069                 :             : 
    2070                 :    31704403 :   if (orig_mode != BLKmode)
    2071                 :    31704375 :     tmp = gen_rtx_REG (orig_mode, regno);
    2072                 :             :   else
    2073                 :             :     {
    2074                 :          28 :       tmp = gen_rtx_REG (mode, regno);
    2075                 :          28 :       tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
    2076                 :          28 :       tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
    2077                 :             :     }
    2078                 :             : 
    2079                 :    31704403 :   return tmp;
    2080                 :             : }
    2081                 :             : 
    2082                 :             : /* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    2083                 :             :    of this code is to classify each 8bytes of incoming argument by the register
    2084                 :             :    class and assign registers accordingly.  */
    2085                 :             : 
    2086                 :             : /* Return the union class of CLASS1 and CLASS2.
    2087                 :             :    See the x86-64 PS ABI for details.  */
    2088                 :             : 
    2089                 :             : static enum x86_64_reg_class
    2090                 :    37719195 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
    2091                 :             : {
    2092                 :             :   /* Rule #1: If both classes are equal, this is the resulting class.  */
    2093                 :    37719195 :   if (class1 == class2)
    2094                 :             :     return class1;
    2095                 :             : 
    2096                 :             :   /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
    2097                 :             :      the other class.  */
    2098                 :    32795677 :   if (class1 == X86_64_NO_CLASS)
    2099                 :             :     return class2;
    2100                 :    32713979 :   if (class2 == X86_64_NO_CLASS)
    2101                 :             :     return class1;
    2102                 :             : 
    2103                 :             :   /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
    2104                 :     1377224 :   if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
    2105                 :             :     return X86_64_MEMORY_CLASS;
    2106                 :             : 
    2107                 :             :   /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
    2108                 :     1376630 :   if ((class1 == X86_64_INTEGERSI_CLASS
    2109                 :      190146 :        && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
    2110                 :     1375347 :       || (class2 == X86_64_INTEGERSI_CLASS
    2111                 :      624375 :           && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
    2112                 :             :     return X86_64_INTEGERSI_CLASS;
    2113                 :     1371483 :   if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
    2114                 :      471254 :       || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
    2115                 :             :     return X86_64_INTEGER_CLASS;
    2116                 :             : 
    2117                 :             :   /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
    2118                 :             :      MEMORY is used.  */
    2119                 :       60317 :   if (class1 == X86_64_X87_CLASS
    2120                 :             :       || class1 == X86_64_X87UP_CLASS
    2121                 :       60317 :       || class1 == X86_64_COMPLEX_X87_CLASS
    2122                 :             :       || class2 == X86_64_X87_CLASS
    2123                 :       59412 :       || class2 == X86_64_X87UP_CLASS
    2124                 :       59102 :       || class2 == X86_64_COMPLEX_X87_CLASS)
    2125                 :        1215 :     return X86_64_MEMORY_CLASS;
    2126                 :             : 
    2127                 :             :   /* Rule #6: Otherwise class SSE is used.  */
    2128                 :             :   return X86_64_SSE_CLASS;
    2129                 :             : }
    2130                 :             : 
    2131                 :             : /* Classify the argument of type TYPE and mode MODE.
    2132                 :             :    CLASSES will be filled by the register class used to pass each word
    2133                 :             :    of the operand.  The number of words is returned.  In case the parameter
    2134                 :             :    should be passed in memory, 0 is returned. As a special case for zero
    2135                 :             :    sized containers, classes[0] will be NO_CLASS and 1 is returned.
    2136                 :             : 
    2137                 :             :    BIT_OFFSET is used internally for handling records and specifies offset
    2138                 :             :    of the offset in bits modulo 512 to avoid overflow cases.
    2139                 :             : 
    2140                 :             :    See the x86-64 PS ABI for details.
    2141                 :             : */
    2142                 :             : 
    2143                 :             : static int
    2144                 :   322539139 : classify_argument (machine_mode mode, const_tree type,
    2145                 :             :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
    2146                 :             :                    int &zero_width_bitfields)
    2147                 :             : {
    2148                 :   322539139 :   HOST_WIDE_INT bytes
    2149                 :   640246385 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2150                 :   322539139 :   int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
    2151                 :             : 
    2152                 :             :   /* Variable sized entities are always passed/returned in memory.  */
    2153                 :   322539139 :   if (bytes < 0)
    2154                 :             :     return 0;
    2155                 :             : 
    2156                 :   322538055 :   if (mode != VOIDmode)
    2157                 :             :     {
    2158                 :             :       /* The value of "named" doesn't matter.  */
    2159                 :   321823149 :       function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
    2160                 :   321823149 :       if (targetm.calls.must_pass_in_stack (arg))
    2161                 :           6 :         return 0;
    2162                 :             :     }
    2163                 :             : 
    2164                 :   322538049 :   if (type && (AGGREGATE_TYPE_P (type)
    2165                 :   300153657 :                || (TREE_CODE (type) == BITINT_TYPE && words > 1)))
    2166                 :             :     {
    2167                 :    23521373 :       int i;
    2168                 :    23521373 :       tree field;
    2169                 :    23521373 :       enum x86_64_reg_class subclasses[MAX_CLASSES];
    2170                 :             : 
    2171                 :             :       /* On x86-64 we pass structures larger than 64 bytes on the stack.  */
    2172                 :    23521373 :       if (bytes > 64)
    2173                 :             :         return 0;
    2174                 :             : 
    2175                 :    61492638 :       for (i = 0; i < words; i++)
    2176                 :    38757743 :         classes[i] = X86_64_NO_CLASS;
    2177                 :             : 
    2178                 :             :       /* Zero sized arrays or structures are NO_CLASS.  We return 0 to
    2179                 :             :          signalize memory class, so handle it as special case.  */
    2180                 :    22734895 :       if (!words)
    2181                 :             :         {
    2182                 :       64994 :           classes[0] = X86_64_NO_CLASS;
    2183                 :       64994 :           return 1;
    2184                 :             :         }
    2185                 :             : 
    2186                 :             :       /* Classify each field of record and merge classes.  */
    2187                 :    22669901 :       switch (TREE_CODE (type))
    2188                 :             :         {
    2189                 :    20747466 :         case RECORD_TYPE:
    2190                 :             :           /* And now merge the fields of structure.  */
    2191                 :   499263311 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2192                 :             :             {
    2193                 :   478694968 :               if (TREE_CODE (field) == FIELD_DECL)
    2194                 :             :                 {
    2195                 :    32343311 :                   int num;
    2196                 :             : 
    2197                 :    32343311 :                   if (TREE_TYPE (field) == error_mark_node)
    2198                 :           5 :                     continue;
    2199                 :             : 
    2200                 :             :                   /* Bitfields are always classified as integer.  Handle them
    2201                 :             :                      early, since later code would consider them to be
    2202                 :             :                      misaligned integers.  */
    2203                 :    32343306 :                   if (DECL_BIT_FIELD (field))
    2204                 :             :                     {
    2205                 :      415136 :                       if (integer_zerop (DECL_SIZE (field)))
    2206                 :             :                         {
    2207                 :       12911 :                           if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
    2208                 :        8057 :                             continue;
    2209                 :        4854 :                           if (zero_width_bitfields != 2)
    2210                 :             :                             {
    2211                 :        4320 :                               zero_width_bitfields = 1;
    2212                 :        4320 :                               continue;
    2213                 :             :                             }
    2214                 :             :                         }
    2215                 :      402759 :                       for (i = (int_bit_position (field)
    2216                 :      402759 :                                 + (bit_offset % 64)) / 8 / 8;
    2217                 :      808625 :                            i < ((int_bit_position (field) + (bit_offset % 64))
    2218                 :      808625 :                                 + tree_to_shwi (DECL_SIZE (field))
    2219                 :      808625 :                                 + 63) / 8 / 8; i++)
    2220                 :      405866 :                         classes[i]
    2221                 :      405866 :                           = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
    2222                 :             :                     }
    2223                 :             :                   else
    2224                 :             :                     {
    2225                 :    31928170 :                       int pos;
    2226                 :             : 
    2227                 :    31928170 :                       type = TREE_TYPE (field);
    2228                 :             : 
    2229                 :             :                       /* Flexible array member is ignored.  */
    2230                 :    31928170 :                       if (TYPE_MODE (type) == BLKmode
    2231                 :      408499 :                           && TREE_CODE (type) == ARRAY_TYPE
    2232                 :      174705 :                           && TYPE_SIZE (type) == NULL_TREE
    2233                 :        2016 :                           && TYPE_DOMAIN (type) != NULL_TREE
    2234                 :    31929415 :                           && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
    2235                 :             :                               == NULL_TREE))
    2236                 :             :                         {
    2237                 :        1245 :                           static bool warned;
    2238                 :             : 
    2239                 :        1245 :                           if (!warned && warn_psabi)
    2240                 :             :                             {
    2241                 :           2 :                               warned = true;
    2242                 :           2 :                               inform (input_location,
    2243                 :             :                                       "the ABI of passing struct with"
    2244                 :             :                                       " a flexible array member has"
    2245                 :             :                                       " changed in GCC 4.4");
    2246                 :             :                             }
    2247                 :        1245 :                           continue;
    2248                 :        1245 :                         }
    2249                 :    31926925 :                       num = classify_argument (TYPE_MODE (type), type,
    2250                 :             :                                                subclasses,
    2251                 :    31926925 :                                                (int_bit_position (field)
    2252                 :    31926925 :                                                 + bit_offset) % 512,
    2253                 :             :                                                zero_width_bitfields);
    2254                 :    31926925 :                       if (!num)
    2255                 :             :                         return 0;
    2256                 :    31747802 :                       pos = (int_bit_position (field)
    2257                 :    31747802 :                              + (bit_offset % 64)) / 8 / 8;
    2258                 :    66310315 :                       for (i = 0; i < num && (i + pos) < words; i++)
    2259                 :    34562513 :                         classes[i + pos]
    2260                 :    34562513 :                           = merge_classes (subclasses[i], classes[i + pos]);
    2261                 :             :                     }
    2262                 :             :                 }
    2263                 :             :             }
    2264                 :             :           break;
    2265                 :             : 
    2266                 :      375515 :         case ARRAY_TYPE:
    2267                 :             :           /* Arrays are handled as small records.  */
    2268                 :      375515 :           {
    2269                 :      375515 :             int num;
    2270                 :      375515 :             num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
    2271                 :      375515 :                                      TREE_TYPE (type), subclasses, bit_offset,
    2272                 :             :                                      zero_width_bitfields);
    2273                 :      375515 :             if (!num)
    2274                 :             :               return 0;
    2275                 :             : 
    2276                 :             :             /* The partial classes are now full classes.  */
    2277                 :      372596 :             if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
    2278                 :       13634 :               subclasses[0] = X86_64_SSE_CLASS;
    2279                 :      372596 :             if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
    2280                 :        4704 :               subclasses[0] = X86_64_SSE_CLASS;
    2281                 :      372596 :             if (subclasses[0] == X86_64_INTEGERSI_CLASS
    2282                 :      170711 :                 && !((bit_offset % 64) == 0 && bytes == 4))
    2283                 :      117469 :               subclasses[0] = X86_64_INTEGER_CLASS;
    2284                 :             : 
    2285                 :     1202256 :             for (i = 0; i < words; i++)
    2286                 :      829660 :               classes[i] = subclasses[i % num];
    2287                 :             : 
    2288                 :             :             break;
    2289                 :             :           }
    2290                 :      292238 :         case UNION_TYPE:
    2291                 :      292238 :         case QUAL_UNION_TYPE:
    2292                 :             :           /* Unions are similar to RECORD_TYPE but offset is always 0.
    2293                 :             :              */
    2294                 :     3585215 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2295                 :             :             {
    2296                 :     3326507 :               if (TREE_CODE (field) == FIELD_DECL)
    2297                 :             :                 {
    2298                 :     1781881 :                   int num;
    2299                 :             : 
    2300                 :     1781881 :                   if (TREE_TYPE (field) == error_mark_node)
    2301                 :           1 :                     continue;
    2302                 :             : 
    2303                 :     1781880 :                   num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
    2304                 :     1781880 :                                            TREE_TYPE (field), subclasses,
    2305                 :             :                                            bit_offset, zero_width_bitfields);
    2306                 :     1781880 :                   if (!num)
    2307                 :             :                     return 0;
    2308                 :     4499166 :                   for (i = 0; i < num && i < words; i++)
    2309                 :     2750816 :                     classes[i] = merge_classes (subclasses[i], classes[i]);
    2310                 :             :                 }
    2311                 :             :             }
    2312                 :             :           break;
    2313                 :             : 
    2314                 :     1254682 :         case BITINT_TYPE:
    2315                 :             :           /* _BitInt(N) for N > 64 is passed as structure containing
    2316                 :             :              (N + 63) / 64 64-bit elements.  */
    2317                 :     1254682 :           if (words > 2)
    2318                 :             :             return 0;
    2319                 :       74519 :           classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2320                 :       74519 :           return 2;
    2321                 :             : 
    2322                 :           0 :         default:
    2323                 :           0 :           gcc_unreachable ();
    2324                 :             :         }
    2325                 :             : 
    2326                 :    21199647 :       if (words > 2)
    2327                 :             :         {
    2328                 :             :           /* When size > 16 bytes, if the first one isn't
    2329                 :             :              X86_64_SSE_CLASS or any other ones aren't
    2330                 :             :              X86_64_SSEUP_CLASS, everything should be passed in
    2331                 :             :              memory.  */
    2332                 :     1058155 :           if (classes[0] != X86_64_SSE_CLASS)
    2333                 :             :             return 0;
    2334                 :             : 
    2335                 :      188168 :           for (i = 1; i < words; i++)
    2336                 :      170811 :             if (classes[i] != X86_64_SSEUP_CLASS)
    2337                 :             :               return 0;
    2338                 :             :         }
    2339                 :             : 
    2340                 :             :       /* Final merger cleanup.  */
    2341                 :    50004466 :       for (i = 0; i < words; i++)
    2342                 :             :         {
    2343                 :             :           /* If one class is MEMORY, everything should be passed in
    2344                 :             :              memory.  */
    2345                 :    29848491 :           if (classes[i] == X86_64_MEMORY_CLASS)
    2346                 :             :             return 0;
    2347                 :             : 
    2348                 :             :           /* The X86_64_SSEUP_CLASS should be always preceded by
    2349                 :             :              X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
    2350                 :    29847989 :           if (classes[i] == X86_64_SSEUP_CLASS
    2351                 :      141445 :               && classes[i - 1] != X86_64_SSE_CLASS
    2352                 :       73474 :               && classes[i - 1] != X86_64_SSEUP_CLASS)
    2353                 :             :             {
    2354                 :             :               /* The first one should never be X86_64_SSEUP_CLASS.  */
    2355                 :        1916 :               gcc_assert (i != 0);
    2356                 :        1916 :               classes[i] = X86_64_SSE_CLASS;
    2357                 :             :             }
    2358                 :             : 
    2359                 :             :           /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
    2360                 :             :              everything should be passed in memory.  */
    2361                 :    29847989 :           if (classes[i] == X86_64_X87UP_CLASS
    2362                 :      186992 :               && (classes[i - 1] != X86_64_X87_CLASS))
    2363                 :             :             {
    2364                 :        2372 :               static bool warned;
    2365                 :             : 
    2366                 :             :               /* The first one should never be X86_64_X87UP_CLASS.  */
    2367                 :        2372 :               gcc_assert (i != 0);
    2368                 :        2372 :               if (!warned && warn_psabi)
    2369                 :             :                 {
    2370                 :           1 :                   warned = true;
    2371                 :           1 :                   inform (input_location,
    2372                 :             :                           "the ABI of passing union with %<long double%>"
    2373                 :             :                           " has changed in GCC 4.4");
    2374                 :             :                 }
    2375                 :        2372 :               return 0;
    2376                 :             :             }
    2377                 :             :         }
    2378                 :             :       return words;
    2379                 :             :     }
    2380                 :             : 
    2381                 :             :   /* Compute alignment needed.  We align all types to natural boundaries with
    2382                 :             :      exception of XFmode that is aligned to 64bits.  */
    2383                 :   299016676 :   if (mode != VOIDmode && mode != BLKmode)
    2384                 :             :     {
    2385                 :   297886977 :       int mode_alignment = GET_MODE_BITSIZE (mode);
    2386                 :             : 
    2387                 :   297886977 :       if (mode == XFmode)
    2388                 :             :         mode_alignment = 128;
    2389                 :   291019636 :       else if (mode == XCmode)
    2390                 :      539289 :         mode_alignment = 256;
    2391                 :   297886977 :       if (COMPLEX_MODE_P (mode))
    2392                 :     2348069 :         mode_alignment /= 2;
    2393                 :             :       /* Misaligned fields are always returned in memory.  */
    2394                 :   297886977 :       if (bit_offset % mode_alignment)
    2395                 :             :         return 0;
    2396                 :             :     }
    2397                 :             : 
    2398                 :             :   /* for V1xx modes, just use the base mode */
    2399                 :   299009043 :   if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
    2400                 :   378606249 :       && GET_MODE_UNIT_SIZE (mode) == bytes)
    2401                 :        2927 :     mode = GET_MODE_INNER (mode);
    2402                 :             : 
    2403                 :             :   /* Classification of atomic types.  */
    2404                 :   299009043 :   switch (mode)
    2405                 :             :     {
    2406                 :      221632 :     case E_SDmode:
    2407                 :      221632 :     case E_DDmode:
    2408                 :      221632 :       classes[0] = X86_64_SSE_CLASS;
    2409                 :      221632 :       return 1;
    2410                 :      106532 :     case E_TDmode:
    2411                 :      106532 :       classes[0] = X86_64_SSE_CLASS;
    2412                 :      106532 :       classes[1] = X86_64_SSEUP_CLASS;
    2413                 :      106532 :       return 2;
    2414                 :   191456578 :     case E_DImode:
    2415                 :   191456578 :     case E_SImode:
    2416                 :   191456578 :     case E_HImode:
    2417                 :   191456578 :     case E_QImode:
    2418                 :   191456578 :     case E_CSImode:
    2419                 :   191456578 :     case E_CHImode:
    2420                 :   191456578 :     case E_CQImode:
    2421                 :   191456578 :       {
    2422                 :   191456578 :         int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
    2423                 :             : 
    2424                 :             :         /* Analyze last 128 bits only.  */
    2425                 :   191456578 :         size = (size - 1) & 0x7f;
    2426                 :             : 
    2427                 :   191456578 :         if (size < 32)
    2428                 :             :           {
    2429                 :    84259847 :             classes[0] = X86_64_INTEGERSI_CLASS;
    2430                 :    84259847 :             return 1;
    2431                 :             :           }
    2432                 :   107196731 :         else if (size < 64)
    2433                 :             :           {
    2434                 :    98311972 :             classes[0] = X86_64_INTEGER_CLASS;
    2435                 :    98311972 :             return 1;
    2436                 :             :           }
    2437                 :     8884759 :         else if (size < 64+32)
    2438                 :             :           {
    2439                 :     3777553 :             classes[0] = X86_64_INTEGER_CLASS;
    2440                 :     3777553 :             classes[1] = X86_64_INTEGERSI_CLASS;
    2441                 :     3777553 :             return 2;
    2442                 :             :           }
    2443                 :     5107206 :         else if (size < 64+64)
    2444                 :             :           {
    2445                 :     5107206 :             classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2446                 :     5107206 :             return 2;
    2447                 :             :           }
    2448                 :             :         else
    2449                 :             :           gcc_unreachable ();
    2450                 :             :       }
    2451                 :     1704611 :     case E_CDImode:
    2452                 :     1704611 :     case E_TImode:
    2453                 :     1704611 :       classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2454                 :     1704611 :       return 2;
    2455                 :           0 :     case E_COImode:
    2456                 :           0 :     case E_OImode:
    2457                 :             :       /* OImode shouldn't be used directly.  */
    2458                 :           0 :       gcc_unreachable ();
    2459                 :             :     case E_CTImode:
    2460                 :             :       return 0;
    2461                 :      840026 :     case E_HFmode:
    2462                 :      840026 :     case E_BFmode:
    2463                 :      840026 :       if (!(bit_offset % 64))
    2464                 :      837766 :         classes[0] = X86_64_SSEHF_CLASS;
    2465                 :             :       else
    2466                 :        2260 :         classes[0] = X86_64_SSE_CLASS;
    2467                 :             :       return 1;
    2468                 :     9589460 :     case E_SFmode:
    2469                 :     9589460 :       if (!(bit_offset % 64))
    2470                 :     9536476 :         classes[0] = X86_64_SSESF_CLASS;
    2471                 :             :       else
    2472                 :       52984 :         classes[0] = X86_64_SSE_CLASS;
    2473                 :             :       return 1;
    2474                 :     4118041 :     case E_DFmode:
    2475                 :     4118041 :       classes[0] = X86_64_SSEDF_CLASS;
    2476                 :     4118041 :       return 1;
    2477                 :     6866625 :     case E_XFmode:
    2478                 :     6866625 :       classes[0] = X86_64_X87_CLASS;
    2479                 :     6866625 :       classes[1] = X86_64_X87UP_CLASS;
    2480                 :     6866625 :       return 2;
    2481                 :     1221278 :     case E_TFmode:
    2482                 :     1221278 :       classes[0] = X86_64_SSE_CLASS;
    2483                 :     1221278 :       classes[1] = X86_64_SSEUP_CLASS;
    2484                 :     1221278 :       return 2;
    2485                 :      112414 :     case E_HCmode:
    2486                 :      112414 :     case E_BCmode:
    2487                 :      112414 :       classes[0] = X86_64_SSE_CLASS;
    2488                 :      112414 :       if (!(bit_offset % 64))
    2489                 :             :         return 1;
    2490                 :             :       else
    2491                 :             :         {
    2492                 :          98 :           classes[1] = X86_64_SSEHF_CLASS;
    2493                 :          98 :           return 2;
    2494                 :             :         }
    2495                 :      692501 :     case E_SCmode:
    2496                 :      692501 :       classes[0] = X86_64_SSE_CLASS;
    2497                 :      692501 :       if (!(bit_offset % 64))
    2498                 :             :         return 1;
    2499                 :             :       else
    2500                 :             :         {
    2501                 :        1047 :           static bool warned;
    2502                 :             : 
    2503                 :        1047 :           if (!warned && warn_psabi)
    2504                 :             :             {
    2505                 :           1 :               warned = true;
    2506                 :           1 :               inform (input_location,
    2507                 :             :                       "the ABI of passing structure with %<complex float%>"
    2508                 :             :                       " member has changed in GCC 4.4");
    2509                 :             :             }
    2510                 :        1047 :           classes[1] = X86_64_SSESF_CLASS;
    2511                 :        1047 :           return 2;
    2512                 :             :         }
    2513                 :      706315 :     case E_DCmode:
    2514                 :      706315 :       classes[0] = X86_64_SSEDF_CLASS;
    2515                 :      706315 :       classes[1] = X86_64_SSEDF_CLASS;
    2516                 :      706315 :       return 2;
    2517                 :      539289 :     case E_XCmode:
    2518                 :      539289 :       classes[0] = X86_64_COMPLEX_X87_CLASS;
    2519                 :      539289 :       return 1;
    2520                 :             :     case E_TCmode:
    2521                 :             :       /* This modes is larger than 16 bytes.  */
    2522                 :             :       return 0;
    2523                 :    21053338 :     case E_V8SFmode:
    2524                 :    21053338 :     case E_V8SImode:
    2525                 :    21053338 :     case E_V32QImode:
    2526                 :    21053338 :     case E_V16HFmode:
    2527                 :    21053338 :     case E_V16BFmode:
    2528                 :    21053338 :     case E_V16HImode:
    2529                 :    21053338 :     case E_V4DFmode:
    2530                 :    21053338 :     case E_V4DImode:
    2531                 :    21053338 :       classes[0] = X86_64_SSE_CLASS;
    2532                 :    21053338 :       classes[1] = X86_64_SSEUP_CLASS;
    2533                 :    21053338 :       classes[2] = X86_64_SSEUP_CLASS;
    2534                 :    21053338 :       classes[3] = X86_64_SSEUP_CLASS;
    2535                 :    21053338 :       return 4;
    2536                 :    23120785 :     case E_V8DFmode:
    2537                 :    23120785 :     case E_V16SFmode:
    2538                 :    23120785 :     case E_V32HFmode:
    2539                 :    23120785 :     case E_V32BFmode:
    2540                 :    23120785 :     case E_V8DImode:
    2541                 :    23120785 :     case E_V16SImode:
    2542                 :    23120785 :     case E_V32HImode:
    2543                 :    23120785 :     case E_V64QImode:
    2544                 :    23120785 :       classes[0] = X86_64_SSE_CLASS;
    2545                 :    23120785 :       classes[1] = X86_64_SSEUP_CLASS;
    2546                 :    23120785 :       classes[2] = X86_64_SSEUP_CLASS;
    2547                 :    23120785 :       classes[3] = X86_64_SSEUP_CLASS;
    2548                 :    23120785 :       classes[4] = X86_64_SSEUP_CLASS;
    2549                 :    23120785 :       classes[5] = X86_64_SSEUP_CLASS;
    2550                 :    23120785 :       classes[6] = X86_64_SSEUP_CLASS;
    2551                 :    23120785 :       classes[7] = X86_64_SSEUP_CLASS;
    2552                 :    23120785 :       return 8;
    2553                 :    32241734 :     case E_V4SFmode:
    2554                 :    32241734 :     case E_V4SImode:
    2555                 :    32241734 :     case E_V16QImode:
    2556                 :    32241734 :     case E_V8HImode:
    2557                 :    32241734 :     case E_V8HFmode:
    2558                 :    32241734 :     case E_V8BFmode:
    2559                 :    32241734 :     case E_V2DFmode:
    2560                 :    32241734 :     case E_V2DImode:
    2561                 :    32241734 :       classes[0] = X86_64_SSE_CLASS;
    2562                 :    32241734 :       classes[1] = X86_64_SSEUP_CLASS;
    2563                 :    32241734 :       return 2;
    2564                 :     3165433 :     case E_V1TImode:
    2565                 :     3165433 :     case E_V1DImode:
    2566                 :     3165433 :     case E_V2SFmode:
    2567                 :     3165433 :     case E_V2SImode:
    2568                 :     3165433 :     case E_V4HImode:
    2569                 :     3165433 :     case E_V4HFmode:
    2570                 :     3165433 :     case E_V4BFmode:
    2571                 :     3165433 :     case E_V2HFmode:
    2572                 :     3165433 :     case E_V2BFmode:
    2573                 :     3165433 :     case E_V8QImode:
    2574                 :     3165433 :       classes[0] = X86_64_SSE_CLASS;
    2575                 :     3165433 :       return 1;
    2576                 :             :     case E_BLKmode:
    2577                 :             :     case E_VOIDmode:
    2578                 :             :       return 0;
    2579                 :       32293 :     default:
    2580                 :       32293 :       gcc_assert (VECTOR_MODE_P (mode));
    2581                 :             : 
    2582                 :       32293 :       if (bytes > 16)
    2583                 :             :         return 0;
    2584                 :             : 
    2585                 :       38684 :       gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
    2586                 :             : 
    2587                 :       38684 :       if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
    2588                 :       18902 :         classes[0] = X86_64_INTEGERSI_CLASS;
    2589                 :             :       else
    2590                 :         440 :         classes[0] = X86_64_INTEGER_CLASS;
    2591                 :       19342 :       classes[1] = X86_64_INTEGER_CLASS;
    2592                 :       19342 :       return 1 + (bytes > 8);
    2593                 :             :     }
    2594                 :             : }
    2595                 :             : 
    2596                 :             : /* Wrapper around classify_argument with the extra zero_width_bitfields
    2597                 :             :    argument, to diagnose GCC 12.1 ABI differences for C.  */
    2598                 :             : 
    2599                 :             : static int
    2600                 :   288454285 : classify_argument (machine_mode mode, const_tree type,
    2601                 :             :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
    2602                 :             : {
    2603                 :   288454285 :   int zero_width_bitfields = 0;
    2604                 :   288454285 :   static bool warned = false;
    2605                 :   288454285 :   int n = classify_argument (mode, type, classes, bit_offset,
    2606                 :             :                              zero_width_bitfields);
    2607                 :   288454285 :   if (!zero_width_bitfields || warned || !warn_psabi)
    2608                 :             :     return n;
    2609                 :         534 :   enum x86_64_reg_class alt_classes[MAX_CLASSES];
    2610                 :         534 :   zero_width_bitfields = 2;
    2611                 :         534 :   if (classify_argument (mode, type, alt_classes, bit_offset,
    2612                 :             :                          zero_width_bitfields) != n)
    2613                 :           0 :     zero_width_bitfields = 3;
    2614                 :             :   else
    2615                 :        1286 :     for (int i = 0; i < n; i++)
    2616                 :         760 :       if (classes[i] != alt_classes[i])
    2617                 :             :         {
    2618                 :           8 :           zero_width_bitfields = 3;
    2619                 :           8 :           break;
    2620                 :             :         }
    2621                 :         534 :   if (zero_width_bitfields == 3)
    2622                 :             :     {
    2623                 :           8 :       warned = true;
    2624                 :           8 :       const char *url
    2625                 :             :         = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
    2626                 :             : 
    2627                 :           8 :       inform (input_location,
    2628                 :             :               "the ABI of passing C structures with zero-width bit-fields"
    2629                 :             :               " has changed in GCC %{12.1%}", url);
    2630                 :             :     }
    2631                 :             :   return n;
    2632                 :             : }
    2633                 :             : 
    2634                 :             : /* Examine the argument and return set number of register required in each
    2635                 :             :    class.  Return true iff parameter should be passed in memory.  */
    2636                 :             : 
    2637                 :             : static bool
    2638                 :   193966998 : examine_argument (machine_mode mode, const_tree type, int in_return,
    2639                 :             :                   int *int_nregs, int *sse_nregs)
    2640                 :             : {
    2641                 :   193966998 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2642                 :   193966998 :   int n = classify_argument (mode, type, regclass, 0);
    2643                 :             : 
    2644                 :   193966998 :   *int_nregs = 0;
    2645                 :   193966998 :   *sse_nregs = 0;
    2646                 :             : 
    2647                 :   193966998 :   if (!n)
    2648                 :             :     return true;
    2649                 :   563195722 :   for (n--; n >= 0; n--)
    2650                 :   373138058 :     switch (regclass[n])
    2651                 :             :       {
    2652                 :   126774360 :       case X86_64_INTEGER_CLASS:
    2653                 :   126774360 :       case X86_64_INTEGERSI_CLASS:
    2654                 :   126774360 :         (*int_nregs)++;
    2655                 :   126774360 :         break;
    2656                 :    64919068 :       case X86_64_SSE_CLASS:
    2657                 :    64919068 :       case X86_64_SSEHF_CLASS:
    2658                 :    64919068 :       case X86_64_SSESF_CLASS:
    2659                 :    64919068 :       case X86_64_SSEDF_CLASS:
    2660                 :    64919068 :         (*sse_nregs)++;
    2661                 :    64919068 :         break;
    2662                 :             :       case X86_64_NO_CLASS:
    2663                 :             :       case X86_64_SSEUP_CLASS:
    2664                 :             :         break;
    2665                 :     9255802 :       case X86_64_X87_CLASS:
    2666                 :     9255802 :       case X86_64_X87UP_CLASS:
    2667                 :     9255802 :       case X86_64_COMPLEX_X87_CLASS:
    2668                 :     9255802 :         if (!in_return)
    2669                 :             :           return true;
    2670                 :             :         break;
    2671                 :           0 :       case X86_64_MEMORY_CLASS:
    2672                 :           0 :         gcc_unreachable ();
    2673                 :             :       }
    2674                 :             : 
    2675                 :             :   return false;
    2676                 :             : }
    2677                 :             : 
    2678                 :             : /* Construct container for the argument used by GCC interface.  See
    2679                 :             :    FUNCTION_ARG for the detailed description.  */
    2680                 :             : 
    2681                 :             : static rtx
    2682                 :    94487287 : construct_container (machine_mode mode, machine_mode orig_mode,
    2683                 :             :                      const_tree type, int in_return, int nintregs, int nsseregs,
    2684                 :             :                      const int *intreg, int sse_regno)
    2685                 :             : {
    2686                 :             :   /* The following variables hold the static issued_error state.  */
    2687                 :    94487287 :   static bool issued_sse_arg_error;
    2688                 :    94487287 :   static bool issued_sse_ret_error;
    2689                 :    94487287 :   static bool issued_x87_ret_error;
    2690                 :             : 
    2691                 :    94487287 :   machine_mode tmpmode;
    2692                 :    94487287 :   int bytes
    2693                 :   188400612 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2694                 :    94487287 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2695                 :    94487287 :   int n;
    2696                 :    94487287 :   int i;
    2697                 :    94487287 :   int nexps = 0;
    2698                 :    94487287 :   int needed_sseregs, needed_intregs;
    2699                 :    94487287 :   rtx exp[MAX_CLASSES];
    2700                 :    94487287 :   rtx ret;
    2701                 :             : 
    2702                 :    94487287 :   n = classify_argument (mode, type, regclass, 0);
    2703                 :    94487287 :   if (!n)
    2704                 :             :     return NULL;
    2705                 :    94048344 :   if (examine_argument (mode, type, in_return, &needed_intregs,
    2706                 :             :                         &needed_sseregs))
    2707                 :             :     return NULL;
    2708                 :    94000611 :   if (needed_intregs > nintregs || needed_sseregs > nsseregs)
    2709                 :             :     return NULL;
    2710                 :             : 
    2711                 :             :   /* We allowed the user to turn off SSE for kernel mode.  Don't crash if
    2712                 :             :      some less clueful developer tries to use floating-point anyway.  */
    2713                 :    92929806 :   if (needed_sseregs
    2714                 :    32029975 :       && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
    2715                 :             :     {
    2716                 :             :       /* Return early if we shouldn't raise an error for invalid
    2717                 :             :          calls.  */
    2718                 :          68 :       if (cfun != NULL && cfun->machine->silent_p)
    2719                 :             :         return NULL;
    2720                 :          43 :       if (in_return)
    2721                 :             :         {
    2722                 :          37 :           if (!issued_sse_ret_error)
    2723                 :             :             {
    2724                 :          18 :               if (VALID_SSE2_TYPE_MODE (mode))
    2725                 :           6 :                 error ("SSE register return with SSE2 disabled");
    2726                 :             :               else
    2727                 :          12 :                 error ("SSE register return with SSE disabled");
    2728                 :          18 :               issued_sse_ret_error = true;
    2729                 :             :             }
    2730                 :             :         }
    2731                 :           6 :       else if (!issued_sse_arg_error)
    2732                 :             :         {
    2733                 :           6 :           if (VALID_SSE2_TYPE_MODE (mode))
    2734                 :           0 :             error ("SSE register argument with SSE2 disabled");
    2735                 :             :           else
    2736                 :           6 :             error ("SSE register argument with SSE disabled");
    2737                 :           6 :           issued_sse_arg_error = true;
    2738                 :             :         }
    2739                 :          43 :       return NULL;
    2740                 :             :     }
    2741                 :             : 
    2742                 :             :   /* Likewise, error if the ABI requires us to return values in the
    2743                 :             :      x87 registers and the user specified -mno-80387.  */
    2744                 :    92929738 :   if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
    2745                 :     1364687 :     for (i = 0; i < n; i++)
    2746                 :      716873 :       if (regclass[i] == X86_64_X87_CLASS
    2747                 :             :           || regclass[i] == X86_64_X87UP_CLASS
    2748                 :      716873 :           || regclass[i] == X86_64_COMPLEX_X87_CLASS)
    2749                 :             :         {
    2750                 :             :           /* Return early if we shouldn't raise an error for invalid
    2751                 :             :              calls.  */
    2752                 :          15 :           if (cfun != NULL && cfun->machine->silent_p)
    2753                 :             :             return NULL;
    2754                 :          12 :           if (!issued_x87_ret_error)
    2755                 :             :             {
    2756                 :           7 :               error ("x87 register return with x87 disabled");
    2757                 :           7 :               issued_x87_ret_error = true;
    2758                 :             :             }
    2759                 :          12 :           return NULL;
    2760                 :             :         }
    2761                 :             : 
    2762                 :             :   /* First construct simple cases.  Avoid SCmode, since we want to use
    2763                 :             :      single register to pass this type.  */
    2764                 :    92929723 :   if (n == 1 && mode != SCmode && mode != HCmode)
    2765                 :    61369472 :     switch (regclass[0])
    2766                 :             :       {
    2767                 :    55471765 :       case X86_64_INTEGER_CLASS:
    2768                 :    55471765 :       case X86_64_INTEGERSI_CLASS:
    2769                 :    55471765 :         return gen_rtx_REG (mode, intreg[0]);
    2770                 :     5706777 :       case X86_64_SSE_CLASS:
    2771                 :     5706777 :       case X86_64_SSEHF_CLASS:
    2772                 :     5706777 :       case X86_64_SSESF_CLASS:
    2773                 :     5706777 :       case X86_64_SSEDF_CLASS:
    2774                 :     5706777 :         if (mode != BLKmode)
    2775                 :    11412746 :           return gen_reg_or_parallel (mode, orig_mode,
    2776                 :    11412746 :                                       GET_SSE_REGNO (sse_regno));
    2777                 :             :         break;
    2778                 :      166671 :       case X86_64_X87_CLASS:
    2779                 :      166671 :       case X86_64_COMPLEX_X87_CLASS:
    2780                 :      166671 :         return gen_rtx_REG (mode, FIRST_STACK_REG);
    2781                 :             :       case X86_64_NO_CLASS:
    2782                 :             :         /* Zero sized array, struct or class.  */
    2783                 :             :         return NULL;
    2784                 :           0 :       default:
    2785                 :           0 :         gcc_unreachable ();
    2786                 :             :       }
    2787                 :    31560655 :   if (n == 2
    2788                 :    16636220 :       && regclass[0] == X86_64_SSE_CLASS
    2789                 :    11149465 :       && regclass[1] == X86_64_SSEUP_CLASS
    2790                 :    11144699 :       && mode != BLKmode)
    2791                 :    22289398 :     return gen_reg_or_parallel (mode, orig_mode,
    2792                 :    22289398 :                                 GET_SSE_REGNO (sse_regno));
    2793                 :    20415956 :   if (n == 4
    2794                 :     7002794 :       && regclass[0] == X86_64_SSE_CLASS
    2795                 :     7002794 :       && regclass[1] == X86_64_SSEUP_CLASS
    2796                 :     7002794 :       && regclass[2] == X86_64_SSEUP_CLASS
    2797                 :     7002794 :       && regclass[3] == X86_64_SSEUP_CLASS
    2798                 :     7002794 :       && mode != BLKmode)
    2799                 :    14002210 :     return gen_reg_or_parallel (mode, orig_mode,
    2800                 :    14002210 :                                 GET_SSE_REGNO (sse_regno));
    2801                 :    13414851 :   if (n == 8
    2802                 :     7677854 :       && regclass[0] == X86_64_SSE_CLASS
    2803                 :     7677854 :       && regclass[1] == X86_64_SSEUP_CLASS
    2804                 :     7677854 :       && regclass[2] == X86_64_SSEUP_CLASS
    2805                 :     7677854 :       && regclass[3] == X86_64_SSEUP_CLASS
    2806                 :     7677854 :       && regclass[4] == X86_64_SSEUP_CLASS
    2807                 :     7677854 :       && regclass[5] == X86_64_SSEUP_CLASS
    2808                 :     7677854 :       && regclass[6] == X86_64_SSEUP_CLASS
    2809                 :     7677854 :       && regclass[7] == X86_64_SSEUP_CLASS
    2810                 :     7677854 :       && mode != BLKmode)
    2811                 :    15351452 :     return gen_reg_or_parallel (mode, orig_mode,
    2812                 :    15351452 :                                 GET_SSE_REGNO (sse_regno));
    2813                 :     5739125 :   if (n == 2
    2814                 :     5491521 :       && regclass[0] == X86_64_X87_CLASS
    2815                 :     2211261 :       && regclass[1] == X86_64_X87UP_CLASS)
    2816                 :     2211261 :     return gen_rtx_REG (XFmode, FIRST_STACK_REG);
    2817                 :             : 
    2818                 :     3527864 :   if (n == 2
    2819                 :     3280260 :       && regclass[0] == X86_64_INTEGER_CLASS
    2820                 :     2915033 :       && regclass[1] == X86_64_INTEGER_CLASS
    2821                 :     2906944 :       && (mode == CDImode || mode == TImode || mode == BLKmode)
    2822                 :     2906944 :       && intreg[0] + 1 == intreg[1])
    2823                 :             :     {
    2824                 :     2621316 :       if (mode == BLKmode)
    2825                 :             :         {
    2826                 :             :           /* Use TImode for BLKmode values in 2 integer registers.  */
    2827                 :      494080 :           exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
    2828                 :      247040 :                                       gen_rtx_REG (TImode, intreg[0]),
    2829                 :             :                                       GEN_INT (0));
    2830                 :      247040 :           ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
    2831                 :      247040 :           XVECEXP (ret, 0, 0) = exp[0];
    2832                 :      247040 :           return ret;
    2833                 :             :         }
    2834                 :             :       else
    2835                 :     2374276 :         return gen_rtx_REG (mode, intreg[0]);
    2836                 :             :     }
    2837                 :             : 
    2838                 :             :   /* Otherwise figure out the entries of the PARALLEL.  */
    2839                 :     2472040 :   for (i = 0; i < n; i++)
    2840                 :             :     {
    2841                 :     1565492 :       int pos;
    2842                 :             : 
    2843                 :     1565492 :       switch (regclass[i])
    2844                 :             :         {
    2845                 :             :           case X86_64_NO_CLASS:
    2846                 :             :             break;
    2847                 :      812251 :           case X86_64_INTEGER_CLASS:
    2848                 :      812251 :           case X86_64_INTEGERSI_CLASS:
    2849                 :             :             /* Merge TImodes on aligned occasions here too.  */
    2850                 :      812251 :             if (i * 8 + 8 > bytes)
    2851                 :             :               {
    2852                 :        3153 :                 unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
    2853                 :        5947 :                 if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
    2854                 :             :                   /* We've requested 24 bytes we
    2855                 :             :                      don't have mode for.  Use DImode.  */
    2856                 :      694091 :                   tmpmode = DImode;
    2857                 :             :               }
    2858                 :      809098 :             else if (regclass[i] == X86_64_INTEGERSI_CLASS)
    2859                 :             :               tmpmode = SImode;
    2860                 :             :             else
    2861                 :      694091 :               tmpmode = DImode;
    2862                 :     1624502 :             exp [nexps++]
    2863                 :      812251 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2864                 :      812251 :                                    gen_rtx_REG (tmpmode, *intreg),
    2865                 :      812251 :                                    GEN_INT (i*8));
    2866                 :      812251 :             intreg++;
    2867                 :      812251 :             break;
    2868                 :         584 :           case X86_64_SSEHF_CLASS:
    2869                 :         584 :             tmpmode = (mode == BFmode ? BFmode : HFmode);
    2870                 :        1168 :             exp [nexps++]
    2871                 :        1168 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2872                 :             :                                    gen_rtx_REG (tmpmode,
    2873                 :         584 :                                                 GET_SSE_REGNO (sse_regno)),
    2874                 :         584 :                                    GEN_INT (i*8));
    2875                 :         584 :             sse_regno++;
    2876                 :         584 :             break;
    2877                 :        2828 :           case X86_64_SSESF_CLASS:
    2878                 :        5656 :             exp [nexps++]
    2879                 :        5656 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2880                 :             :                                    gen_rtx_REG (SFmode,
    2881                 :        2828 :                                                 GET_SSE_REGNO (sse_regno)),
    2882                 :        2828 :                                    GEN_INT (i*8));
    2883                 :        2828 :             sse_regno++;
    2884                 :        2828 :             break;
    2885                 :      485020 :           case X86_64_SSEDF_CLASS:
    2886                 :      970040 :             exp [nexps++]
    2887                 :      970040 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2888                 :             :                                    gen_rtx_REG (DFmode,
    2889                 :      485020 :                                                 GET_SSE_REGNO (sse_regno)),
    2890                 :      485020 :                                    GEN_INT (i*8));
    2891                 :      485020 :             sse_regno++;
    2892                 :      485020 :             break;
    2893                 :      256746 :           case X86_64_SSE_CLASS:
    2894                 :      256746 :             pos = i;
    2895                 :      256746 :             switch (n)
    2896                 :             :               {
    2897                 :             :               case 1:
    2898                 :             :                 tmpmode = DImode;
    2899                 :             :                 break;
    2900                 :        9356 :               case 2:
    2901                 :        9356 :                 if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
    2902                 :             :                   {
    2903                 :           0 :                     tmpmode = TImode;
    2904                 :           0 :                     i++;
    2905                 :             :                   }
    2906                 :             :                 else
    2907                 :             :                   tmpmode = DImode;
    2908                 :             :                 break;
    2909                 :        1689 :               case 4:
    2910                 :        1689 :                 gcc_assert (i == 0
    2911                 :             :                             && regclass[1] == X86_64_SSEUP_CLASS
    2912                 :             :                             && regclass[2] == X86_64_SSEUP_CLASS
    2913                 :             :                             && regclass[3] == X86_64_SSEUP_CLASS);
    2914                 :             :                 tmpmode = OImode;
    2915                 :             :                 i += 3;
    2916                 :             :                 break;
    2917                 :        2128 :               case 8:
    2918                 :        2128 :                 gcc_assert (i == 0
    2919                 :             :                             && regclass[1] == X86_64_SSEUP_CLASS
    2920                 :             :                             && regclass[2] == X86_64_SSEUP_CLASS
    2921                 :             :                             && regclass[3] == X86_64_SSEUP_CLASS
    2922                 :             :                             && regclass[4] == X86_64_SSEUP_CLASS
    2923                 :             :                             && regclass[5] == X86_64_SSEUP_CLASS
    2924                 :             :                             && regclass[6] == X86_64_SSEUP_CLASS
    2925                 :             :                             && regclass[7] == X86_64_SSEUP_CLASS);
    2926                 :             :                 tmpmode = XImode;
    2927                 :             :                 i += 7;
    2928                 :             :                 break;
    2929                 :           0 :               default:
    2930                 :           0 :                 gcc_unreachable ();
    2931                 :             :               }
    2932                 :      513492 :             exp [nexps++]
    2933                 :      513492 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2934                 :             :                                    gen_rtx_REG (tmpmode,
    2935                 :      256746 :                                                 GET_SSE_REGNO (sse_regno)),
    2936                 :      256746 :                                    GEN_INT (pos*8));
    2937                 :      256746 :             sse_regno++;
    2938                 :      256746 :             break;
    2939                 :           0 :           default:
    2940                 :           0 :             gcc_unreachable ();
    2941                 :             :         }
    2942                 :             :     }
    2943                 :             : 
    2944                 :             :   /* Empty aligned struct, union or class.  */
    2945                 :      906548 :   if (nexps == 0)
    2946                 :             :     return NULL;
    2947                 :             : 
    2948                 :      906286 :   ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
    2949                 :     2463715 :   for (i = 0; i < nexps; i++)
    2950                 :     1557429 :     XVECEXP (ret, 0, i) = exp [i];
    2951                 :             :   return ret;
    2952                 :             : }
    2953                 :             : 
    2954                 :             : /* Update the data in CUM to advance over an argument of mode MODE
    2955                 :             :    and data type TYPE.  (TYPE is null for libcalls where that information
    2956                 :             :    may not be available.)
    2957                 :             : 
    2958                 :             :    Return a number of integer regsiters advanced over.  */
    2959                 :             : 
    2960                 :             : static int
    2961                 :     2091413 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    2962                 :             :                          const_tree type, HOST_WIDE_INT bytes,
    2963                 :             :                          HOST_WIDE_INT words)
    2964                 :             : {
    2965                 :     2091413 :   int res = 0;
    2966                 :     2091413 :   bool error_p = false;
    2967                 :             : 
    2968                 :     2091413 :   if (TARGET_IAMCU)
    2969                 :             :     {
    2970                 :             :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    2971                 :             :          bytes in registers.  */
    2972                 :           0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    2973                 :           0 :         goto pass_in_reg;
    2974                 :             :       return res;
    2975                 :             :     }
    2976                 :             : 
    2977                 :     2091413 :   switch (mode)
    2978                 :             :     {
    2979                 :             :     default:
    2980                 :             :       break;
    2981                 :             : 
    2982                 :       93580 :     case E_BLKmode:
    2983                 :       93580 :       if (bytes < 0)
    2984                 :             :         break;
    2985                 :             :       /* FALLTHRU */
    2986                 :             : 
    2987                 :     2054738 :     case E_DImode:
    2988                 :     2054738 :     case E_SImode:
    2989                 :     2054738 :     case E_HImode:
    2990                 :     2054738 :     case E_QImode:
    2991                 :       93580 : pass_in_reg:
    2992                 :     2054738 :       cum->words += words;
    2993                 :     2054738 :       cum->nregs -= words;
    2994                 :     2054738 :       cum->regno += words;
    2995                 :     2054738 :       if (cum->nregs >= 0)
    2996                 :       45603 :         res = words;
    2997                 :     2054738 :       if (cum->nregs <= 0)
    2998                 :             :         {
    2999                 :     2022063 :           cum->nregs = 0;
    3000                 :     2022063 :           cfun->machine->arg_reg_available = false;
    3001                 :     2022063 :           cum->regno = 0;
    3002                 :             :         }
    3003                 :             :       break;
    3004                 :             : 
    3005                 :           0 :     case E_OImode:
    3006                 :             :       /* OImode shouldn't be used directly.  */
    3007                 :           0 :       gcc_unreachable ();
    3008                 :             : 
    3009                 :        4687 :     case E_DFmode:
    3010                 :        4687 :       if (cum->float_in_sse == -1)
    3011                 :           0 :         error_p = true;
    3012                 :        4687 :       if (cum->float_in_sse < 2)
    3013                 :             :         break;
    3014                 :             :       /* FALLTHRU */
    3015                 :        1351 :     case E_SFmode:
    3016                 :        1351 :       if (cum->float_in_sse == -1)
    3017                 :           0 :         error_p = true;
    3018                 :        1351 :       if (cum->float_in_sse < 1)
    3019                 :             :         break;
    3020                 :             :       /* FALLTHRU */
    3021                 :             : 
    3022                 :          52 :     case E_V16HFmode:
    3023                 :          52 :     case E_V16BFmode:
    3024                 :          52 :     case E_V8SFmode:
    3025                 :          52 :     case E_V8SImode:
    3026                 :          52 :     case E_V64QImode:
    3027                 :          52 :     case E_V32HImode:
    3028                 :          52 :     case E_V16SImode:
    3029                 :          52 :     case E_V8DImode:
    3030                 :          52 :     case E_V32HFmode:
    3031                 :          52 :     case E_V32BFmode:
    3032                 :          52 :     case E_V16SFmode:
    3033                 :          52 :     case E_V8DFmode:
    3034                 :          52 :     case E_V32QImode:
    3035                 :          52 :     case E_V16HImode:
    3036                 :          52 :     case E_V4DFmode:
    3037                 :          52 :     case E_V4DImode:
    3038                 :          52 :     case E_TImode:
    3039                 :          52 :     case E_V16QImode:
    3040                 :          52 :     case E_V8HImode:
    3041                 :          52 :     case E_V4SImode:
    3042                 :          52 :     case E_V2DImode:
    3043                 :          52 :     case E_V8HFmode:
    3044                 :          52 :     case E_V8BFmode:
    3045                 :          52 :     case E_V4SFmode:
    3046                 :          52 :     case E_V2DFmode:
    3047                 :          52 :       if (!type || !AGGREGATE_TYPE_P (type))
    3048                 :             :         {
    3049                 :          52 :           cum->sse_words += words;
    3050                 :          52 :           cum->sse_nregs -= 1;
    3051                 :          52 :           cum->sse_regno += 1;
    3052                 :          52 :           if (cum->sse_nregs <= 0)
    3053                 :             :             {
    3054                 :           4 :               cum->sse_nregs = 0;
    3055                 :           4 :               cum->sse_regno = 0;
    3056                 :             :             }
    3057                 :             :         }
    3058                 :             :       break;
    3059                 :             : 
    3060                 :          12 :     case E_V8QImode:
    3061                 :          12 :     case E_V4HImode:
    3062                 :          12 :     case E_V4HFmode:
    3063                 :          12 :     case E_V4BFmode:
    3064                 :          12 :     case E_V2SImode:
    3065                 :          12 :     case E_V2SFmode:
    3066                 :          12 :     case E_V1TImode:
    3067                 :          12 :     case E_V1DImode:
    3068                 :          12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3069                 :             :         {
    3070                 :          12 :           cum->mmx_words += words;
    3071                 :          12 :           cum->mmx_nregs -= 1;
    3072                 :          12 :           cum->mmx_regno += 1;
    3073                 :          12 :           if (cum->mmx_nregs <= 0)
    3074                 :             :             {
    3075                 :           0 :               cum->mmx_nregs = 0;
    3076                 :           0 :               cum->mmx_regno = 0;
    3077                 :             :             }
    3078                 :             :         }
    3079                 :             :       break;
    3080                 :             :     }
    3081                 :     2028153 :   if (error_p)
    3082                 :             :     {
    3083                 :           0 :       cum->float_in_sse = 0;
    3084                 :           0 :       error ("calling %qD with SSE calling convention without "
    3085                 :             :              "SSE/SSE2 enabled", cum->decl);
    3086                 :           0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3087                 :             :              "attribute used to function called");
    3088                 :             :     }
    3089                 :             : 
    3090                 :             :   return res;
    3091                 :             : }
    3092                 :             : 
    3093                 :             : static int
    3094                 :    17481097 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3095                 :             :                          const_tree type, HOST_WIDE_INT words, bool named)
    3096                 :             : {
    3097                 :    17481097 :   int int_nregs, sse_nregs;
    3098                 :             : 
    3099                 :             :   /* Unnamed 512 and 256bit vector mode parameters are passed on stack.  */
    3100                 :    17481097 :   if (!named && (VALID_AVX512F_REG_MODE (mode)
    3101                 :             :                  || VALID_AVX256_REG_MODE (mode)))
    3102                 :             :     return 0;
    3103                 :             : 
    3104                 :    17480733 :   if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
    3105                 :    17480733 :       && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
    3106                 :             :     {
    3107                 :    15256817 :       cum->nregs -= int_nregs;
    3108                 :    15256817 :       cum->sse_nregs -= sse_nregs;
    3109                 :    15256817 :       cum->regno += int_nregs;
    3110                 :    15256817 :       cum->sse_regno += sse_nregs;
    3111                 :    15256817 :       return int_nregs;
    3112                 :             :     }
    3113                 :             :   else
    3114                 :             :     {
    3115                 :     2223916 :       int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
    3116                 :     2223916 :       cum->words = ROUND_UP (cum->words, align);
    3117                 :     2223916 :       cum->words += words;
    3118                 :     2223916 :       return 0;
    3119                 :             :     }
    3120                 :             : }
    3121                 :             : 
    3122                 :             : static int
    3123                 :      447221 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
    3124                 :             :                             HOST_WIDE_INT words)
    3125                 :             : {
    3126                 :             :   /* Otherwise, this should be passed indirect.  */
    3127                 :      447221 :   gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
    3128                 :             : 
    3129                 :      447221 :   cum->words += words;
    3130                 :      447221 :   if (cum->nregs > 0)
    3131                 :             :     {
    3132                 :      289536 :       cum->nregs -= 1;
    3133                 :      289536 :       cum->regno += 1;
    3134                 :      289536 :       return 1;
    3135                 :             :     }
    3136                 :             :   return 0;
    3137                 :             : }
    3138                 :             : 
    3139                 :             : /* Update the data in CUM to advance over argument ARG.  */
    3140                 :             : 
    3141                 :             : static void
    3142                 :    20020085 : ix86_function_arg_advance (cumulative_args_t cum_v,
    3143                 :             :                            const function_arg_info &arg)
    3144                 :             : {
    3145                 :    20020085 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3146                 :    20020085 :   machine_mode mode = arg.mode;
    3147                 :    20020085 :   HOST_WIDE_INT bytes, words;
    3148                 :    20020085 :   int nregs;
    3149                 :             : 
    3150                 :             :   /* The argument of interrupt handler is a special case and is
    3151                 :             :      handled in ix86_function_arg.  */
    3152                 :    20020085 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3153                 :             :     return;
    3154                 :             : 
    3155                 :    20019731 :   bytes = arg.promoted_size_in_bytes ();
    3156                 :    20019731 :   words = CEIL (bytes, UNITS_PER_WORD);
    3157                 :             : 
    3158                 :    20019731 :   if (arg.type)
    3159                 :    19742164 :     mode = type_natural_mode (arg.type, NULL, false);
    3160                 :             : 
    3161                 :    20019731 :   if (TARGET_64BIT)
    3162                 :             :     {
    3163                 :    17928318 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3164                 :             : 
    3165                 :    17928318 :       if (call_abi == MS_ABI)
    3166                 :      447221 :         nregs = function_arg_advance_ms_64 (cum, bytes, words);
    3167                 :             :       else
    3168                 :    17481097 :         nregs = function_arg_advance_64 (cum, mode, arg.type, words,
    3169                 :    17481097 :                                          arg.named);
    3170                 :             :     }
    3171                 :             :   else
    3172                 :     2091413 :     nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
    3173                 :             : 
    3174                 :    20019731 :   if (!nregs)
    3175                 :             :     {
    3176                 :             :       /* Track if there are outgoing arguments on stack.  */
    3177                 :     5549423 :       if (cum->caller)
    3178                 :     2668929 :         cfun->machine->outgoing_args_on_stack = true;
    3179                 :             :     }
    3180                 :             : }
    3181                 :             : 
    3182                 :             : /* Define where to put the arguments to a function.
    3183                 :             :    Value is zero to push the argument on the stack,
    3184                 :             :    or a hard register in which to store the argument.
    3185                 :             : 
    3186                 :             :    MODE is the argument's machine mode.
    3187                 :             :    TYPE is the data type of the argument (as a tree).
    3188                 :             :     This is null for libcalls where that information may
    3189                 :             :     not be available.
    3190                 :             :    CUM is a variable of type CUMULATIVE_ARGS which gives info about
    3191                 :             :     the preceding args and about the function being called.
    3192                 :             :    NAMED is nonzero if this argument is a named parameter
    3193                 :             :     (otherwise it is an extra parameter matching an ellipsis).  */
    3194                 :             : 
    3195                 :             : static rtx
    3196                 :     2518952 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3197                 :             :                  machine_mode orig_mode, const_tree type,
    3198                 :             :                  HOST_WIDE_INT bytes, HOST_WIDE_INT words)
    3199                 :             : {
    3200                 :     2518952 :   bool error_p = false;
    3201                 :             : 
    3202                 :             :   /* Avoid the AL settings for the Unix64 ABI.  */
    3203                 :     2518952 :   if (mode == VOIDmode)
    3204                 :      734400 :     return constm1_rtx;
    3205                 :             : 
    3206                 :     1784552 :   if (TARGET_IAMCU)
    3207                 :             :     {
    3208                 :             :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3209                 :             :          bytes in registers.  */
    3210                 :           0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3211                 :           0 :         goto pass_in_reg;
    3212                 :             :       return NULL_RTX;
    3213                 :             :     }
    3214                 :             : 
    3215                 :     1784552 :   switch (mode)
    3216                 :             :     {
    3217                 :             :     default:
    3218                 :             :       break;
    3219                 :             : 
    3220                 :       77611 :     case E_BLKmode:
    3221                 :       77611 :       if (bytes < 0)
    3222                 :             :         break;
    3223                 :             :       /* FALLTHRU */
    3224                 :     1751126 :     case E_DImode:
    3225                 :     1751126 :     case E_SImode:
    3226                 :     1751126 :     case E_HImode:
    3227                 :     1751126 :     case E_QImode:
    3228                 :       77611 : pass_in_reg:
    3229                 :     1751126 :       if (words <= cum->nregs)
    3230                 :             :         {
    3231                 :       43771 :           int regno = cum->regno;
    3232                 :             : 
    3233                 :             :           /* Fastcall allocates the first two DWORD (SImode) or
    3234                 :             :             smaller arguments to ECX and EDX if it isn't an
    3235                 :             :             aggregate type .  */
    3236                 :       43771 :           if (cum->fastcall)
    3237                 :             :             {
    3238                 :           6 :               if (mode == BLKmode
    3239                 :           6 :                   || mode == DImode
    3240                 :           6 :                   || (type && AGGREGATE_TYPE_P (type)))
    3241                 :             :                 break;
    3242                 :             : 
    3243                 :             :               /* ECX not EAX is the first allocated register.  */
    3244                 :           6 :               if (regno == AX_REG)
    3245                 :       43771 :                 regno = CX_REG;
    3246                 :             :             }
    3247                 :       43771 :           return gen_rtx_REG (mode, regno);
    3248                 :             :         }
    3249                 :             :       break;
    3250                 :             : 
    3251                 :        3305 :     case E_DFmode:
    3252                 :        3305 :       if (cum->float_in_sse == -1)
    3253                 :           0 :         error_p = true;
    3254                 :        3305 :       if (cum->float_in_sse < 2)
    3255                 :             :         break;
    3256                 :             :       /* FALLTHRU */
    3257                 :         963 :     case E_SFmode:
    3258                 :         963 :       if (cum->float_in_sse == -1)
    3259                 :           0 :         error_p = true;
    3260                 :         963 :       if (cum->float_in_sse < 1)
    3261                 :             :         break;
    3262                 :             :       /* FALLTHRU */
    3263                 :          12 :     case E_TImode:
    3264                 :             :       /* In 32bit, we pass TImode in xmm registers.  */
    3265                 :          12 :     case E_V16QImode:
    3266                 :          12 :     case E_V8HImode:
    3267                 :          12 :     case E_V4SImode:
    3268                 :          12 :     case E_V2DImode:
    3269                 :          12 :     case E_V8HFmode:
    3270                 :          12 :     case E_V8BFmode:
    3271                 :          12 :     case E_V4SFmode:
    3272                 :          12 :     case E_V2DFmode:
    3273                 :          12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3274                 :             :         {
    3275                 :          12 :           if (cum->sse_nregs)
    3276                 :          12 :             return gen_reg_or_parallel (mode, orig_mode,
    3277                 :          12 :                                         cum->sse_regno + FIRST_SSE_REG);
    3278                 :             :         }
    3279                 :             :       break;
    3280                 :             : 
    3281                 :           0 :     case E_OImode:
    3282                 :           0 :     case E_XImode:
    3283                 :             :       /* OImode and XImode shouldn't be used directly.  */
    3284                 :           0 :       gcc_unreachable ();
    3285                 :             : 
    3286                 :           9 :     case E_V64QImode:
    3287                 :           9 :     case E_V32HImode:
    3288                 :           9 :     case E_V16SImode:
    3289                 :           9 :     case E_V8DImode:
    3290                 :           9 :     case E_V32HFmode:
    3291                 :           9 :     case E_V32BFmode:
    3292                 :           9 :     case E_V16SFmode:
    3293                 :           9 :     case E_V8DFmode:
    3294                 :           9 :     case E_V16HFmode:
    3295                 :           9 :     case E_V16BFmode:
    3296                 :           9 :     case E_V8SFmode:
    3297                 :           9 :     case E_V8SImode:
    3298                 :           9 :     case E_V32QImode:
    3299                 :           9 :     case E_V16HImode:
    3300                 :           9 :     case E_V4DFmode:
    3301                 :           9 :     case E_V4DImode:
    3302                 :           9 :       if (!type || !AGGREGATE_TYPE_P (type))
    3303                 :             :         {
    3304                 :           9 :           if (cum->sse_nregs)
    3305                 :           9 :             return gen_reg_or_parallel (mode, orig_mode,
    3306                 :           9 :                                         cum->sse_regno + FIRST_SSE_REG);
    3307                 :             :         }
    3308                 :             :       break;
    3309                 :             : 
    3310                 :           6 :     case E_V8QImode:
    3311                 :           6 :     case E_V4HImode:
    3312                 :           6 :     case E_V4HFmode:
    3313                 :           6 :     case E_V4BFmode:
    3314                 :           6 :     case E_V2SImode:
    3315                 :           6 :     case E_V2SFmode:
    3316                 :           6 :     case E_V1TImode:
    3317                 :           6 :     case E_V1DImode:
    3318                 :           6 :       if (!type || !AGGREGATE_TYPE_P (type))
    3319                 :             :         {
    3320                 :           6 :           if (cum->mmx_nregs)
    3321                 :           6 :             return gen_reg_or_parallel (mode, orig_mode,
    3322                 :           6 :                                         cum->mmx_regno + FIRST_MMX_REG);
    3323                 :             :         }
    3324                 :             :       break;
    3325                 :             :     }
    3326                 :        4268 :   if (error_p)
    3327                 :             :     {
    3328                 :           0 :       cum->float_in_sse = 0;
    3329                 :           0 :       error ("calling %qD with SSE calling convention without "
    3330                 :             :              "SSE/SSE2 enabled", cum->decl);
    3331                 :           0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3332                 :             :              "attribute used to function called");
    3333                 :             :     }
    3334                 :             : 
    3335                 :             :   return NULL_RTX;
    3336                 :             : }
    3337                 :             : 
    3338                 :             : static rtx
    3339                 :    17390904 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3340                 :             :                  machine_mode orig_mode, const_tree type, bool named)
    3341                 :             : {
    3342                 :             :   /* Handle a hidden AL argument containing number of registers
    3343                 :             :      for varargs x86-64 functions.  */
    3344                 :    17390904 :   if (mode == VOIDmode)
    3345                 :     4818116 :     return GEN_INT (cum->maybe_vaarg
    3346                 :             :                     ? (cum->sse_nregs < 0
    3347                 :             :                        ? X86_64_SSE_REGPARM_MAX
    3348                 :             :                        : cum->sse_regno)
    3349                 :             :                     : -1);
    3350                 :             : 
    3351                 :    12572788 :   switch (mode)
    3352                 :             :     {
    3353                 :             :     default:
    3354                 :             :       break;
    3355                 :             : 
    3356                 :       77499 :     case E_V16HFmode:
    3357                 :       77499 :     case E_V16BFmode:
    3358                 :       77499 :     case E_V8SFmode:
    3359                 :       77499 :     case E_V8SImode:
    3360                 :       77499 :     case E_V32QImode:
    3361                 :       77499 :     case E_V16HImode:
    3362                 :       77499 :     case E_V4DFmode:
    3363                 :       77499 :     case E_V4DImode:
    3364                 :       77499 :     case E_V32HFmode:
    3365                 :       77499 :     case E_V32BFmode:
    3366                 :       77499 :     case E_V16SFmode:
    3367                 :       77499 :     case E_V16SImode:
    3368                 :       77499 :     case E_V64QImode:
    3369                 :       77499 :     case E_V32HImode:
    3370                 :       77499 :     case E_V8DFmode:
    3371                 :       77499 :     case E_V8DImode:
    3372                 :             :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    3373                 :       77499 :       if (!named)
    3374                 :             :         return NULL;
    3375                 :             :       break;
    3376                 :             :     }
    3377                 :             : 
    3378                 :    12572424 :   return construct_container (mode, orig_mode, type, 0, cum->nregs,
    3379                 :    12572424 :                               cum->sse_nregs,
    3380                 :    12572424 :                               &x86_64_int_parameter_registers [cum->regno],
    3381                 :    12572424 :                               cum->sse_regno);
    3382                 :             : }
    3383                 :             : 
    3384                 :             : static rtx
    3385                 :      296636 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3386                 :             :                     machine_mode orig_mode, bool named, const_tree type,
    3387                 :             :                     HOST_WIDE_INT bytes)
    3388                 :             : {
    3389                 :      296636 :   unsigned int regno;
    3390                 :             : 
    3391                 :             :   /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
    3392                 :             :      We use value of -2 to specify that current function call is MSABI.  */
    3393                 :      296636 :   if (mode == VOIDmode)
    3394                 :       36357 :     return GEN_INT (-2);
    3395                 :             : 
    3396                 :             :   /* If we've run out of registers, it goes on the stack.  */
    3397                 :      260279 :   if (cum->nregs == 0)
    3398                 :             :     return NULL_RTX;
    3399                 :             : 
    3400                 :      176473 :   regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
    3401                 :             : 
    3402                 :             :   /* Only floating point modes are passed in anything but integer regs.  */
    3403                 :      176473 :   if (TARGET_SSE && (mode == SFmode || mode == DFmode))
    3404                 :             :     {
    3405                 :       38334 :       if (named)
    3406                 :             :         {
    3407                 :       38334 :           if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
    3408                 :       37337 :             regno = cum->regno + FIRST_SSE_REG;
    3409                 :             :         }
    3410                 :             :       else
    3411                 :             :         {
    3412                 :           0 :           rtx t1, t2;
    3413                 :             : 
    3414                 :             :           /* Unnamed floating parameters are passed in both the
    3415                 :             :              SSE and integer registers.  */
    3416                 :           0 :           t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
    3417                 :           0 :           t2 = gen_rtx_REG (mode, regno);
    3418                 :           0 :           t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
    3419                 :           0 :           t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
    3420                 :           0 :           return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
    3421                 :             :         }
    3422                 :             :     }
    3423                 :             :   /* Handle aggregated types passed in register.  */
    3424                 :      176473 :   if (orig_mode == BLKmode)
    3425                 :             :     {
    3426                 :           0 :       if (bytes > 0 && bytes <= 8)
    3427                 :           0 :         mode = (bytes > 4 ? DImode : SImode);
    3428                 :           0 :       if (mode == BLKmode)
    3429                 :           0 :         mode = DImode;
    3430                 :             :     }
    3431                 :             : 
    3432                 :      176473 :   return gen_reg_or_parallel (mode, orig_mode, regno);
    3433                 :             : }
    3434                 :             : 
    3435                 :             : /* Return where to put the arguments to a function.
    3436                 :             :    Return zero to push the argument on the stack, or a hard register in which to store the argument.
    3437                 :             : 
    3438                 :             :    ARG describes the argument while CUM gives information about the
    3439                 :             :    preceding args and about the function being called.  */
    3440                 :             : 
    3441                 :             : static rtx
    3442                 :    20206673 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    3443                 :             : {
    3444                 :    20206673 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3445                 :    20206673 :   machine_mode mode = arg.mode;
    3446                 :    20206673 :   HOST_WIDE_INT bytes, words;
    3447                 :    20206673 :   rtx reg;
    3448                 :             : 
    3449                 :    20206673 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3450                 :             :     {
    3451                 :         181 :       gcc_assert (arg.type != NULL_TREE);
    3452                 :         181 :       if (POINTER_TYPE_P (arg.type))
    3453                 :             :         {
    3454                 :             :           /* This is the pointer argument.  */
    3455                 :         118 :           gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
    3456                 :             :           /* It is at -WORD(AP) in the current frame in interrupt and
    3457                 :             :              exception handlers.  */
    3458                 :         118 :           reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
    3459                 :             :         }
    3460                 :             :       else
    3461                 :             :         {
    3462                 :          63 :           gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
    3463                 :             :                       && TREE_CODE (arg.type) == INTEGER_TYPE
    3464                 :             :                       && TYPE_MODE (arg.type) == word_mode);
    3465                 :             :           /* The error code is the word-mode integer argument at
    3466                 :             :              -2 * WORD(AP) in the current frame of the exception
    3467                 :             :              handler.  */
    3468                 :          63 :           reg = gen_rtx_MEM (word_mode,
    3469                 :          63 :                              plus_constant (Pmode,
    3470                 :             :                                             arg_pointer_rtx,
    3471                 :          63 :                                             -2 * UNITS_PER_WORD));
    3472                 :             :         }
    3473                 :         181 :       return reg;
    3474                 :             :     }
    3475                 :             : 
    3476                 :    20206492 :   bytes = arg.promoted_size_in_bytes ();
    3477                 :    20206492 :   words = CEIL (bytes, UNITS_PER_WORD);
    3478                 :             : 
    3479                 :             :   /* To simplify the code below, represent vector types with a vector mode
    3480                 :             :      even if MMX/SSE are not active.  */
    3481                 :    20206492 :   if (arg.type && VECTOR_TYPE_P (arg.type))
    3482                 :      150470 :     mode = type_natural_mode (arg.type, cum, false);
    3483                 :             : 
    3484                 :    20206492 :   if (TARGET_64BIT)
    3485                 :             :     {
    3486                 :    17687540 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3487                 :             : 
    3488                 :    17687540 :       if (call_abi == MS_ABI)
    3489                 :      296636 :         reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
    3490                 :      296636 :                                   arg.type, bytes);
    3491                 :             :       else
    3492                 :    17390904 :         reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
    3493                 :             :     }
    3494                 :             :   else
    3495                 :     2518952 :     reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
    3496                 :             : 
    3497                 :             :   /* Track if there are outgoing arguments on stack.  */
    3498                 :    20206492 :   if (reg == NULL_RTX && cum->caller)
    3499                 :     2145587 :     cfun->machine->outgoing_args_on_stack = true;
    3500                 :             : 
    3501                 :             :   return reg;
    3502                 :             : }
    3503                 :             : 
    3504                 :             : /* A C expression that indicates when an argument must be passed by
    3505                 :             :    reference.  If nonzero for an argument, a copy of that argument is
    3506                 :             :    made in memory and a pointer to the argument is passed instead of
    3507                 :             :    the argument itself.  The pointer is passed in whatever way is
    3508                 :             :    appropriate for passing a pointer to that type.  */
    3509                 :             : 
    3510                 :             : static bool
    3511                 :    19980382 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
    3512                 :             : {
    3513                 :    19980382 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3514                 :             : 
    3515                 :    19980382 :   if (TARGET_64BIT)
    3516                 :             :     {
    3517                 :    17899250 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3518                 :             : 
    3519                 :             :       /* See Windows x64 Software Convention.  */
    3520                 :    17899250 :       if (call_abi == MS_ABI)
    3521                 :             :         {
    3522                 :      441622 :           HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
    3523                 :             : 
    3524                 :      441622 :           if (tree type = arg.type)
    3525                 :             :             {
    3526                 :             :               /* Arrays are passed by reference.  */
    3527                 :      441622 :               if (TREE_CODE (type) == ARRAY_TYPE)
    3528                 :             :                 return true;
    3529                 :             : 
    3530                 :      441622 :               if (RECORD_OR_UNION_TYPE_P (type))
    3531                 :             :                 {
    3532                 :             :                   /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
    3533                 :             :                      are passed by reference.  */
    3534                 :       15036 :                   msize = int_size_in_bytes (type);
    3535                 :             :                 }
    3536                 :             :             }
    3537                 :             : 
    3538                 :             :           /* __m128 is passed by reference.  */
    3539                 :      873293 :           return msize != 1 && msize != 2 && msize != 4 && msize != 8;
    3540                 :             :         }
    3541                 :    17457628 :       else if (arg.type && int_size_in_bytes (arg.type) == -1)
    3542                 :             :         return true;
    3543                 :             :     }
    3544                 :             : 
    3545                 :             :   return false;
    3546                 :             : }
    3547                 :             : 
    3548                 :             : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3549                 :             :    passing ABI.  XXX: This function is obsolete and is only used for
    3550                 :             :    checking psABI compatibility with previous versions of GCC.  */
    3551                 :             : 
    3552                 :             : static bool
    3553                 :     1931842 : ix86_compat_aligned_value_p (const_tree type)
    3554                 :             : {
    3555                 :     1931842 :   machine_mode mode = TYPE_MODE (type);
    3556                 :     1931842 :   if (((TARGET_SSE && SSE_REG_MODE_P (mode))
    3557                 :     1931800 :        || mode == TDmode
    3558                 :     1931800 :        || mode == TFmode
    3559                 :             :        || mode == TCmode)
    3560                 :     1932054 :       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
    3561                 :             :     return true;
    3562                 :     1931630 :   if (TYPE_ALIGN (type) < 128)
    3563                 :             :     return false;
    3564                 :             : 
    3565                 :           0 :   if (AGGREGATE_TYPE_P (type))
    3566                 :             :     {
    3567                 :             :       /* Walk the aggregates recursively.  */
    3568                 :           0 :       switch (TREE_CODE (type))
    3569                 :             :         {
    3570                 :           0 :         case RECORD_TYPE:
    3571                 :           0 :         case UNION_TYPE:
    3572                 :           0 :         case QUAL_UNION_TYPE:
    3573                 :           0 :           {
    3574                 :           0 :             tree field;
    3575                 :             : 
    3576                 :             :             /* Walk all the structure fields.  */
    3577                 :           0 :             for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    3578                 :             :               {
    3579                 :           0 :                 if (TREE_CODE (field) == FIELD_DECL
    3580                 :           0 :                     && ix86_compat_aligned_value_p (TREE_TYPE (field)))
    3581                 :             :                   return true;
    3582                 :             :               }
    3583                 :             :             break;
    3584                 :             :           }
    3585                 :             : 
    3586                 :           0 :         case ARRAY_TYPE:
    3587                 :             :           /* Just for use if some languages passes arrays by value.  */
    3588                 :           0 :           if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
    3589                 :             :             return true;
    3590                 :             :           break;
    3591                 :             : 
    3592                 :             :         default:
    3593                 :             :           gcc_unreachable ();
    3594                 :             :         }
    3595                 :             :     }
    3596                 :             :   return false;
    3597                 :             : }
    3598                 :             : 
    3599                 :             : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
    3600                 :             :    XXX: This function is obsolete and is only used for checking psABI
    3601                 :             :    compatibility with previous versions of GCC.  */
    3602                 :             : 
    3603                 :             : static unsigned int
    3604                 :     5239190 : ix86_compat_function_arg_boundary (machine_mode mode,
    3605                 :             :                                    const_tree type, unsigned int align)
    3606                 :             : {
    3607                 :             :   /* In 32bit, only _Decimal128 and __float128 are aligned to their
    3608                 :             :      natural boundaries.  */
    3609                 :     5239190 :   if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
    3610                 :             :     {
    3611                 :             :       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
    3612                 :             :          make an exception for SSE modes since these require 128bit
    3613                 :             :          alignment.
    3614                 :             : 
    3615                 :             :          The handling here differs from field_alignment.  ICC aligns MMX
    3616                 :             :          arguments to 4 byte boundaries, while structure fields are aligned
    3617                 :             :          to 8 byte boundaries.  */
    3618                 :     1943795 :       if (!type)
    3619                 :             :         {
    3620                 :       11953 :           if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
    3621                 :     1943583 :             align = PARM_BOUNDARY;
    3622                 :             :         }
    3623                 :             :       else
    3624                 :             :         {
    3625                 :     1931842 :           if (!ix86_compat_aligned_value_p (type))
    3626                 :     1931630 :             align = PARM_BOUNDARY;
    3627                 :             :         }
    3628                 :             :     }
    3629                 :    10124370 :   if (align > BIGGEST_ALIGNMENT)
    3630                 :          76 :     align = BIGGEST_ALIGNMENT;
    3631                 :     5239190 :   return align;
    3632                 :             : }
    3633                 :             : 
    3634                 :             : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3635                 :             :    passing ABI.  */
    3636                 :             : 
    3637                 :             : static bool
    3638                 :     1934494 : ix86_contains_aligned_value_p (const_tree type)
    3639                 :             : {
    3640                 :     1934494 :   machine_mode mode = TYPE_MODE (type);
    3641                 :             : 
    3642                 :     1934494 :   if (mode == XFmode || mode == XCmode)
    3643                 :             :     return false;
    3644                 :             : 
    3645                 :     1932402 :   if (TYPE_ALIGN (type) < 128)
    3646                 :             :     return false;
    3647                 :             : 
    3648                 :        2864 :   if (AGGREGATE_TYPE_P (type))
    3649                 :             :     {
    3650                 :             :       /* Walk the aggregates recursively.  */
    3651                 :           0 :       switch (TREE_CODE (type))
    3652                 :             :         {
    3653                 :           0 :         case RECORD_TYPE:
    3654                 :           0 :         case UNION_TYPE:
    3655                 :           0 :         case QUAL_UNION_TYPE:
    3656                 :           0 :           {
    3657                 :           0 :             tree field;
    3658                 :             : 
    3659                 :             :             /* Walk all the structure fields.  */
    3660                 :           0 :             for (field = TYPE_FIELDS (type);
    3661                 :           0 :                  field;
    3662                 :           0 :                  field = DECL_CHAIN (field))
    3663                 :             :               {
    3664                 :           0 :                 if (TREE_CODE (field) == FIELD_DECL
    3665                 :           0 :                     && ix86_contains_aligned_value_p (TREE_TYPE (field)))
    3666                 :             :                   return true;
    3667                 :             :               }
    3668                 :             :             break;
    3669                 :             :           }
    3670                 :             : 
    3671                 :           0 :         case ARRAY_TYPE:
    3672                 :             :           /* Just for use if some languages passes arrays by value.  */
    3673                 :           0 :           if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
    3674                 :             :             return true;
    3675                 :             :           break;
    3676                 :             : 
    3677                 :             :         default:
    3678                 :             :           gcc_unreachable ();
    3679                 :             :         }
    3680                 :             :     }
    3681                 :             :   else
    3682                 :        2864 :     return TYPE_ALIGN (type) >= 128;
    3683                 :             : 
    3684                 :             :   return false;
    3685                 :             : }
    3686                 :             : 
    3687                 :             : /* Gives the alignment boundary, in bits, of an argument with the
    3688                 :             :    specified mode and type.  */
    3689                 :             : 
    3690                 :             : static unsigned int
    3691                 :    10528190 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
    3692                 :             : {
    3693                 :    10528190 :   unsigned int align;
    3694                 :    10528190 :   if (type)
    3695                 :             :     {
    3696                 :             :       /* Since the main variant type is used for call, we convert it to
    3697                 :             :          the main variant type.  */
    3698                 :    10488376 :       type = TYPE_MAIN_VARIANT (type);
    3699                 :    10488376 :       align = TYPE_ALIGN (type);
    3700                 :    10488376 :       if (TYPE_EMPTY_P (type))
    3701                 :       21199 :         return PARM_BOUNDARY;
    3702                 :             :     }
    3703                 :             :   else
    3704                 :       39814 :     align = GET_MODE_ALIGNMENT (mode);
    3705                 :    12501728 :   if (align < PARM_BOUNDARY)
    3706                 :    10528190 :     align = PARM_BOUNDARY;
    3707                 :             :   else
    3708                 :             :     {
    3709                 :     6494774 :       static bool warned;
    3710                 :     6494774 :       unsigned int saved_align = align;
    3711                 :             : 
    3712                 :     6494774 :       if (!TARGET_64BIT)
    3713                 :             :         {
    3714                 :             :           /* i386 ABI defines XFmode arguments to be 4 byte aligned.  */
    3715                 :     1970305 :           if (!type)
    3716                 :             :             {
    3717                 :       35811 :               if (mode == XFmode || mode == XCmode)
    3718                 :             :                 align = PARM_BOUNDARY;
    3719                 :             :             }
    3720                 :     1934494 :           else if (!ix86_contains_aligned_value_p (type))
    3721                 :             :             align = PARM_BOUNDARY;
    3722                 :             : 
    3723                 :       38669 :           if (align < 128)
    3724                 :     1943583 :             align = PARM_BOUNDARY;
    3725                 :             :         }
    3726                 :             : 
    3727                 :     6494774 :       if (warn_psabi
    3728                 :     5241838 :           && !warned
    3729                 :    11733964 :           && align != ix86_compat_function_arg_boundary (mode, type,
    3730                 :             :                                                          saved_align))
    3731                 :             :         {
    3732                 :          76 :           warned = true;
    3733                 :          76 :           inform (input_location,
    3734                 :             :                   "the ABI for passing parameters with %d-byte"
    3735                 :             :                   " alignment has changed in GCC 4.6",
    3736                 :             :                   align / BITS_PER_UNIT);
    3737                 :             :         }
    3738                 :             :     }
    3739                 :             : 
    3740                 :             :   return align;
    3741                 :             : }
    3742                 :             : 
    3743                 :             : /* Return true if N is a possible register number of function value.  */
    3744                 :             : 
    3745                 :             : static bool
    3746                 :     4376002 : ix86_function_value_regno_p (const unsigned int regno)
    3747                 :             : {
    3748                 :     4376002 :   switch (regno)
    3749                 :             :     {
    3750                 :             :     case AX_REG:
    3751                 :             :       return true;
    3752                 :       94858 :     case DX_REG:
    3753                 :       94858 :       return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
    3754                 :       89651 :     case DI_REG:
    3755                 :       89651 :     case SI_REG:
    3756                 :       89651 :       return TARGET_64BIT && ix86_cfun_abi () != MS_ABI;
    3757                 :             : 
    3758                 :             :       /* Complex values are returned in %st(0)/%st(1) pair.  */
    3759                 :       21446 :     case ST0_REG:
    3760                 :       21446 :     case ST1_REG:
    3761                 :             :       /* TODO: The function should depend on current function ABI but
    3762                 :             :        builtins.cc would need updating then. Therefore we use the
    3763                 :             :        default ABI.  */
    3764                 :       21446 :       if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
    3765                 :             :         return false;
    3766                 :       21446 :       return TARGET_FLOAT_RETURNS_IN_80387;
    3767                 :             : 
    3768                 :             :       /* Complex values are returned in %xmm0/%xmm1 pair.  */
    3769                 :     1259704 :     case XMM0_REG:
    3770                 :     1259704 :     case XMM1_REG:
    3771                 :     1259704 :       return TARGET_SSE;
    3772                 :             : 
    3773                 :        9652 :     case MM0_REG:
    3774                 :        9652 :       if (TARGET_MACHO || TARGET_64BIT)
    3775                 :             :         return false;
    3776                 :        4399 :       return TARGET_MMX;
    3777                 :             :     }
    3778                 :             : 
    3779                 :             :   return false;
    3780                 :             : }
    3781                 :             : 
    3782                 :             : /* Check whether the register REGNO should be zeroed on X86.
    3783                 :             :    When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
    3784                 :             :    together, no need to zero it again.
    3785                 :             :    When NEED_ZERO_MMX is true, MMX registers should be cleared.  */
    3786                 :             : 
    3787                 :             : static bool
    3788                 :        1514 : zero_call_used_regno_p (const unsigned int regno,
    3789                 :             :                         bool all_sse_zeroed,
    3790                 :             :                         bool need_zero_mmx)
    3791                 :             : {
    3792                 :         883 :   return GENERAL_REGNO_P (regno)
    3793                 :         883 :          || (!all_sse_zeroed && SSE_REGNO_P (regno))
    3794                 :         431 :          || MASK_REGNO_P (regno)
    3795                 :        1937 :          || (need_zero_mmx && MMX_REGNO_P (regno));
    3796                 :             : }
    3797                 :             : 
    3798                 :             : /* Return the machine_mode that is used to zero register REGNO.  */
    3799                 :             : 
    3800                 :             : static machine_mode
    3801                 :        1091 : zero_call_used_regno_mode (const unsigned int regno)
    3802                 :             : {
    3803                 :             :   /* NB: We only need to zero the lower 32 bits for integer registers
    3804                 :             :      and the lower 128 bits for vector registers since destination are
    3805                 :             :      zero-extended to the full register width.  */
    3806                 :        1091 :   if (GENERAL_REGNO_P (regno))
    3807                 :             :     return SImode;
    3808                 :             :   else if (SSE_REGNO_P (regno))
    3809                 :         452 :     return V4SFmode;
    3810                 :             :   else if (MASK_REGNO_P (regno))
    3811                 :             :     return HImode;
    3812                 :             :   else if (MMX_REGNO_P (regno))
    3813                 :           0 :     return V2SImode;
    3814                 :             :   else
    3815                 :           0 :     gcc_unreachable ();
    3816                 :             : }
    3817                 :             : 
    3818                 :             : /* Generate a rtx to zero all vector registers together if possible,
    3819                 :             :    otherwise, return NULL.  */
    3820                 :             : 
    3821                 :             : static rtx
    3822                 :         156 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
    3823                 :             : {
    3824                 :         156 :   if (!TARGET_AVX)
    3825                 :             :     return NULL;
    3826                 :             : 
    3827                 :         279 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3828                 :         276 :     if ((LEGACY_SSE_REGNO_P (regno)
    3829                 :         252 :          || (TARGET_64BIT
    3830                 :         252 :              && (REX_SSE_REGNO_P (regno)
    3831                 :         228 :                  || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
    3832                 :         316 :         && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3833                 :             :       return NULL;
    3834                 :             : 
    3835                 :           3 :   return gen_avx_vzeroall ();
    3836                 :             : }
    3837                 :             : 
    3838                 :             : /* Generate insns to zero all st registers together.
    3839                 :             :    Return true when zeroing instructions are generated.
    3840                 :             :    Assume the number of st registers that are zeroed is num_of_st,
    3841                 :             :    we will emit the following sequence to zero them together:
    3842                 :             :                   fldz;         \
    3843                 :             :                   fldz;         \
    3844                 :             :                   ...
    3845                 :             :                   fldz;         \
    3846                 :             :                   fstp %%st(0); \
    3847                 :             :                   fstp %%st(0); \
    3848                 :             :                   ...
    3849                 :             :                   fstp %%st(0);
    3850                 :             :    i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
    3851                 :             :    mark stack slots empty.
    3852                 :             : 
    3853                 :             :    How to compute the num_of_st:
    3854                 :             :    There is no direct mapping from stack registers to hard register
    3855                 :             :    numbers.  If one stack register needs to be cleared, we don't know
    3856                 :             :    where in the stack the value remains.  So, if any stack register
    3857                 :             :    needs to be cleared, the whole stack should be cleared.  However,
    3858                 :             :    x87 stack registers that hold the return value should be excluded.
    3859                 :             :    x87 returns in the top (two for complex values) register, so
    3860                 :             :    num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
    3861                 :             :    return the value of num_of_st.  */
    3862                 :             : 
    3863                 :             : 
    3864                 :             : static int
    3865                 :         156 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
    3866                 :             : {
    3867                 :             : 
    3868                 :             :   /* If the FPU is disabled, no need to zero all st registers.  */
    3869                 :         156 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
    3870                 :             :     return 0;
    3871                 :             : 
    3872                 :       12486 :   unsigned int num_of_st = 0;
    3873                 :       12486 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3874                 :       12354 :     if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
    3875                 :       12354 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3876                 :             :       {
    3877                 :             :         num_of_st++;
    3878                 :             :         break;
    3879                 :             :       }
    3880                 :             : 
    3881                 :         155 :   if (num_of_st == 0)
    3882                 :             :     return 0;
    3883                 :             : 
    3884                 :          23 :   bool return_with_x87 = false;
    3885                 :          46 :   return_with_x87 = (crtl->return_rtx
    3886                 :          23 :                      && (STACK_REG_P (crtl->return_rtx)));
    3887                 :             : 
    3888                 :          23 :   bool complex_return = false;
    3889                 :          46 :   complex_return = (crtl->return_rtx
    3890                 :          23 :                     && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
    3891                 :             : 
    3892                 :          23 :   if (return_with_x87)
    3893                 :           2 :     if (complex_return)
    3894                 :             :       num_of_st = 6;
    3895                 :             :     else
    3896                 :           1 :       num_of_st = 7;
    3897                 :             :   else
    3898                 :             :     num_of_st = 8;
    3899                 :             : 
    3900                 :          23 :   rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
    3901                 :         204 :   for (unsigned int i = 0; i < num_of_st; i++)
    3902                 :         181 :     emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
    3903                 :             : 
    3904                 :         204 :   for (unsigned int i = 0; i < num_of_st; i++)
    3905                 :             :     {
    3906                 :         181 :       rtx insn;
    3907                 :         181 :       insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
    3908                 :         181 :       add_reg_note (insn, REG_DEAD, st_reg);
    3909                 :             :     }
    3910                 :          23 :   return num_of_st;
    3911                 :             : }
    3912                 :             : 
    3913                 :             : 
    3914                 :             : /* When the routine exit in MMX mode, if any ST register needs
    3915                 :             :    to be zeroed, we should clear all MMX registers except the
    3916                 :             :    RET_MMX_REGNO that holds the return value.  */
    3917                 :             : static bool
    3918                 :           0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
    3919                 :             :                        unsigned int ret_mmx_regno)
    3920                 :             : {
    3921                 :           0 :   bool need_zero_all_mm = false;
    3922                 :           0 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3923                 :           0 :     if (STACK_REGNO_P (regno)
    3924                 :           0 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3925                 :             :       {
    3926                 :             :         need_zero_all_mm = true;
    3927                 :             :         break;
    3928                 :             :       }
    3929                 :             : 
    3930                 :           0 :   if (!need_zero_all_mm)
    3931                 :             :     return false;
    3932                 :             : 
    3933                 :             :   machine_mode mode = V2SImode;
    3934                 :           0 :   for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    3935                 :           0 :     if (regno != ret_mmx_regno)
    3936                 :             :       {
    3937                 :           0 :         rtx reg = gen_rtx_REG (mode, regno);
    3938                 :           0 :         emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
    3939                 :             :       }
    3940                 :             :   return true;
    3941                 :             : }
    3942                 :             : 
    3943                 :             : /* TARGET_ZERO_CALL_USED_REGS.  */
    3944                 :             : /* Generate a sequence of instructions that zero registers specified by
    3945                 :             :    NEED_ZEROED_HARDREGS.  Return the ZEROED_HARDREGS that are actually
    3946                 :             :    zeroed.  */
    3947                 :             : static HARD_REG_SET
    3948                 :         156 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
    3949                 :             : {
    3950                 :         156 :   HARD_REG_SET zeroed_hardregs;
    3951                 :         156 :   bool all_sse_zeroed = false;
    3952                 :         156 :   int all_st_zeroed_num = 0;
    3953                 :         156 :   bool all_mm_zeroed = false;
    3954                 :             : 
    3955                 :         156 :   CLEAR_HARD_REG_SET (zeroed_hardregs);
    3956                 :             : 
    3957                 :             :   /* first, let's see whether we can zero all vector registers together.  */
    3958                 :         156 :   rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
    3959                 :         156 :   if (zero_all_vec_insn)
    3960                 :             :     {
    3961                 :           3 :       emit_insn (zero_all_vec_insn);
    3962                 :           3 :       all_sse_zeroed = true;
    3963                 :             :     }
    3964                 :             : 
    3965                 :             :   /* mm/st registers are shared registers set, we should follow the following
    3966                 :             :      rules to clear them:
    3967                 :             :                         MMX exit mode         x87 exit mode
    3968                 :             :         -------------|----------------------|---------------
    3969                 :             :         uses x87 reg | clear all MMX        | clear all x87
    3970                 :             :         uses MMX reg | clear individual MMX | clear all x87
    3971                 :             :         x87 + MMX    | clear all MMX        | clear all x87
    3972                 :             : 
    3973                 :             :      first, we should decide which mode (MMX mode or x87 mode) the function
    3974                 :             :      exit with.  */
    3975                 :             : 
    3976                 :         156 :   bool exit_with_mmx_mode = (crtl->return_rtx
    3977                 :         156 :                              && (MMX_REG_P (crtl->return_rtx)));
    3978                 :             : 
    3979                 :         156 :   if (!exit_with_mmx_mode)
    3980                 :             :     /* x87 exit mode, we should zero all st registers together.  */
    3981                 :             :     {
    3982                 :         156 :       all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
    3983                 :             : 
    3984                 :         156 :       if (all_st_zeroed_num > 0)
    3985                 :         207 :         for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
    3986                 :             :           /* x87 stack registers that hold the return value should be excluded.
    3987                 :             :              x87 returns in the top (two for complex values) register.  */
    3988                 :         184 :           if (all_st_zeroed_num == 8
    3989                 :         184 :               || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
    3990                 :             :                    || (all_st_zeroed_num == 6
    3991                 :           7 :                        && (regno == (REGNO (crtl->return_rtx) + 1)))))
    3992                 :         181 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    3993                 :             :     }
    3994                 :             :   else
    3995                 :             :     /* MMX exit mode, check whether we can zero all mm registers.  */
    3996                 :             :     {
    3997                 :           0 :       unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
    3998                 :           0 :       all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
    3999                 :             :                                              exit_mmx_regno);
    4000                 :           0 :       if (all_mm_zeroed)
    4001                 :           0 :         for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4002                 :           0 :           if (regno != exit_mmx_regno)
    4003                 :           0 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4004                 :             :     }
    4005                 :             : 
    4006                 :             :   /* Now, generate instructions to zero all the other registers.  */
    4007                 :             : 
    4008                 :       14508 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4009                 :             :     {
    4010                 :       14352 :       if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4011                 :       12838 :         continue;
    4012                 :        1937 :       if (!zero_call_used_regno_p (regno, all_sse_zeroed,
    4013                 :        1514 :                                    exit_with_mmx_mode && !all_mm_zeroed))
    4014                 :         423 :         continue;
    4015                 :             : 
    4016                 :        1091 :       SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4017                 :             : 
    4018                 :        1091 :       machine_mode mode = zero_call_used_regno_mode (regno);
    4019                 :             : 
    4020                 :        1091 :       rtx reg = gen_rtx_REG (mode, regno);
    4021                 :        1091 :       rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
    4022                 :             : 
    4023                 :        1091 :       switch (mode)
    4024                 :             :         {
    4025                 :         631 :         case E_SImode:
    4026                 :         631 :           if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
    4027                 :             :             {
    4028                 :         631 :               rtx clob = gen_rtx_CLOBBER (VOIDmode,
    4029                 :             :                                           gen_rtx_REG (CCmode,
    4030                 :             :                                                        FLAGS_REG));
    4031                 :         631 :               tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
    4032                 :             :                                                            tmp,
    4033                 :             :                                                            clob));
    4034                 :             :             }
    4035                 :             :           /* FALLTHRU.  */
    4036                 :             : 
    4037                 :        1091 :         case E_V4SFmode:
    4038                 :        1091 :         case E_HImode:
    4039                 :        1091 :         case E_V2SImode:
    4040                 :        1091 :           emit_insn (tmp);
    4041                 :        1091 :           break;
    4042                 :             : 
    4043                 :           0 :         default:
    4044                 :           0 :           gcc_unreachable ();
    4045                 :             :         }
    4046                 :             :     }
    4047                 :         156 :   return zeroed_hardregs;
    4048                 :             : }
    4049                 :             : 
    4050                 :             : /* Define how to find the value returned by a function.
    4051                 :             :    VALTYPE is the data type of the value (as a tree).
    4052                 :             :    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    4053                 :             :    otherwise, FUNC is 0.  */
    4054                 :             : 
    4055                 :             : static rtx
    4056                 :     3823142 : function_value_32 (machine_mode orig_mode, machine_mode mode,
    4057                 :             :                    const_tree fntype, const_tree fn)
    4058                 :             : {
    4059                 :     3823142 :   unsigned int regno;
    4060                 :             : 
    4061                 :             :   /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
    4062                 :             :      we normally prevent this case when mmx is not available.  However
    4063                 :             :      some ABIs may require the result to be returned like DImode.  */
    4064                 :     4061603 :   if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
    4065                 :             :     regno = FIRST_MMX_REG;
    4066                 :             : 
    4067                 :             :   /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
    4068                 :             :      we prevent this case when sse is not available.  However some ABIs
    4069                 :             :      may require the result to be returned like integer TImode.  */
    4070                 :     3813902 :   else if (mode == TImode
    4071                 :     4043123 :            || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
    4072                 :             :     regno = FIRST_SSE_REG;
    4073                 :             : 
    4074                 :             :   /* 32-byte vector modes in %ymm0.   */
    4075                 :     3846297 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
    4076                 :             :     regno = FIRST_SSE_REG;
    4077                 :             : 
    4078                 :             :   /* 64-byte vector modes in %zmm0.   */
    4079                 :     3721019 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
    4080                 :             :     regno = FIRST_SSE_REG;
    4081                 :             : 
    4082                 :             :   /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387).  */
    4083                 :     3584681 :   else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
    4084                 :             :     regno = FIRST_FLOAT_REG;
    4085                 :             :   else
    4086                 :             :     /* Most things go in %eax.  */
    4087                 :     3522786 :     regno = AX_REG;
    4088                 :             : 
    4089                 :             :   /* Return __bf16/ _Float16/_Complex _Foat16 by sse register.  */
    4090                 :     3823142 :   if (mode == HFmode || mode == BFmode)
    4091                 :             :     {
    4092                 :        1619 :       if (!TARGET_SSE2)
    4093                 :             :         {
    4094                 :           0 :           error ("SSE register return with SSE2 disabled");
    4095                 :           0 :           regno = AX_REG;
    4096                 :             :         }
    4097                 :             :       else
    4098                 :             :         regno = FIRST_SSE_REG;
    4099                 :             :     }
    4100                 :             : 
    4101                 :     3823142 :   if (mode == HCmode)
    4102                 :             :     {
    4103                 :          80 :       if (!TARGET_SSE2)
    4104                 :           0 :         error ("SSE register return with SSE2 disabled");
    4105                 :             : 
    4106                 :          80 :       rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
    4107                 :         160 :       XVECEXP (ret, 0, 0)
    4108                 :         160 :         = gen_rtx_EXPR_LIST (VOIDmode,
    4109                 :             :                              gen_rtx_REG (SImode,
    4110                 :          80 :                                           TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
    4111                 :             :                              GEN_INT (0));
    4112                 :          80 :       return ret;
    4113                 :             :     }
    4114                 :             : 
    4115                 :             :   /* Override FP return register with %xmm0 for local functions when
    4116                 :             :      SSE math is enabled or for functions with sseregparm attribute.  */
    4117                 :     3823062 :   if ((fn || fntype) && (mode == SFmode || mode == DFmode))
    4118                 :             :     {
    4119                 :       48144 :       int sse_level = ix86_function_sseregparm (fntype, fn, false);
    4120                 :       48144 :       if (sse_level == -1)
    4121                 :             :         {
    4122                 :           0 :           error ("calling %qD with SSE calling convention without "
    4123                 :             :                  "SSE/SSE2 enabled", fn);
    4124                 :           0 :           sorry ("this is a GCC bug that can be worked around by adding "
    4125                 :             :                  "attribute used to function called");
    4126                 :             :         }
    4127                 :       48144 :       else if ((sse_level >= 1 && mode == SFmode)
    4128                 :       48144 :                || (sse_level == 2 && mode == DFmode))
    4129                 :             :         regno = FIRST_SSE_REG;
    4130                 :             :     }
    4131                 :             : 
    4132                 :             :   /* OImode shouldn't be used directly.  */
    4133                 :     3823062 :   gcc_assert (mode != OImode);
    4134                 :             : 
    4135                 :     3823062 :   return gen_rtx_REG (orig_mode, regno);
    4136                 :             : }
    4137                 :             : 
    4138                 :             : static rtx
    4139                 :    81968710 : function_value_64 (machine_mode orig_mode, machine_mode mode,
    4140                 :             :                    const_tree valtype)
    4141                 :             : {
    4142                 :    81968710 :   rtx ret;
    4143                 :             : 
    4144                 :             :   /* Handle libcalls, which don't provide a type node.  */
    4145                 :    81968710 :   if (valtype == NULL)
    4146                 :             :     {
    4147                 :      105352 :       unsigned int regno;
    4148                 :             : 
    4149                 :      105352 :       switch (mode)
    4150                 :             :         {
    4151                 :             :         case E_BFmode:
    4152                 :             :         case E_HFmode:
    4153                 :             :         case E_HCmode:
    4154                 :             :         case E_SFmode:
    4155                 :             :         case E_SCmode:
    4156                 :             :         case E_DFmode:
    4157                 :             :         case E_DCmode:
    4158                 :             :         case E_TFmode:
    4159                 :             :         case E_SDmode:
    4160                 :             :         case E_DDmode:
    4161                 :             :         case E_TDmode:
    4162                 :             :           regno = FIRST_SSE_REG;
    4163                 :             :           break;
    4164                 :        1096 :         case E_XFmode:
    4165                 :        1096 :         case E_XCmode:
    4166                 :        1096 :           regno = FIRST_FLOAT_REG;
    4167                 :        1096 :           break;
    4168                 :             :         case E_TCmode:
    4169                 :             :           return NULL;
    4170                 :       57277 :         default:
    4171                 :       57277 :           regno = AX_REG;
    4172                 :             :         }
    4173                 :             : 
    4174                 :      105352 :       return gen_rtx_REG (mode, regno);
    4175                 :             :     }
    4176                 :    81863358 :   else if (POINTER_TYPE_P (valtype))
    4177                 :             :     {
    4178                 :             :       /* Pointers are always returned in word_mode.  */
    4179                 :    12895730 :       mode = word_mode;
    4180                 :             :     }
    4181                 :             : 
    4182                 :    81863358 :   ret = construct_container (mode, orig_mode, valtype, 1,
    4183                 :             :                              X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
    4184                 :             :                              x86_64_int_return_registers, 0);
    4185                 :             : 
    4186                 :             :   /* For zero sized structures, construct_container returns NULL, but we
    4187                 :             :      need to keep rest of compiler happy by returning meaningful value.  */
    4188                 :    81863358 :   if (!ret)
    4189                 :      183288 :     ret = gen_rtx_REG (orig_mode, AX_REG);
    4190                 :             : 
    4191                 :             :   return ret;
    4192                 :             : }
    4193                 :             : 
    4194                 :             : static rtx
    4195                 :           0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
    4196                 :             :                       const_tree fntype, const_tree fn, const_tree valtype)
    4197                 :             : {
    4198                 :           0 :   unsigned int regno;
    4199                 :             : 
    4200                 :             :   /* Floating point return values in %st(0)
    4201                 :             :      (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes).  */
    4202                 :           0 :   if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
    4203                 :           0 :            && (GET_MODE_SIZE (mode) > 8
    4204                 :           0 :                || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
    4205                 :             :   {
    4206                 :           0 :     regno = FIRST_FLOAT_REG;
    4207                 :           0 :     return gen_rtx_REG (orig_mode, regno);
    4208                 :             :   }
    4209                 :             :   else
    4210                 :           0 :     return function_value_32(orig_mode, mode, fntype,fn);
    4211                 :             : }
    4212                 :             : 
    4213                 :             : static rtx
    4214                 :      760940 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
    4215                 :             :                       const_tree valtype)
    4216                 :             : {
    4217                 :      760940 :   unsigned int regno = AX_REG;
    4218                 :             : 
    4219                 :      760940 :   if (TARGET_SSE)
    4220                 :             :     {
    4221                 :     1520426 :       switch (GET_MODE_SIZE (mode))
    4222                 :             :         {
    4223                 :       12531 :         case 16:
    4224                 :       12531 :           if (valtype != NULL_TREE
    4225                 :       12531 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4226                 :        6654 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4227                 :        6654 :               && !INTEGRAL_TYPE_P (valtype)
    4228                 :       19185 :               && !VECTOR_FLOAT_TYPE_P (valtype))
    4229                 :             :             break;
    4230                 :       12531 :           if ((SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
    4231                 :             :               && !COMPLEX_MODE_P (mode))
    4232                 :      760940 :             regno = FIRST_SSE_REG;
    4233                 :             :           break;
    4234                 :      728054 :         case 8:
    4235                 :      728054 :         case 4:
    4236                 :      728054 :           if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
    4237                 :             :             break;
    4238                 :      713280 :           if (mode == SFmode || mode == DFmode)
    4239                 :      760940 :             regno = FIRST_SSE_REG;
    4240                 :             :           break;
    4241                 :             :         default:
    4242                 :             :           break;
    4243                 :             :         }
    4244                 :             :     }
    4245                 :      760940 :   return gen_rtx_REG (orig_mode, regno);
    4246                 :             : }
    4247                 :             : 
    4248                 :             : static rtx
    4249                 :    86552792 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
    4250                 :             :                        machine_mode orig_mode, machine_mode mode)
    4251                 :             : {
    4252                 :    86552792 :   const_tree fn, fntype;
    4253                 :             : 
    4254                 :    86552792 :   fn = NULL_TREE;
    4255                 :    86552792 :   if (fntype_or_decl && DECL_P (fntype_or_decl))
    4256                 :     3303480 :     fn = fntype_or_decl;
    4257                 :     3303480 :   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
    4258                 :             :   
    4259                 :    86552792 :   if (ix86_function_type_abi (fntype) == MS_ABI)
    4260                 :             :     {
    4261                 :      760940 :       if (TARGET_64BIT)
    4262                 :      760940 :         return function_value_ms_64 (orig_mode, mode, valtype);
    4263                 :             :       else
    4264                 :           0 :         return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
    4265                 :             :     }
    4266                 :    85791852 :   else if (TARGET_64BIT)
    4267                 :    81968710 :     return function_value_64 (orig_mode, mode, valtype);
    4268                 :             :   else
    4269                 :     3823142 :     return function_value_32 (orig_mode, mode, fntype, fn);
    4270                 :             : }
    4271                 :             : 
    4272                 :             : static rtx
    4273                 :    86444282 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
    4274                 :             : {
    4275                 :    86444282 :   machine_mode mode, orig_mode;
    4276                 :             : 
    4277                 :    86444282 :   orig_mode = TYPE_MODE (valtype);
    4278                 :    86444282 :   mode = type_natural_mode (valtype, NULL, true);
    4279                 :    86444282 :   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
    4280                 :             : }
    4281                 :             : 
    4282                 :             : /* Pointer function arguments and return values are promoted to
    4283                 :             :    word_mode for normal functions.  */
    4284                 :             : 
    4285                 :             : static machine_mode
    4286                 :    29973743 : ix86_promote_function_mode (const_tree type, machine_mode mode,
    4287                 :             :                             int *punsignedp, const_tree fntype,
    4288                 :             :                             int for_return)
    4289                 :             : {
    4290                 :    29973743 :   if (cfun->machine->func_type == TYPE_NORMAL
    4291                 :    29972751 :       && type != NULL_TREE
    4292                 :    29940083 :       && POINTER_TYPE_P (type))
    4293                 :             :     {
    4294                 :    14720409 :       *punsignedp = POINTERS_EXTEND_UNSIGNED;
    4295                 :    14720409 :       return word_mode;
    4296                 :             :     }
    4297                 :    15253334 :   return default_promote_function_mode (type, mode, punsignedp, fntype,
    4298                 :    15253334 :                                         for_return);
    4299                 :             : }
    4300                 :             : 
    4301                 :             : /* Return true if a structure, union or array with MODE containing FIELD
    4302                 :             :    should be accessed using BLKmode.  */
    4303                 :             : 
    4304                 :             : static bool
    4305                 :   109398991 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
    4306                 :             : {
    4307                 :             :   /* Union with XFmode must be in BLKmode.  */
    4308                 :   109398991 :   return (mode == XFmode
    4309                 :   109526926 :           && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
    4310                 :      116754 :               || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
    4311                 :             : }
    4312                 :             : 
    4313                 :             : rtx
    4314                 :      108510 : ix86_libcall_value (machine_mode mode)
    4315                 :             : {
    4316                 :      108510 :   return ix86_function_value_1 (NULL, NULL, mode, mode);
    4317                 :             : }
    4318                 :             : 
    4319                 :             : /* Return true iff type is returned in memory.  */
    4320                 :             : 
    4321                 :             : static bool
    4322                 :    87509703 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
    4323                 :             : {
    4324                 :    87509703 :   const machine_mode mode = type_natural_mode (type, NULL, true);
    4325                 :    87509703 :   HOST_WIDE_INT size;
    4326                 :             : 
    4327                 :    87509703 :   if (TARGET_64BIT)
    4328                 :             :     {
    4329                 :    83107360 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    4330                 :             :         {
    4331                 :      697878 :           size = int_size_in_bytes (type);
    4332                 :             : 
    4333                 :             :           /* __m128 is returned in xmm0.  */
    4334                 :      697878 :           if ((!type || VECTOR_INTEGER_TYPE_P (type)
    4335                 :      681119 :                || INTEGRAL_TYPE_P (type)
    4336                 :      215574 :                || VECTOR_FLOAT_TYPE_P (type))
    4337                 :      496728 :               && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
    4338                 :             :               && !COMPLEX_MODE_P (mode)
    4339                 :     1194606 :               && (GET_MODE_SIZE (mode) == 16 || size == 16))
    4340                 :             :             return false;
    4341                 :             : 
    4342                 :             :           /* Otherwise, the size must be exactly in [1248]. */
    4343                 :     1337087 :           return size != 1 && size != 2 && size != 4 && size != 8;
    4344                 :             :         }
    4345                 :             :       else
    4346                 :             :         {
    4347                 :    82409482 :           int needed_intregs, needed_sseregs;
    4348                 :             : 
    4349                 :    82409482 :           return examine_argument (mode, type, 1,
    4350                 :             :                                    &needed_intregs, &needed_sseregs);
    4351                 :             :         }
    4352                 :             :     }
    4353                 :             :   else
    4354                 :             :     {
    4355                 :     4402343 :       size = int_size_in_bytes (type);
    4356                 :             : 
    4357                 :             :       /* Intel MCU psABI returns scalars and aggregates no larger than 8
    4358                 :             :          bytes in registers.  */
    4359                 :     4402343 :       if (TARGET_IAMCU)
    4360                 :           0 :         return VECTOR_MODE_P (mode) || size < 0 || size > 8;
    4361                 :             : 
    4362                 :     4402343 :       if (mode == BLKmode)
    4363                 :             :         return true;
    4364                 :             : 
    4365                 :     4402343 :       if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
    4366                 :             :         return false;
    4367                 :             : 
    4368                 :     4402343 :       if (VECTOR_MODE_P (mode) || mode == TImode)
    4369                 :             :         {
    4370                 :             :           /* User-created vectors small enough to fit in EAX.  */
    4371                 :      238433 :           if (size < 8)
    4372                 :             :             return false;
    4373                 :             : 
    4374                 :             :           /* Unless ABI prescibes otherwise,
    4375                 :             :              MMX/3dNow values are returned in MM0 if available.  */
    4376                 :             :              
    4377                 :      238433 :           if (size == 8)
    4378                 :        9232 :             return TARGET_VECT8_RETURNS || !TARGET_MMX;
    4379                 :             : 
    4380                 :             :           /* SSE values are returned in XMM0 if available.  */
    4381                 :      229201 :           if (size == 16)
    4382                 :       98403 :             return !TARGET_SSE;
    4383                 :             : 
    4384                 :             :           /* AVX values are returned in YMM0 if available.  */
    4385                 :      130798 :           if (size == 32)
    4386                 :       62630 :             return !TARGET_AVX;
    4387                 :             : 
    4388                 :             :           /* AVX512F values are returned in ZMM0 if available.  */
    4389                 :       68168 :           if (size == 64)
    4390                 :       68168 :             return !TARGET_AVX512F || !TARGET_EVEX512;
    4391                 :             :         }
    4392                 :             : 
    4393                 :     4163910 :       if (mode == XFmode)
    4394                 :             :         return false;
    4395                 :             : 
    4396                 :     4152689 :       if (size > 12)
    4397                 :             :         return true;
    4398                 :             : 
    4399                 :             :       /* OImode shouldn't be used directly.  */
    4400                 :     3205006 :       gcc_assert (mode != OImode);
    4401                 :             : 
    4402                 :             :       return false;
    4403                 :             :     }
    4404                 :             : }
    4405                 :             : 
    4406                 :             : /* Implement TARGET_PUSH_ARGUMENT.  */
    4407                 :             : 
    4408                 :             : static bool
    4409                 :     8823406 : ix86_push_argument (unsigned int npush)
    4410                 :             : {
    4411                 :             :   /* If SSE2 is available, use vector move to put large argument onto
    4412                 :             :      stack.  NB:  In 32-bit mode, use 8-byte vector move.  */
    4413                 :    11221205 :   return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
    4414                 :     8561020 :           && TARGET_PUSH_ARGS
    4415                 :    17384338 :           && !ACCUMULATE_OUTGOING_ARGS);
    4416                 :             : }
    4417                 :             : 
    4418                 :             : 
    4419                 :             : /* Create the va_list data type.  */
    4420                 :             : 
    4421                 :             : static tree
    4422                 :      273310 : ix86_build_builtin_va_list_64 (void)
    4423                 :             : {
    4424                 :      273310 :   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
    4425                 :             : 
    4426                 :      273310 :   record = lang_hooks.types.make_type (RECORD_TYPE);
    4427                 :      273310 :   type_decl = build_decl (BUILTINS_LOCATION,
    4428                 :             :                           TYPE_DECL, get_identifier ("__va_list_tag"), record);
    4429                 :             : 
    4430                 :      273310 :   f_gpr = build_decl (BUILTINS_LOCATION,
    4431                 :             :                       FIELD_DECL, get_identifier ("gp_offset"),
    4432                 :             :                       unsigned_type_node);
    4433                 :      273310 :   f_fpr = build_decl (BUILTINS_LOCATION,
    4434                 :             :                       FIELD_DECL, get_identifier ("fp_offset"),
    4435                 :             :                       unsigned_type_node);
    4436                 :      273310 :   f_ovf = build_decl (BUILTINS_LOCATION,
    4437                 :             :                       FIELD_DECL, get_identifier ("overflow_arg_area"),
    4438                 :             :                       ptr_type_node);
    4439                 :      273310 :   f_sav = build_decl (BUILTINS_LOCATION,
    4440                 :             :                       FIELD_DECL, get_identifier ("reg_save_area"),
    4441                 :             :                       ptr_type_node);
    4442                 :             : 
    4443                 :      273310 :   va_list_gpr_counter_field = f_gpr;
    4444                 :      273310 :   va_list_fpr_counter_field = f_fpr;
    4445                 :             : 
    4446                 :      273310 :   DECL_FIELD_CONTEXT (f_gpr) = record;
    4447                 :      273310 :   DECL_FIELD_CONTEXT (f_fpr) = record;
    4448                 :      273310 :   DECL_FIELD_CONTEXT (f_ovf) = record;
    4449                 :      273310 :   DECL_FIELD_CONTEXT (f_sav) = record;
    4450                 :             : 
    4451                 :      273310 :   TYPE_STUB_DECL (record) = type_decl;
    4452                 :      273310 :   TYPE_NAME (record) = type_decl;
    4453                 :      273310 :   TYPE_FIELDS (record) = f_gpr;
    4454                 :      273310 :   DECL_CHAIN (f_gpr) = f_fpr;
    4455                 :      273310 :   DECL_CHAIN (f_fpr) = f_ovf;
    4456                 :      273310 :   DECL_CHAIN (f_ovf) = f_sav;
    4457                 :             : 
    4458                 :      273310 :   layout_type (record);
    4459                 :             : 
    4460                 :      273310 :   TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
    4461                 :      273310 :                                         NULL_TREE, TYPE_ATTRIBUTES (record));
    4462                 :             : 
    4463                 :             :   /* The correct type is an array type of one element.  */
    4464                 :      273310 :   return build_array_type (record, build_index_type (size_zero_node));
    4465                 :             : }
    4466                 :             : 
    4467                 :             : /* Setup the builtin va_list data type and for 64-bit the additional
    4468                 :             :    calling convention specific va_list data types.  */
    4469                 :             : 
    4470                 :             : static tree
    4471                 :      280166 : ix86_build_builtin_va_list (void)
    4472                 :             : {
    4473                 :      280166 :   if (TARGET_64BIT)
    4474                 :             :     {
    4475                 :             :       /* Initialize ABI specific va_list builtin types.
    4476                 :             : 
    4477                 :             :          In lto1, we can encounter two va_list types:
    4478                 :             :          - one as a result of the type-merge across TUs, and
    4479                 :             :          - the one constructed here.
    4480                 :             :          These two types will not have the same TYPE_MAIN_VARIANT, and therefore
    4481                 :             :          a type identity check in canonical_va_list_type based on
    4482                 :             :          TYPE_MAIN_VARIANT (which we used to have) will not work.
    4483                 :             :          Instead, we tag each va_list_type_node with its unique attribute, and
    4484                 :             :          look for the attribute in the type identity check in
    4485                 :             :          canonical_va_list_type.
    4486                 :             : 
    4487                 :             :          Tagging sysv_va_list_type_node directly with the attribute is
    4488                 :             :          problematic since it's a array of one record, which will degrade into a
    4489                 :             :          pointer to record when used as parameter (see build_va_arg comments for
    4490                 :             :          an example), dropping the attribute in the process.  So we tag the
    4491                 :             :          record instead.  */
    4492                 :             : 
    4493                 :             :       /* For SYSV_ABI we use an array of one record.  */
    4494                 :      273310 :       sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
    4495                 :             :         
    4496                 :             :       /* For MS_ABI we use plain pointer to argument area.  */
    4497                 :      273310 :       tree char_ptr_type = build_pointer_type (char_type_node);
    4498                 :      273310 :       tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
    4499                 :      273310 :                              TYPE_ATTRIBUTES (char_ptr_type));
    4500                 :      273310 :       ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
    4501                 :             : 
    4502                 :      273310 :       return ((ix86_abi == MS_ABI)
    4503                 :      273310 :               ? ms_va_list_type_node
    4504                 :      273310 :               : sysv_va_list_type_node);
    4505                 :             :     }
    4506                 :             :   else
    4507                 :             :     {
    4508                 :             :       /* For i386 we use plain pointer to argument area.  */
    4509                 :        6856 :       return build_pointer_type (char_type_node);
    4510                 :             :     }
    4511                 :             : }
    4512                 :             : 
    4513                 :             : /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
    4514                 :             : 
    4515                 :             : static void
    4516                 :       15346 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
    4517                 :             : {
    4518                 :       15346 :   rtx save_area, mem;
    4519                 :       15346 :   alias_set_type set;
    4520                 :       15346 :   int i, max;
    4521                 :             : 
    4522                 :             :   /* GPR size of varargs save area.  */
    4523                 :       15346 :   if (cfun->va_list_gpr_size)
    4524                 :       14925 :     ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
    4525                 :             :   else
    4526                 :         421 :     ix86_varargs_gpr_size = 0;
    4527                 :             : 
    4528                 :             :   /* FPR size of varargs save area.  We don't need it if we don't pass
    4529                 :             :      anything in SSE registers.  */
    4530                 :       15346 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4531                 :       14388 :     ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
    4532                 :             :   else
    4533                 :         958 :     ix86_varargs_fpr_size = 0;
    4534                 :             : 
    4535                 :       15346 :   if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
    4536                 :             :     return;
    4537                 :             : 
    4538                 :       15092 :   save_area = frame_pointer_rtx;
    4539                 :       15092 :   set = get_varargs_alias_set ();
    4540                 :             : 
    4541                 :       15092 :   max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
    4542                 :       15092 :   if (max > X86_64_REGPARM_MAX)
    4543                 :             :     max = X86_64_REGPARM_MAX;
    4544                 :             : 
    4545                 :       84071 :   for (i = cum->regno; i < max; i++)
    4546                 :             :     {
    4547                 :       68979 :       mem = gen_rtx_MEM (word_mode,
    4548                 :       68979 :                          plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
    4549                 :       68979 :       MEM_NOTRAP_P (mem) = 1;
    4550                 :       68979 :       set_mem_alias_set (mem, set);
    4551                 :       68979 :       emit_move_insn (mem,
    4552                 :             :                       gen_rtx_REG (word_mode,
    4553                 :       68979 :                                    x86_64_int_parameter_registers[i]));
    4554                 :             :     }
    4555                 :             : 
    4556                 :       15092 :   if (ix86_varargs_fpr_size)
    4557                 :             :     {
    4558                 :       14388 :       machine_mode smode;
    4559                 :       14388 :       rtx_code_label *label;
    4560                 :       14388 :       rtx test;
    4561                 :             : 
    4562                 :             :       /* Now emit code to save SSE registers.  The AX parameter contains number
    4563                 :             :          of SSE parameter registers used to call this function, though all we
    4564                 :             :          actually check here is the zero/non-zero status.  */
    4565                 :             : 
    4566                 :       14388 :       label = gen_label_rtx ();
    4567                 :       14388 :       test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
    4568                 :       14388 :       emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
    4569                 :             :                                       label));
    4570                 :             : 
    4571                 :             :       /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
    4572                 :             :          we used movdqa (i.e. TImode) instead?  Perhaps even better would
    4573                 :             :          be if we could determine the real mode of the data, via a hook
    4574                 :             :          into pass_stdarg.  Ignore all that for now.  */
    4575                 :       14388 :       smode = V4SFmode;
    4576                 :       14388 :       if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
    4577                 :        3898 :         crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
    4578                 :             : 
    4579                 :       14388 :       max = cum->sse_regno + cfun->va_list_fpr_size / 16;
    4580                 :       14388 :       if (max > X86_64_SSE_REGPARM_MAX)
    4581                 :             :         max = X86_64_SSE_REGPARM_MAX;
    4582                 :             : 
    4583                 :      127956 :       for (i = cum->sse_regno; i < max; ++i)
    4584                 :             :         {
    4585                 :      113568 :           mem = plus_constant (Pmode, save_area,
    4586                 :      113568 :                                i * 16 + ix86_varargs_gpr_size);
    4587                 :      113568 :           mem = gen_rtx_MEM (smode, mem);
    4588                 :      113568 :           MEM_NOTRAP_P (mem) = 1;
    4589                 :      113568 :           set_mem_alias_set (mem, set);
    4590                 :      113568 :           set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
    4591                 :             : 
    4592                 :      113568 :           emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
    4593                 :             :         }
    4594                 :             : 
    4595                 :       14388 :       emit_label (label);
    4596                 :             :     }
    4597                 :             : }
    4598                 :             : 
    4599                 :             : static void
    4600                 :        5652 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
    4601                 :             : {
    4602                 :        5652 :   alias_set_type set = get_varargs_alias_set ();
    4603                 :        5652 :   int i;
    4604                 :             : 
    4605                 :             :   /* Reset to zero, as there might be a sysv vaarg used
    4606                 :             :      before.  */
    4607                 :        5652 :   ix86_varargs_gpr_size = 0;
    4608                 :        5652 :   ix86_varargs_fpr_size = 0;
    4609                 :             : 
    4610                 :       14154 :   for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
    4611                 :             :     {
    4612                 :        8502 :       rtx reg, mem;
    4613                 :             : 
    4614                 :        8502 :       mem = gen_rtx_MEM (Pmode,
    4615                 :        8502 :                          plus_constant (Pmode, virtual_incoming_args_rtx,
    4616                 :        8502 :                                         i * UNITS_PER_WORD));
    4617                 :        8502 :       MEM_NOTRAP_P (mem) = 1;
    4618                 :        8502 :       set_mem_alias_set (mem, set);
    4619                 :             : 
    4620                 :        8502 :       reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
    4621                 :        8502 :       emit_move_insn (mem, reg);
    4622                 :             :     }
    4623                 :        5652 : }
    4624                 :             : 
    4625                 :             : static void
    4626                 :       21144 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
    4627                 :             :                              const function_arg_info &arg,
    4628                 :             :                              int *, int no_rtl)
    4629                 :             : {
    4630                 :       21144 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    4631                 :       21144 :   CUMULATIVE_ARGS next_cum;
    4632                 :       21144 :   tree fntype;
    4633                 :             : 
    4634                 :             :   /* This argument doesn't appear to be used anymore.  Which is good,
    4635                 :             :      because the old code here didn't suppress rtl generation.  */
    4636                 :       21144 :   gcc_assert (!no_rtl);
    4637                 :             : 
    4638                 :       21144 :   if (!TARGET_64BIT)
    4639                 :         146 :     return;
    4640                 :             : 
    4641                 :       20998 :   fntype = TREE_TYPE (current_function_decl);
    4642                 :             : 
    4643                 :             :   /* For varargs, we do not want to skip the dummy va_dcl argument.
    4644                 :             :      For stdargs, we do want to skip the last named argument.  */
    4645                 :       20998 :   next_cum = *cum;
    4646                 :       20998 :   if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
    4647                 :          63 :        || arg.type != NULL_TREE)
    4648                 :       21010 :       && stdarg_p (fntype))
    4649                 :       20947 :     ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
    4650                 :             : 
    4651                 :       20998 :   if (cum->call_abi == MS_ABI)
    4652                 :        5652 :     setup_incoming_varargs_ms_64 (&next_cum);
    4653                 :             :   else
    4654                 :       15346 :     setup_incoming_varargs_64 (&next_cum);
    4655                 :             : }
    4656                 :             : 
    4657                 :             : /* Checks if TYPE is of kind va_list char *.  */
    4658                 :             : 
    4659                 :             : static bool
    4660                 :       72481 : is_va_list_char_pointer (tree type)
    4661                 :             : {
    4662                 :       72481 :   tree canonic;
    4663                 :             : 
    4664                 :             :   /* For 32-bit it is always true.  */
    4665                 :       72481 :   if (!TARGET_64BIT)
    4666                 :             :     return true;
    4667                 :       72319 :   canonic = ix86_canonical_va_list_type (type);
    4668                 :       72319 :   return (canonic == ms_va_list_type_node
    4669                 :       72319 :           || (ix86_abi == MS_ABI && canonic == va_list_type_node));
    4670                 :             : }
    4671                 :             : 
    4672                 :             : /* Implement va_start.  */
    4673                 :             : 
    4674                 :             : static void
    4675                 :       20688 : ix86_va_start (tree valist, rtx nextarg)
    4676                 :             : {
    4677                 :       20688 :   HOST_WIDE_INT words, n_gpr, n_fpr;
    4678                 :       20688 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4679                 :       20688 :   tree gpr, fpr, ovf, sav, t;
    4680                 :       20688 :   tree type;
    4681                 :       20688 :   rtx ovf_rtx;
    4682                 :             : 
    4683                 :       20688 :   if (flag_split_stack
    4684                 :          12 :       && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4685                 :             :     {
    4686                 :          12 :       unsigned int scratch_regno;
    4687                 :             : 
    4688                 :             :       /* When we are splitting the stack, we can't refer to the stack
    4689                 :             :          arguments using internal_arg_pointer, because they may be on
    4690                 :             :          the old stack.  The split stack prologue will arrange to
    4691                 :             :          leave a pointer to the old stack arguments in a scratch
    4692                 :             :          register, which we here copy to a pseudo-register.  The split
    4693                 :             :          stack prologue can't set the pseudo-register directly because
    4694                 :             :          it (the prologue) runs before any registers have been saved.  */
    4695                 :             : 
    4696                 :          12 :       scratch_regno = split_stack_prologue_scratch_regno ();
    4697                 :          12 :       if (scratch_regno != INVALID_REGNUM)
    4698                 :             :         {
    4699                 :          12 :           rtx reg;
    4700                 :          12 :           rtx_insn *seq;
    4701                 :             : 
    4702                 :          12 :           reg = gen_reg_rtx (Pmode);
    4703                 :          12 :           cfun->machine->split_stack_varargs_pointer = reg;
    4704                 :             : 
    4705                 :          12 :           start_sequence ();
    4706                 :          12 :           emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
    4707                 :          12 :           seq = get_insns ();
    4708                 :          12 :           end_sequence ();
    4709                 :             : 
    4710                 :          12 :           push_topmost_sequence ();
    4711                 :          12 :           emit_insn_after (seq, entry_of_function ());
    4712                 :          12 :           pop_topmost_sequence ();
    4713                 :             :         }
    4714                 :             :     }
    4715                 :             : 
    4716                 :             :   /* Only 64bit target needs something special.  */
    4717                 :       20688 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4718                 :             :     {
    4719                 :        5656 :       if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4720                 :        5652 :         std_expand_builtin_va_start (valist, nextarg);
    4721                 :             :       else
    4722                 :             :         {
    4723                 :           4 :           rtx va_r, next;
    4724                 :             : 
    4725                 :           4 :           va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
    4726                 :           8 :           next = expand_binop (ptr_mode, add_optab,
    4727                 :           4 :                                cfun->machine->split_stack_varargs_pointer,
    4728                 :             :                                crtl->args.arg_offset_rtx,
    4729                 :             :                                NULL_RTX, 0, OPTAB_LIB_WIDEN);
    4730                 :           4 :           convert_move (va_r, next, 0);
    4731                 :             :         }
    4732                 :        5656 :       return;
    4733                 :             :     }
    4734                 :             : 
    4735                 :       15032 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4736                 :       15032 :   f_fpr = DECL_CHAIN (f_gpr);
    4737                 :       15032 :   f_ovf = DECL_CHAIN (f_fpr);
    4738                 :       15032 :   f_sav = DECL_CHAIN (f_ovf);
    4739                 :             : 
    4740                 :       15032 :   valist = build_simple_mem_ref (valist);
    4741                 :       15032 :   TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
    4742                 :             :   /* The following should be folded into the MEM_REF offset.  */
    4743                 :       15032 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
    4744                 :             :                 f_gpr, NULL_TREE);
    4745                 :       15032 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
    4746                 :             :                 f_fpr, NULL_TREE);
    4747                 :       15032 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
    4748                 :             :                 f_ovf, NULL_TREE);
    4749                 :       15032 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
    4750                 :             :                 f_sav, NULL_TREE);
    4751                 :             : 
    4752                 :             :   /* Count number of gp and fp argument registers used.  */
    4753                 :       15032 :   words = crtl->args.info.words;
    4754                 :       15032 :   n_gpr = crtl->args.info.regno;
    4755                 :       15032 :   n_fpr = crtl->args.info.sse_regno;
    4756                 :             : 
    4757                 :       15032 :   if (cfun->va_list_gpr_size)
    4758                 :             :     {
    4759                 :       14819 :       type = TREE_TYPE (gpr);
    4760                 :       14819 :       t = build2 (MODIFY_EXPR, type,
    4761                 :       14819 :                   gpr, build_int_cst (type, n_gpr * 8));
    4762                 :       14819 :       TREE_SIDE_EFFECTS (t) = 1;
    4763                 :       14819 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4764                 :             :     }
    4765                 :             : 
    4766                 :       15032 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4767                 :             :     {
    4768                 :       14273 :       type = TREE_TYPE (fpr);
    4769                 :       14273 :       t = build2 (MODIFY_EXPR, type, fpr,
    4770                 :       14273 :                   build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
    4771                 :       14273 :       TREE_SIDE_EFFECTS (t) = 1;
    4772                 :       14273 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4773                 :             :     }
    4774                 :             : 
    4775                 :             :   /* Find the overflow area.  */
    4776                 :       15032 :   type = TREE_TYPE (ovf);
    4777                 :       15032 :   if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4778                 :       15024 :     ovf_rtx = crtl->args.internal_arg_pointer;
    4779                 :             :   else
    4780                 :             :     ovf_rtx = cfun->machine->split_stack_varargs_pointer;
    4781                 :       15032 :   t = make_tree (type, ovf_rtx);
    4782                 :       15032 :   if (words != 0)
    4783                 :         435 :     t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
    4784                 :             : 
    4785                 :       15032 :   t = build2 (MODIFY_EXPR, type, ovf, t);
    4786                 :       15032 :   TREE_SIDE_EFFECTS (t) = 1;
    4787                 :       15032 :   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4788                 :             : 
    4789                 :       15032 :   if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
    4790                 :             :     {
    4791                 :             :       /* Find the register save area.
    4792                 :             :          Prologue of the function save it right above stack frame.  */
    4793                 :       14986 :       type = TREE_TYPE (sav);
    4794                 :       14986 :       t = make_tree (type, frame_pointer_rtx);
    4795                 :       14986 :       if (!ix86_varargs_gpr_size)
    4796                 :         167 :         t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
    4797                 :             : 
    4798                 :       14986 :       t = build2 (MODIFY_EXPR, type, sav, t);
    4799                 :       14986 :       TREE_SIDE_EFFECTS (t) = 1;
    4800                 :       14986 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4801                 :             :     }
    4802                 :             : }
    4803                 :             : 
    4804                 :             : /* Implement va_arg.  */
    4805                 :             : 
    4806                 :             : static tree
    4807                 :       51793 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
    4808                 :             :                       gimple_seq *post_p)
    4809                 :             : {
    4810                 :       51793 :   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
    4811                 :       51793 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4812                 :       51793 :   tree gpr, fpr, ovf, sav, t;
    4813                 :       51793 :   int size, rsize;
    4814                 :       51793 :   tree lab_false, lab_over = NULL_TREE;
    4815                 :       51793 :   tree addr, t2;
    4816                 :       51793 :   rtx container;
    4817                 :       51793 :   int indirect_p = 0;
    4818                 :       51793 :   tree ptrtype;
    4819                 :       51793 :   machine_mode nat_mode;
    4820                 :       51793 :   unsigned int arg_boundary;
    4821                 :       51793 :   unsigned int type_align;
    4822                 :             : 
    4823                 :             :   /* Only 64bit target needs something special.  */
    4824                 :       51793 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4825                 :         260 :     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
    4826                 :             : 
    4827                 :       51533 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4828                 :       51533 :   f_fpr = DECL_CHAIN (f_gpr);
    4829                 :       51533 :   f_ovf = DECL_CHAIN (f_fpr);
    4830                 :       51533 :   f_sav = DECL_CHAIN (f_ovf);
    4831                 :             : 
    4832                 :       51533 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
    4833                 :             :                 valist, f_gpr, NULL_TREE);
    4834                 :             : 
    4835                 :       51533 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
    4836                 :       51533 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
    4837                 :       51533 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
    4838                 :             : 
    4839                 :       51533 :   indirect_p = pass_va_arg_by_reference (type);
    4840                 :       51533 :   if (indirect_p)
    4841                 :          99 :     type = build_pointer_type (type);
    4842                 :       51533 :   size = arg_int_size_in_bytes (type);
    4843                 :       51533 :   rsize = CEIL (size, UNITS_PER_WORD);
    4844                 :             : 
    4845                 :       51533 :   nat_mode = type_natural_mode (type, NULL, false);
    4846                 :       51533 :   switch (nat_mode)
    4847                 :             :     {
    4848                 :          28 :     case E_V16HFmode:
    4849                 :          28 :     case E_V16BFmode:
    4850                 :          28 :     case E_V8SFmode:
    4851                 :          28 :     case E_V8SImode:
    4852                 :          28 :     case E_V32QImode:
    4853                 :          28 :     case E_V16HImode:
    4854                 :          28 :     case E_V4DFmode:
    4855                 :          28 :     case E_V4DImode:
    4856                 :          28 :     case E_V32HFmode:
    4857                 :          28 :     case E_V32BFmode:
    4858                 :          28 :     case E_V16SFmode:
    4859                 :          28 :     case E_V16SImode:
    4860                 :          28 :     case E_V64QImode:
    4861                 :          28 :     case E_V32HImode:
    4862                 :          28 :     case E_V8DFmode:
    4863                 :          28 :     case E_V8DImode:
    4864                 :             :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    4865                 :          28 :       if (!TARGET_64BIT_MS_ABI)
    4866                 :             :         {
    4867                 :             :           container = NULL;
    4868                 :             :           break;
    4869                 :             :         }
    4870                 :             :       /* FALLTHRU */
    4871                 :             : 
    4872                 :       51505 :     default:
    4873                 :       51505 :       container = construct_container (nat_mode, TYPE_MODE (type),
    4874                 :             :                                        type, 0, X86_64_REGPARM_MAX,
    4875                 :             :                                        X86_64_SSE_REGPARM_MAX, intreg,
    4876                 :             :                                        0);
    4877                 :       51505 :       break;
    4878                 :             :     }
    4879                 :             : 
    4880                 :             :   /* Pull the value out of the saved registers.  */
    4881                 :             : 
    4882                 :       51533 :   addr = create_tmp_var (ptr_type_node, "addr");
    4883                 :       51533 :   type_align = TYPE_ALIGN (type);
    4884                 :             : 
    4885                 :       51533 :   if (container)
    4886                 :             :     {
    4887                 :       28439 :       int needed_intregs, needed_sseregs;
    4888                 :       28439 :       bool need_temp;
    4889                 :       28439 :       tree int_addr, sse_addr;
    4890                 :             : 
    4891                 :       28439 :       lab_false = create_artificial_label (UNKNOWN_LOCATION);
    4892                 :       28439 :       lab_over = create_artificial_label (UNKNOWN_LOCATION);
    4893                 :             : 
    4894                 :       28439 :       examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
    4895                 :             : 
    4896                 :       56360 :       need_temp = (!REG_P (container)
    4897                 :       28439 :                    && ((needed_intregs && TYPE_ALIGN (type) > 64)
    4898                 :        1113 :                        || TYPE_ALIGN (type) > 128));
    4899                 :             : 
    4900                 :             :       /* In case we are passing structure, verify that it is consecutive block
    4901                 :             :          on the register save area.  If not we need to do moves.  */
    4902                 :       27921 :       if (!need_temp && !REG_P (container))
    4903                 :             :         {
    4904                 :             :           /* Verify that all registers are strictly consecutive  */
    4905                 :        1394 :           if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
    4906                 :             :             {
    4907                 :             :               int i;
    4908                 :             : 
    4909                 :         795 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    4910                 :             :                 {
    4911                 :         514 :                   rtx slot = XVECEXP (container, 0, i);
    4912                 :         514 :                   if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
    4913                 :         514 :                       || INTVAL (XEXP (slot, 1)) != i * 16)
    4914                 :             :                     need_temp = true;
    4915                 :             :                 }
    4916                 :             :             }
    4917                 :             :           else
    4918                 :             :             {
    4919                 :             :               int i;
    4920                 :             : 
    4921                 :        1996 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    4922                 :             :                 {
    4923                 :        1164 :                   rtx slot = XVECEXP (container, 0, i);
    4924                 :        1164 :                   if (REGNO (XEXP (slot, 0)) != (unsigned int) i
    4925                 :        1164 :                       || INTVAL (XEXP (slot, 1)) != i * 8)
    4926                 :             :                     need_temp = true;
    4927                 :             :                 }
    4928                 :             :             }
    4929                 :             :         }
    4930                 :       27921 :       if (!need_temp)
    4931                 :             :         {
    4932                 :             :           int_addr = addr;
    4933                 :             :           sse_addr = addr;
    4934                 :             :         }
    4935                 :             :       else
    4936                 :             :         {
    4937                 :         915 :           int_addr = create_tmp_var (ptr_type_node, "int_addr");
    4938                 :         915 :           sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
    4939                 :             :         }
    4940                 :             : 
    4941                 :             :       /* First ensure that we fit completely in registers.  */
    4942                 :       28439 :       if (needed_intregs)
    4943                 :             :         {
    4944                 :       17760 :           t = build_int_cst (TREE_TYPE (gpr),
    4945                 :       17760 :                              (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
    4946                 :       17760 :           t = build2 (GE_EXPR, boolean_type_node, gpr, t);
    4947                 :       17760 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    4948                 :       17760 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    4949                 :       17760 :           gimplify_and_add (t, pre_p);
    4950                 :             :         }
    4951                 :       28439 :       if (needed_sseregs)
    4952                 :             :         {
    4953                 :       11059 :           t = build_int_cst (TREE_TYPE (fpr),
    4954                 :             :                              (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
    4955                 :       11059 :                              + X86_64_REGPARM_MAX * 8);
    4956                 :       11059 :           t = build2 (GE_EXPR, boolean_type_node, fpr, t);
    4957                 :       11059 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    4958                 :       11059 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    4959                 :       11059 :           gimplify_and_add (t, pre_p);
    4960                 :             :         }
    4961                 :             : 
    4962                 :             :       /* Compute index to start of area used for integer regs.  */
    4963                 :       28439 :       if (needed_intregs)
    4964                 :             :         {
    4965                 :             :           /* int_addr = gpr + sav; */
    4966                 :       17760 :           t = fold_build_pointer_plus (sav, gpr);
    4967                 :       17760 :           gimplify_assign (int_addr, t, pre_p);
    4968                 :             :         }
    4969                 :       28439 :       if (needed_sseregs)
    4970                 :             :         {
    4971                 :             :           /* sse_addr = fpr + sav; */
    4972                 :       11059 :           t = fold_build_pointer_plus (sav, fpr);
    4973                 :       11059 :           gimplify_assign (sse_addr, t, pre_p);
    4974                 :             :         }
    4975                 :       28439 :       if (need_temp)
    4976                 :             :         {
    4977                 :         915 :           int i, prev_size = 0;
    4978                 :         915 :           tree temp = create_tmp_var (type, "va_arg_tmp");
    4979                 :         915 :           TREE_ADDRESSABLE (temp) = 1;
    4980                 :             : 
    4981                 :             :           /* addr = &temp; */
    4982                 :         915 :           t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
    4983                 :         915 :           gimplify_assign (addr, t, pre_p);
    4984                 :             : 
    4985                 :        2307 :           for (i = 0; i < XVECLEN (container, 0); i++)
    4986                 :             :             {
    4987                 :        1392 :               rtx slot = XVECEXP (container, 0, i);
    4988                 :        1392 :               rtx reg = XEXP (slot, 0);
    4989                 :        1392 :               machine_mode mode = GET_MODE (reg);
    4990                 :        1392 :               tree piece_type;
    4991                 :        1392 :               tree addr_type;
    4992                 :        1392 :               tree daddr_type;
    4993                 :        1392 :               tree src_addr, src;
    4994                 :        1392 :               int src_offset;
    4995                 :        1392 :               tree dest_addr, dest;
    4996                 :        1392 :               int cur_size = GET_MODE_SIZE (mode);
    4997                 :             : 
    4998                 :        1392 :               gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
    4999                 :        1392 :               prev_size = INTVAL (XEXP (slot, 1));
    5000                 :        1392 :               if (prev_size + cur_size > size)
    5001                 :             :                 {
    5002                 :          30 :                   cur_size = size - prev_size;
    5003                 :          30 :                   unsigned int nbits = cur_size * BITS_PER_UNIT;
    5004                 :          30 :                   if (!int_mode_for_size (nbits, 1).exists (&mode))
    5005                 :          10 :                     mode = QImode;
    5006                 :             :                 }
    5007                 :        1392 :               piece_type = lang_hooks.types.type_for_mode (mode, 1);
    5008                 :        1392 :               if (mode == GET_MODE (reg))
    5009                 :        1362 :                 addr_type = build_pointer_type (piece_type);
    5010                 :             :               else
    5011                 :          30 :                 addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5012                 :             :                                                          true);
    5013                 :        1392 :               daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5014                 :             :                                                         true);
    5015                 :             : 
    5016                 :        1392 :               if (SSE_REGNO_P (REGNO (reg)))
    5017                 :             :                 {
    5018                 :         526 :                   src_addr = sse_addr;
    5019                 :         526 :                   src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
    5020                 :             :                 }
    5021                 :             :               else
    5022                 :             :                 {
    5023                 :         866 :                   src_addr = int_addr;
    5024                 :         866 :                   src_offset = REGNO (reg) * 8;
    5025                 :             :                 }
    5026                 :        1392 :               src_addr = fold_convert (addr_type, src_addr);
    5027                 :        1392 :               src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
    5028                 :             : 
    5029                 :        1392 :               dest_addr = fold_convert (daddr_type, addr);
    5030                 :        1392 :               dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
    5031                 :        2784 :               if (cur_size == GET_MODE_SIZE (mode))
    5032                 :             :                 {
    5033                 :        1382 :                   src = build_va_arg_indirect_ref (src_addr);
    5034                 :        1382 :                   dest = build_va_arg_indirect_ref (dest_addr);
    5035                 :             : 
    5036                 :        1382 :                   gimplify_assign (dest, src, pre_p);
    5037                 :             :                 }
    5038                 :             :               else
    5039                 :             :                 {
    5040                 :          10 :                   tree copy
    5041                 :          10 :                     = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
    5042                 :             :                                        3, dest_addr, src_addr,
    5043                 :             :                                        size_int (cur_size));
    5044                 :          10 :                   gimplify_and_add (copy, pre_p);
    5045                 :             :                 }
    5046                 :        1392 :               prev_size += cur_size;
    5047                 :             :             }
    5048                 :             :         }
    5049                 :             : 
    5050                 :       28439 :       if (needed_intregs)
    5051                 :             :         {
    5052                 :       17760 :           t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
    5053                 :       17760 :                       build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
    5054                 :       17760 :           gimplify_assign (gpr, t, pre_p);
    5055                 :             :           /* The GPR save area guarantees only 8-byte alignment.  */
    5056                 :       17760 :           if (!need_temp)
    5057                 :       16920 :             type_align = MIN (type_align, 64);
    5058                 :             :         }
    5059                 :             : 
    5060                 :       28439 :       if (needed_sseregs)
    5061                 :             :         {
    5062                 :       11059 :           t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
    5063                 :       11059 :                       build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
    5064                 :       11059 :           gimplify_assign (unshare_expr (fpr), t, pre_p);
    5065                 :             :         }
    5066                 :             : 
    5067                 :       28439 :       gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
    5068                 :             : 
    5069                 :       28439 :       gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
    5070                 :             :     }
    5071                 :             : 
    5072                 :             :   /* ... otherwise out of the overflow area.  */
    5073                 :             : 
    5074                 :             :   /* When we align parameter on stack for caller, if the parameter
    5075                 :             :      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
    5076                 :             :      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
    5077                 :             :      here with caller.  */
    5078                 :       51533 :   arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
    5079                 :       51533 :   if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
    5080                 :             :     arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
    5081                 :             : 
    5082                 :             :   /* Care for on-stack alignment if needed.  */
    5083                 :       51533 :   if (arg_boundary <= 64 || size == 0)
    5084                 :       34476 :     t = ovf;
    5085                 :             :  else
    5086                 :             :     {
    5087                 :       17057 :       HOST_WIDE_INT align = arg_boundary / 8;
    5088                 :       17057 :       t = fold_build_pointer_plus_hwi (ovf, align - 1);
    5089                 :       17057 :       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
    5090                 :       34114 :                   build_int_cst (TREE_TYPE (t), -align));
    5091                 :             :     }
    5092                 :             : 
    5093                 :       51533 :   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
    5094                 :       51533 :   gimplify_assign (addr, t, pre_p);
    5095                 :             : 
    5096                 :       51533 :   t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
    5097                 :       51533 :   gimplify_assign (unshare_expr (ovf), t, pre_p);
    5098                 :             : 
    5099                 :       51533 :   if (container)
    5100                 :       28439 :     gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
    5101                 :             : 
    5102                 :       51533 :   type = build_aligned_type (type, type_align);
    5103                 :       51533 :   ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
    5104                 :       51533 :   addr = fold_convert (ptrtype, addr);
    5105                 :             : 
    5106                 :       51533 :   if (indirect_p)
    5107                 :          99 :     addr = build_va_arg_indirect_ref (addr);
    5108                 :       51533 :   return build_va_arg_indirect_ref (addr);
    5109                 :             : }
    5110                 :             : 
    5111                 :             : /* Return true if OPNUM's MEM should be matched
    5112                 :             :    in movabs* patterns.  */
    5113                 :             : 
    5114                 :             : bool
    5115                 :       10270 : ix86_check_movabs (rtx insn, int opnum)
    5116                 :             : {
    5117                 :       10270 :   rtx set, mem;
    5118                 :             : 
    5119                 :       10270 :   set = PATTERN (insn);
    5120                 :       10270 :   if (GET_CODE (set) == PARALLEL)
    5121                 :           0 :     set = XVECEXP (set, 0, 0);
    5122                 :       10270 :   gcc_assert (GET_CODE (set) == SET);
    5123                 :       10270 :   mem = XEXP (set, opnum);
    5124                 :       10270 :   while (SUBREG_P (mem))
    5125                 :           0 :     mem = SUBREG_REG (mem);
    5126                 :       10270 :   gcc_assert (MEM_P (mem));
    5127                 :       10270 :   return volatile_ok || !MEM_VOLATILE_P (mem);
    5128                 :             : }
    5129                 :             : 
    5130                 :             : /* Return false if INSN contains a MEM with a non-default address space.  */
    5131                 :             : bool
    5132                 :      137633 : ix86_check_no_addr_space (rtx insn)
    5133                 :             : {
    5134                 :      137633 :   subrtx_var_iterator::array_type array;
    5135                 :     3103100 :   FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
    5136                 :             :     {
    5137                 :     2965467 :       rtx x = *iter;
    5138                 :     3182506 :       if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
    5139                 :           0 :         return false;
    5140                 :             :     }
    5141                 :      137633 :   return true;
    5142                 :      137633 : }
    5143                 :             : 
    5144                 :             : /* Initialize the table of extra 80387 mathematical constants.  */
    5145                 :             : 
    5146                 :             : static void
    5147                 :        2350 : init_ext_80387_constants (void)
    5148                 :             : {
    5149                 :        2350 :   static const char * cst[5] =
    5150                 :             :   {
    5151                 :             :     "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
    5152                 :             :     "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
    5153                 :             :     "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
    5154                 :             :     "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
    5155                 :             :     "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
    5156                 :             :   };
    5157                 :        2350 :   int i;
    5158                 :             : 
    5159                 :       14100 :   for (i = 0; i < 5; i++)
    5160                 :             :     {
    5161                 :       11750 :       real_from_string (&ext_80387_constants_table[i], cst[i]);
    5162                 :             :       /* Ensure each constant is rounded to XFmode precision.  */
    5163                 :       11750 :       real_convert (&ext_80387_constants_table[i],
    5164                 :       23500 :                     XFmode, &ext_80387_constants_table[i]);
    5165                 :             :     }
    5166                 :             : 
    5167                 :        2350 :   ext_80387_constants_init = 1;
    5168                 :        2350 : }
    5169                 :             : 
    5170                 :             : /* Return non-zero if the constant is something that
    5171                 :             :    can be loaded with a special instruction.  */
    5172                 :             : 
    5173                 :             : int
    5174                 :     4896996 : standard_80387_constant_p (rtx x)
    5175                 :             : {
    5176                 :     4896996 :   machine_mode mode = GET_MODE (x);
    5177                 :             : 
    5178                 :     4896996 :   const REAL_VALUE_TYPE *r;
    5179                 :             : 
    5180                 :     4896996 :   if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
    5181                 :             :     return -1;
    5182                 :             : 
    5183                 :     4477509 :   if (x == CONST0_RTX (mode))
    5184                 :             :     return 1;
    5185                 :     2027275 :   if (x == CONST1_RTX (mode))
    5186                 :             :     return 2;
    5187                 :             : 
    5188                 :     1199074 :   r = CONST_DOUBLE_REAL_VALUE (x);
    5189                 :             : 
    5190                 :             :   /* For XFmode constants, try to find a special 80387 instruction when
    5191                 :             :      optimizing for size or on those CPUs that benefit from them.  */
    5192                 :     1199074 :   if (mode == XFmode
    5193                 :      783816 :       && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
    5194                 :     1982890 :       && !flag_rounding_math)
    5195                 :             :     {
    5196                 :      776168 :       int i;
    5197                 :             : 
    5198                 :      776168 :       if (! ext_80387_constants_init)
    5199                 :        2343 :         init_ext_80387_constants ();
    5200                 :             : 
    5201                 :     4646514 :       for (i = 0; i < 5; i++)
    5202                 :     3879159 :         if (real_identical (r, &ext_80387_constants_table[i]))
    5203                 :        8813 :           return i + 3;
    5204                 :             :     }
    5205                 :             : 
    5206                 :             :   /* Load of the constant -0.0 or -1.0 will be split as
    5207                 :             :      fldz;fchs or fld1;fchs sequence.  */
    5208                 :     1190261 :   if (real_isnegzero (r))
    5209                 :             :     return 8;
    5210                 :     1174413 :   if (real_identical (r, &dconstm1))
    5211                 :      294746 :     return 9;
    5212                 :             : 
    5213                 :             :   return 0;
    5214                 :             : }
    5215                 :             : 
    5216                 :             : /* Return the opcode of the special instruction to be used to load
    5217                 :             :    the constant X.  */
    5218                 :             : 
    5219                 :             : const char *
    5220                 :       55257 : standard_80387_constant_opcode (rtx x)
    5221                 :             : {
    5222                 :       55257 :   switch (standard_80387_constant_p (x))
    5223                 :             :     {
    5224                 :             :     case 1:
    5225                 :             :       return "fldz";
    5226                 :       34083 :     case 2:
    5227                 :       34083 :       return "fld1";
    5228                 :           1 :     case 3:
    5229                 :           1 :       return "fldlg2";
    5230                 :          10 :     case 4:
    5231                 :          10 :       return "fldln2";
    5232                 :          12 :     case 5:
    5233                 :          12 :       return "fldl2e";
    5234                 :           2 :     case 6:
    5235                 :           2 :       return "fldl2t";
    5236                 :         192 :     case 7:
    5237                 :         192 :       return "fldpi";
    5238                 :           0 :     case 8:
    5239                 :           0 :     case 9:
    5240                 :           0 :       return "#";
    5241                 :           0 :     default:
    5242                 :           0 :       gcc_unreachable ();
    5243                 :             :     }
    5244                 :             : }
    5245                 :             : 
    5246                 :             : /* Return the CONST_DOUBLE representing the 80387 constant that is
    5247                 :             :    loaded by the specified special instruction.  The argument IDX
    5248                 :             :    matches the return value from standard_80387_constant_p.  */
    5249                 :             : 
    5250                 :             : rtx
    5251                 :          24 : standard_80387_constant_rtx (int idx)
    5252                 :             : {
    5253                 :          24 :   int i;
    5254                 :             : 
    5255                 :          24 :   if (! ext_80387_constants_init)
    5256                 :           7 :     init_ext_80387_constants ();
    5257                 :             : 
    5258                 :          24 :   switch (idx)
    5259                 :             :     {
    5260                 :          24 :     case 3:
    5261                 :          24 :     case 4:
    5262                 :          24 :     case 5:
    5263                 :          24 :     case 6:
    5264                 :          24 :     case 7:
    5265                 :          24 :       i = idx - 3;
    5266                 :          24 :       break;
    5267                 :             : 
    5268                 :           0 :     default:
    5269                 :           0 :       gcc_unreachable ();
    5270                 :             :     }
    5271                 :             : 
    5272                 :          24 :   return const_double_from_real_value (ext_80387_constants_table[i],
    5273                 :          24 :                                        XFmode);
    5274                 :             : }
    5275                 :             : 
    5276                 :             : /* Return 1 if X is all bits 0, 2 if X is all bits 1
    5277                 :             :    and 3 if X is all bits 1 with zero extend
    5278                 :             :    in supported SSE/AVX vector mode.  */
    5279                 :             : 
    5280                 :             : int
    5281                 :    35465390 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
    5282                 :             : {
    5283                 :    35465390 :   machine_mode mode;
    5284                 :             : 
    5285                 :    35465390 :   if (!TARGET_SSE)
    5286                 :             :     return 0;
    5287                 :             : 
    5288                 :    35302166 :   mode = GET_MODE (x);
    5289                 :             : 
    5290                 :    35302166 :   if (x == const0_rtx || const0_operand (x, mode))
    5291                 :     7720176 :     return 1;
    5292                 :             : 
    5293                 :    27581990 :   if (x == constm1_rtx
    5294                 :    27456559 :       || vector_all_ones_operand (x, mode)
    5295                 :    54950660 :       || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5296                 :    23559842 :            || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
    5297                 :     3808828 :           && float_vector_all_ones_operand (x, mode)))
    5298                 :             :     {
    5299                 :             :       /* VOIDmode integer constant, get mode from the predicate.  */
    5300                 :      214735 :       if (mode == VOIDmode)
    5301                 :      125431 :         mode = pred_mode;
    5302                 :             : 
    5303                 :      429470 :       switch (GET_MODE_SIZE (mode))
    5304                 :             :         {
    5305                 :        7473 :         case 64:
    5306                 :        7473 :           if (TARGET_AVX512F && TARGET_EVEX512)
    5307                 :             :             return 2;
    5308                 :             :           break;
    5309                 :        6326 :         case 32:
    5310                 :        6326 :           if (TARGET_AVX2)
    5311                 :             :             return 2;
    5312                 :             :           break;
    5313                 :      190575 :         case 16:
    5314                 :      190575 :           if (TARGET_SSE2)
    5315                 :             :             return 2;
    5316                 :             :           break;
    5317                 :           0 :         case 0:
    5318                 :             :           /* VOIDmode */
    5319                 :           0 :           gcc_unreachable ();
    5320                 :             :         default:
    5321                 :             :           break;
    5322                 :             :         }
    5323                 :             :     }
    5324                 :             : 
    5325                 :    27378097 :   if (vector_all_ones_zero_extend_half_operand (x, mode)
    5326                 :    27378097 :       || vector_all_ones_zero_extend_quarter_operand (x, mode))
    5327                 :         407 :     return 3;
    5328                 :             : 
    5329                 :             :   return 0;
    5330                 :             : }
    5331                 :             : 
    5332                 :             : /* Return the opcode of the special instruction to be used to load
    5333                 :             :    the constant operands[1] into operands[0].  */
    5334                 :             : 
    5335                 :             : const char *
    5336                 :      423462 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
    5337                 :             : {
    5338                 :      423462 :   machine_mode mode;
    5339                 :      423462 :   rtx x = operands[1];
    5340                 :             : 
    5341                 :      423462 :   gcc_assert (TARGET_SSE);
    5342                 :             : 
    5343                 :      423462 :   mode = GET_MODE (x);
    5344                 :             : 
    5345                 :      423462 :   if (x == const0_rtx || const0_operand (x, mode))
    5346                 :             :     {
    5347                 :      420672 :       switch (get_attr_mode (insn))
    5348                 :             :         {
    5349                 :      405269 :         case MODE_TI:
    5350                 :      405269 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5351                 :             :             return "%vpxor\t%0, %d0";
    5352                 :             :           /* FALLTHRU */
    5353                 :        4277 :         case MODE_XI:
    5354                 :        4277 :         case MODE_OI:
    5355                 :        4277 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5356                 :             :             {
    5357                 :          25 :               if (TARGET_AVX512VL)
    5358                 :             :                 return "vpxord\t%x0, %x0, %x0";
    5359                 :          22 :               else if (TARGET_EVEX512)
    5360                 :             :                 return "vpxord\t%g0, %g0, %g0";
    5361                 :             :               else
    5362                 :           0 :                 gcc_unreachable ();
    5363                 :             :             }
    5364                 :             :           return "vpxor\t%x0, %x0, %x0";
    5365                 :             : 
    5366                 :        1991 :         case MODE_V2DF:
    5367                 :        1991 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5368                 :             :             return "%vxorpd\t%0, %d0";
    5369                 :             :           /* FALLTHRU */
    5370                 :         871 :         case MODE_V8DF:
    5371                 :         871 :         case MODE_V4DF:
    5372                 :         871 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5373                 :             :             {
    5374                 :           5 :               if (TARGET_AVX512DQ)
    5375                 :             :                 {
    5376                 :           0 :                   if (TARGET_AVX512VL)
    5377                 :             :                     return "vxorpd\t%x0, %x0, %x0";
    5378                 :           0 :                   else if (TARGET_EVEX512)
    5379                 :             :                     return "vxorpd\t%g0, %g0, %g0";
    5380                 :             :                   else
    5381                 :           0 :                     gcc_unreachable ();
    5382                 :             :                 }
    5383                 :             :               else
    5384                 :             :                 {
    5385                 :           5 :                   if (TARGET_AVX512VL)
    5386                 :             :                     return "vpxorq\t%x0, %x0, %x0";
    5387                 :           5 :                   else if (TARGET_EVEX512)
    5388                 :             :                     return "vpxorq\t%g0, %g0, %g0";
    5389                 :             :                   else
    5390                 :           0 :                     gcc_unreachable ();
    5391                 :             :                 }
    5392                 :             :             }
    5393                 :             :           return "vxorpd\t%x0, %x0, %x0";
    5394                 :             : 
    5395                 :        6368 :         case MODE_V4SF:
    5396                 :        6368 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5397                 :             :             return "%vxorps\t%0, %d0";
    5398                 :             :           /* FALLTHRU */
    5399                 :        1921 :         case MODE_V16SF:
    5400                 :        1921 :         case MODE_V8SF:
    5401                 :        1921 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5402                 :             :             {
    5403                 :          24 :               if (TARGET_AVX512DQ)
    5404                 :             :                 {
    5405                 :          21 :                   if (TARGET_AVX512VL)
    5406                 :             :                     return "vxorps\t%x0, %x0, %x0";
    5407                 :           0 :                   else if (TARGET_EVEX512)
    5408                 :             :                     return "vxorps\t%g0, %g0, %g0";
    5409                 :             :                   else
    5410                 :           0 :                     gcc_unreachable ();
    5411                 :             :                 }
    5412                 :             :               else
    5413                 :             :                 {
    5414                 :           3 :                   if (TARGET_AVX512VL)
    5415                 :             :                     return "vpxord\t%x0, %x0, %x0";
    5416                 :           0 :                   else if (TARGET_EVEX512)
    5417                 :             :                     return "vpxord\t%g0, %g0, %g0";
    5418                 :             :                   else
    5419                 :           0 :                     gcc_unreachable ();
    5420                 :             :                 }
    5421                 :             :             }
    5422                 :             :           return "vxorps\t%x0, %x0, %x0";
    5423                 :             : 
    5424                 :           0 :         default:
    5425                 :           0 :           gcc_unreachable ();
    5426                 :             :         }
    5427                 :             :     }
    5428                 :        2790 :   else if (x == constm1_rtx
    5429                 :        2781 :            || vector_all_ones_operand (x, mode)
    5430                 :        2836 :            || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5431                 :          26 :                && float_vector_all_ones_operand (x, mode)))
    5432                 :             :     {
    5433                 :        2770 :       enum attr_mode insn_mode = get_attr_mode (insn);
    5434                 :             :       
    5435                 :        2770 :       switch (insn_mode)
    5436                 :             :         {
    5437                 :           0 :         case MODE_XI:
    5438                 :           0 :         case MODE_V8DF:
    5439                 :           0 :         case MODE_V16SF:
    5440                 :           0 :           gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5441                 :             :           return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5442                 :             : 
    5443                 :         162 :         case MODE_OI:
    5444                 :         162 :         case MODE_V4DF:
    5445                 :         162 :         case MODE_V8SF:
    5446                 :         162 :           gcc_assert (TARGET_AVX2);
    5447                 :             :           /* FALLTHRU */
    5448                 :        2770 :         case MODE_TI:
    5449                 :        2770 :         case MODE_V2DF:
    5450                 :        2770 :         case MODE_V4SF:
    5451                 :        2770 :           gcc_assert (TARGET_SSE2);
    5452                 :        2770 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5453                 :             :             {
    5454                 :           2 :               if (TARGET_AVX512VL)
    5455                 :             :                 return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
    5456                 :           0 :               else if (TARGET_EVEX512)
    5457                 :             :                 return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5458                 :             :               else
    5459                 :           0 :                 gcc_unreachable ();
    5460                 :             :             }
    5461                 :        2768 :           return (TARGET_AVX
    5462                 :        2768 :                   ? "vpcmpeqd\t%0, %0, %0"
    5463                 :        2768 :                   : "pcmpeqd\t%0, %0");
    5464                 :             : 
    5465                 :           0 :         default:
    5466                 :           0 :           gcc_unreachable ();
    5467                 :             :         }
    5468                 :             :    }
    5469                 :          20 :   else if (vector_all_ones_zero_extend_half_operand (x, mode))
    5470                 :             :     {
    5471                 :          38 :       if (GET_MODE_SIZE (mode) == 64)
    5472                 :             :         {
    5473                 :           5 :           gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5474                 :             :           return "vpcmpeqd\t%t0, %t0, %t0";
    5475                 :             :         }
    5476                 :          28 :       else if (GET_MODE_SIZE (mode) == 32)
    5477                 :             :         {
    5478                 :          14 :           gcc_assert (TARGET_AVX);
    5479                 :             :           return "vpcmpeqd\t%x0, %x0, %x0";
    5480                 :             :         }
    5481                 :           0 :       gcc_unreachable ();
    5482                 :             :     }
    5483                 :           1 :   else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
    5484                 :             :     {
    5485                 :           1 :       gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
    5486                 :             :       return "vpcmpeqd\t%x0, %x0, %x0";
    5487                 :             :     }
    5488                 :             : 
    5489                 :           0 :   gcc_unreachable ();
    5490                 :             : }
    5491                 :             : 
    5492                 :             : /* Returns true if INSN can be transformed from a memory load
    5493                 :             :    to a supported FP constant load.  */
    5494                 :             : 
    5495                 :             : bool
    5496                 :     2151814 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
    5497                 :             : {
    5498                 :     2151814 :   rtx src = find_constant_src (insn);
    5499                 :             : 
    5500                 :     2151814 :   gcc_assert (REG_P (dst));
    5501                 :             : 
    5502                 :     2151814 :   if (src == NULL
    5503                 :      604477 :       || (SSE_REGNO_P (REGNO (dst))
    5504                 :      471012 :           && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
    5505                 :      166561 :       || (!TARGET_AVX512VL
    5506                 :      166499 :           && EXT_REX_SSE_REGNO_P (REGNO (dst))
    5507                 :          14 :           && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
    5508                 :     2318361 :       || (STACK_REGNO_P (REGNO (dst))
    5509                 :      133465 :            && standard_80387_constant_p (src) < 1))
    5510                 :     2075194 :     return false;
    5511                 :             : 
    5512                 :             :   return true;
    5513                 :             : }
    5514                 :             : 
    5515                 :             : /* Predicate for pre-reload splitters with associated instructions,
    5516                 :             :    which can match any time before the split1 pass (usually combine),
    5517                 :             :    then are unconditionally split in that pass and should not be
    5518                 :             :    matched again afterwards.  */
    5519                 :             : 
    5520                 :             : bool
    5521                 :     5828383 : ix86_pre_reload_split (void)
    5522                 :             : {
    5523                 :     5828383 :   return (can_create_pseudo_p ()
    5524                 :     8719106 :           && !(cfun->curr_properties & PROP_rtl_split_insns));
    5525                 :             : }
    5526                 :             : 
    5527                 :             : /* Return the opcode of the TYPE_SSEMOV instruction.  To move from
    5528                 :             :    or to xmm16-xmm31/ymm16-ymm31 registers, we either require
    5529                 :             :    TARGET_AVX512VL or it is a register to register move which can
    5530                 :             :    be done with zmm register move. */
    5531                 :             : 
    5532                 :             : static const char *
    5533                 :     3621484 : ix86_get_ssemov (rtx *operands, unsigned size,
    5534                 :             :                  enum attr_mode insn_mode, machine_mode mode)
    5535                 :             : {
    5536                 :     3621484 :   char buf[128];
    5537                 :     3621484 :   bool misaligned_p = (misaligned_operand (operands[0], mode)
    5538                 :     3621484 :                        || misaligned_operand (operands[1], mode));
    5539                 :     3621484 :   bool evex_reg_p = (size == 64
    5540                 :     3546174 :                      || EXT_REX_SSE_REG_P (operands[0])
    5541                 :     7167048 :                      || EXT_REX_SSE_REG_P (operands[1]));
    5542                 :             : 
    5543                 :     3621484 :   bool egpr_p = (TARGET_APX_EGPR
    5544                 :     3621484 :                  && (x86_extended_rex2reg_mentioned_p (operands[0])
    5545                 :         101 :                      || x86_extended_rex2reg_mentioned_p (operands[1])));
    5546                 :         193 :   bool egpr_vl = egpr_p && TARGET_AVX512VL;
    5547                 :             : 
    5548                 :     3621484 :   machine_mode scalar_mode;
    5549                 :             : 
    5550                 :     3621484 :   const char *opcode = NULL;
    5551                 :     3621484 :   enum
    5552                 :             :     {
    5553                 :             :       opcode_int,
    5554                 :             :       opcode_float,
    5555                 :             :       opcode_double
    5556                 :     3621484 :     } type = opcode_int;
    5557                 :             : 
    5558                 :     3621484 :   switch (insn_mode)
    5559                 :             :     {
    5560                 :             :     case MODE_V16SF:
    5561                 :             :     case MODE_V8SF:
    5562                 :             :     case MODE_V4SF:
    5563                 :             :       scalar_mode = E_SFmode;
    5564                 :             :       type = opcode_float;
    5565                 :             :       break;
    5566                 :      196718 :     case MODE_V8DF:
    5567                 :      196718 :     case MODE_V4DF:
    5568                 :      196718 :     case MODE_V2DF:
    5569                 :      196718 :       scalar_mode = E_DFmode;
    5570                 :      196718 :       type = opcode_double;
    5571                 :      196718 :       break;
    5572                 :     1275395 :     case MODE_XI:
    5573                 :     1275395 :     case MODE_OI:
    5574                 :     1275395 :     case MODE_TI:
    5575                 :     1275395 :       scalar_mode = GET_MODE_INNER (mode);
    5576                 :             :       break;
    5577                 :           0 :     default:
    5578                 :           0 :       gcc_unreachable ();
    5579                 :             :     }
    5580                 :             : 
    5581                 :             :   /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
    5582                 :             :      we can only use zmm register move without memory operand.  */
    5583                 :     3621484 :   if (evex_reg_p
    5584                 :       76484 :       && !TARGET_AVX512VL
    5585                 :     3661684 :       && GET_MODE_SIZE (mode) < 64)
    5586                 :             :     {
    5587                 :             :       /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
    5588                 :             :          xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
    5589                 :             :          AVX512VL is disabled, LRA can still generate reg to
    5590                 :             :          reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
    5591                 :             :          modes.  */
    5592                 :           0 :       if (memory_operand (operands[0], mode)
    5593                 :           0 :           || memory_operand (operands[1], mode))
    5594                 :           0 :         gcc_unreachable ();
    5595                 :           0 :       size = 64;
    5596                 :             :       /* We need TARGET_EVEX512 to move into zmm register.  */
    5597                 :           0 :       gcc_assert (TARGET_EVEX512);
    5598                 :           0 :       switch (type)
    5599                 :             :         {
    5600                 :           0 :         case opcode_int:
    5601                 :           0 :           if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
    5602                 :           0 :             opcode = (misaligned_p
    5603                 :           0 :                       ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
    5604                 :             :                       : "vmovdqa64");
    5605                 :             :           else
    5606                 :           0 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5607                 :             :           break;
    5608                 :           0 :         case opcode_float:
    5609                 :           0 :           opcode = misaligned_p ? "vmovups" : "vmovaps";
    5610                 :             :           break;
    5611                 :           0 :         case opcode_double:
    5612                 :           0 :           opcode = misaligned_p ? "vmovupd" : "vmovapd";
    5613                 :             :           break;
    5614                 :             :         }
    5615                 :             :     }
    5616                 :     3621484 :   else if (SCALAR_FLOAT_MODE_P (scalar_mode))
    5617                 :             :     {
    5618                 :     2515362 :       switch (scalar_mode)
    5619                 :             :         {
    5620                 :       29441 :         case E_HFmode:
    5621                 :       29441 :         case E_BFmode:
    5622                 :       29441 :           if (evex_reg_p || egpr_vl)
    5623                 :        8817 :             opcode = (misaligned_p
    5624                 :         159 :                       ? (TARGET_AVX512BW
    5625                 :             :                          ? "vmovdqu16"
    5626                 :             :                          : "vmovdqu64")
    5627                 :             :                       : "vmovdqa64");
    5628                 :       20624 :           else if (egpr_p)
    5629                 :           0 :             opcode = (misaligned_p
    5630                 :           0 :                       ? (TARGET_AVX512BW
    5631                 :           0 :                          ? "vmovdqu16"
    5632                 :             :                          : "%vmovups")
    5633                 :             :                       : "%vmovaps");
    5634                 :             :           else
    5635                 :       20624 :             opcode = (misaligned_p
    5636                 :       20624 :                       ? (TARGET_AVX512BW
    5637                 :         463 :                          ? "vmovdqu16"
    5638                 :             :                          : "%vmovdqu")
    5639                 :             :                       : "%vmovdqa");
    5640                 :             :           break;
    5641                 :     2149371 :         case E_SFmode:
    5642                 :     2149371 :           opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5643                 :             :           break;
    5644                 :      196718 :         case E_DFmode:
    5645                 :      196718 :           opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
    5646                 :             :           break;
    5647                 :      139832 :         case E_TFmode:
    5648                 :      139832 :           if (evex_reg_p || egpr_vl)
    5649                 :          14 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5650                 :      139818 :           else if (egpr_p)
    5651                 :           0 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5652                 :             :           else
    5653                 :      139818 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5654                 :             :           break;
    5655                 :           0 :         default:
    5656                 :           0 :           gcc_unreachable ();
    5657                 :             :         }
    5658                 :             :     }
    5659                 :     1106122 :   else if (SCALAR_INT_MODE_P (scalar_mode))
    5660                 :             :     {
    5661                 :     1106122 :       switch (scalar_mode)
    5662                 :             :         {
    5663                 :       38499 :         case E_QImode:
    5664                 :       38499 :           if (evex_reg_p || egpr_vl)
    5665                 :        5596 :             opcode = (misaligned_p
    5666                 :        5596 :                       ? (TARGET_AVX512BW
    5667                 :        2351 :                          ? "vmovdqu8"
    5668                 :             :                          : "vmovdqu64")
    5669                 :             :                       : "vmovdqa64");
    5670                 :       32903 :           else if (egpr_p)
    5671                 :          30 :             opcode = (misaligned_p
    5672                 :           0 :                       ? (TARGET_AVX512BW
    5673                 :             :                          ? "vmovdqu8"
    5674                 :             :                          : "%vmovups")
    5675                 :             :                       : "%vmovaps");
    5676                 :             :           else
    5677                 :       32873 :             opcode = (misaligned_p
    5678                 :        4454 :                       ? (TARGET_AVX512BW
    5679                 :             :                          ? "vmovdqu8"
    5680                 :             :                          : "%vmovdqu")
    5681                 :             :                       : "%vmovdqa");
    5682                 :             :           break;
    5683                 :       36204 :         case E_HImode:
    5684                 :       36204 :           if (evex_reg_p || egpr_vl)
    5685                 :        3124 :             opcode = (misaligned_p
    5686                 :         111 :                       ? (TARGET_AVX512BW
    5687                 :             :                          ? "vmovdqu16"
    5688                 :             :                          : "vmovdqu64")
    5689                 :             :                       : "vmovdqa64");
    5690                 :       33080 :           else if (egpr_p)
    5691                 :          27 :             opcode = (misaligned_p
    5692                 :          27 :                       ? (TARGET_AVX512BW
    5693                 :           0 :                          ? "vmovdqu16"
    5694                 :             :                          : "%vmovups")
    5695                 :             :                       : "%vmovaps");
    5696                 :             :           else
    5697                 :       33053 :             opcode = (misaligned_p
    5698                 :       33053 :                       ? (TARGET_AVX512BW
    5699                 :        2903 :                          ? "vmovdqu16"
    5700                 :             :                          : "%vmovdqu")
    5701                 :             :                       : "%vmovdqa");
    5702                 :             :           break;
    5703                 :      138615 :         case E_SImode:
    5704                 :      138615 :           if (evex_reg_p || egpr_vl)
    5705                 :        7047 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5706                 :      131568 :           else if (egpr_p)
    5707                 :          14 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5708                 :             :           else
    5709                 :      131554 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5710                 :             :           break;
    5711                 :      881759 :         case E_DImode:
    5712                 :      881759 :         case E_TImode:
    5713                 :      881759 :         case E_OImode:
    5714                 :      881759 :           if (evex_reg_p || egpr_vl)
    5715                 :       16999 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5716                 :      864760 :           else if (egpr_p)
    5717                 :          26 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5718                 :             :           else
    5719                 :      864734 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5720                 :             :           break;
    5721                 :       11045 :         case E_XImode:
    5722                 :       11045 :           opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5723                 :             :           break;
    5724                 :           0 :         default:
    5725                 :           0 :           gcc_unreachable ();
    5726                 :             :         }
    5727                 :             :     }
    5728                 :             :   else
    5729                 :           0 :     gcc_unreachable ();
    5730                 :             : 
    5731                 :     3621484 :   switch (size)
    5732                 :             :     {
    5733                 :       75310 :     case 64:
    5734                 :       75310 :       snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
    5735                 :             :                 opcode);
    5736                 :       75310 :       break;
    5737                 :       80140 :     case 32:
    5738                 :       80140 :       snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
    5739                 :             :                 opcode);
    5740                 :       80140 :       break;
    5741                 :     3466034 :     case 16:
    5742                 :     3466034 :       snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
    5743                 :             :                 opcode);
    5744                 :     3466034 :       break;
    5745                 :           0 :     default:
    5746                 :           0 :       gcc_unreachable ();
    5747                 :             :     }
    5748                 :     3621484 :   output_asm_insn (buf, operands);
    5749                 :     3621484 :   return "";
    5750                 :             : }
    5751                 :             : 
    5752                 :             : /* Return the template of the TYPE_SSEMOV instruction to move
    5753                 :             :    operands[1] into operands[0].  */
    5754                 :             : 
    5755                 :             : const char *
    5756                 :     6085310 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
    5757                 :             : {
    5758                 :     6085310 :   machine_mode mode = GET_MODE (operands[0]);
    5759                 :     6085310 :   if (get_attr_type (insn) != TYPE_SSEMOV
    5760                 :     6085310 :       || mode != GET_MODE (operands[1]))
    5761                 :           0 :     gcc_unreachable ();
    5762                 :             : 
    5763                 :     6085310 :   enum attr_mode insn_mode = get_attr_mode (insn);
    5764                 :             : 
    5765                 :     6085310 :   switch (insn_mode)
    5766                 :             :     {
    5767                 :       75310 :     case MODE_XI:
    5768                 :       75310 :     case MODE_V8DF:
    5769                 :       75310 :     case MODE_V16SF:
    5770                 :       75310 :       return ix86_get_ssemov (operands, 64, insn_mode, mode);
    5771                 :             : 
    5772                 :       80140 :     case MODE_OI:
    5773                 :       80140 :     case MODE_V4DF:
    5774                 :       80140 :     case MODE_V8SF:
    5775                 :       80140 :       return ix86_get_ssemov (operands, 32, insn_mode, mode);
    5776                 :             : 
    5777                 :     3466034 :     case MODE_TI:
    5778                 :     3466034 :     case MODE_V2DF:
    5779                 :     3466034 :     case MODE_V4SF:
    5780                 :     3466034 :       return ix86_get_ssemov (operands, 16, insn_mode, mode);
    5781                 :             : 
    5782                 :      727107 :     case MODE_DI:
    5783                 :             :       /* Handle broken assemblers that require movd instead of movq. */
    5784                 :      727107 :       if (GENERAL_REG_P (operands[0]))
    5785                 :             :         {
    5786                 :             :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5787                 :             :             return "%vmovq\t{%1, %q0|%q0, %1}";
    5788                 :             :           else
    5789                 :             :             return "%vmovd\t{%1, %q0|%q0, %1}";
    5790                 :             :         }
    5791                 :      653143 :       else if (GENERAL_REG_P (operands[1]))
    5792                 :             :         {
    5793                 :             :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5794                 :             :             return "%vmovq\t{%q1, %0|%0, %q1}";
    5795                 :             :           else
    5796                 :             :             return "%vmovd\t{%q1, %0|%0, %q1}";
    5797                 :             :         }
    5798                 :             :       else
    5799                 :      460950 :         return "%vmovq\t{%1, %0|%0, %1}";
    5800                 :             : 
    5801                 :      246817 :     case MODE_SI:
    5802                 :      246817 :       if (GENERAL_REG_P (operands[0]))
    5803                 :             :         return "%vmovd\t{%1, %k0|%k0, %1}";
    5804                 :      194069 :       else if (GENERAL_REG_P (operands[1]))
    5805                 :             :         return "%vmovd\t{%k1, %0|%0, %k1}";
    5806                 :             :       else
    5807                 :       82254 :         return "%vmovd\t{%1, %0|%0, %1}";
    5808                 :             : 
    5809                 :       49114 :     case MODE_HI:
    5810                 :       49114 :       if (GENERAL_REG_P (operands[0]))
    5811                 :             :         return "vmovw\t{%1, %k0|%k0, %1}";
    5812                 :       49088 :       else if (GENERAL_REG_P (operands[1]))
    5813                 :             :         return "vmovw\t{%k1, %0|%0, %k1}";
    5814                 :             :       else
    5815                 :       48985 :         return "vmovw\t{%1, %0|%0, %1}";
    5816                 :             : 
    5817                 :      774844 :     case MODE_DF:
    5818                 :      774844 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5819                 :             :         return "vmovsd\t{%d1, %0|%0, %d1}";
    5820                 :             :       else
    5821                 :      773849 :         return "%vmovsd\t{%1, %0|%0, %1}";
    5822                 :             : 
    5823                 :      662838 :     case MODE_SF:
    5824                 :      662838 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5825                 :             :         return "vmovss\t{%d1, %0|%0, %d1}";
    5826                 :             :       else
    5827                 :      662197 :         return "%vmovss\t{%1, %0|%0, %1}";
    5828                 :             : 
    5829                 :          52 :     case MODE_HF:
    5830                 :          52 :     case MODE_BF:
    5831                 :          52 :       if (REG_P (operands[0]) && REG_P (operands[1]))
    5832                 :             :         return "vmovsh\t{%d1, %0|%0, %d1}";
    5833                 :             :       else
    5834                 :           0 :         return "vmovsh\t{%1, %0|%0, %1}";
    5835                 :             : 
    5836                 :          33 :     case MODE_V1DF:
    5837                 :          33 :       gcc_assert (!TARGET_AVX);
    5838                 :             :       return "movlpd\t{%1, %0|%0, %1}";
    5839                 :             : 
    5840                 :        3021 :     case MODE_V2SF:
    5841                 :        3021 :       if (TARGET_AVX && REG_P (operands[0]))
    5842                 :             :         return "vmovlps\t{%1, %d0|%d0, %1}";
    5843                 :             :       else
    5844                 :        2935 :         return "%vmovlps\t{%1, %0|%0, %1}";
    5845                 :             : 
    5846                 :           0 :     default:
    5847                 :           0 :       gcc_unreachable ();
    5848                 :             :     }
    5849                 :             : }
    5850                 :             : 
    5851                 :             : /* Returns true if OP contains a symbol reference */
    5852                 :             : 
    5853                 :             : bool
    5854                 :   496587938 : symbolic_reference_mentioned_p (rtx op)
    5855                 :             : {
    5856                 :   496587938 :   const char *fmt;
    5857                 :   496587938 :   int i;
    5858                 :             : 
    5859                 :   496587938 :   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
    5860                 :             :     return true;
    5861                 :             : 
    5862                 :   375640127 :   fmt = GET_RTX_FORMAT (GET_CODE (op));
    5863                 :   638412656 :   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
    5864                 :             :     {
    5865                 :   509026372 :       if (fmt[i] == 'E')
    5866                 :             :         {
    5867                 :     1797015 :           int j;
    5868                 :             : 
    5869                 :     3630367 :           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
    5870                 :     2993934 :             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
    5871                 :             :               return true;
    5872                 :             :         }
    5873                 :             : 
    5874                 :   507229357 :       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
    5875                 :             :         return true;
    5876                 :             :     }
    5877                 :             : 
    5878                 :             :   return false;
    5879                 :             : }
    5880                 :             : 
    5881                 :             : /* Return true if it is appropriate to emit `ret' instructions in the
    5882                 :             :    body of a function.  Do this only if the epilogue is simple, needing a
    5883                 :             :    couple of insns.  Prior to reloading, we can't tell how many registers
    5884                 :             :    must be saved, so return false then.  Return false if there is no frame
    5885                 :             :    marker to de-allocate.  */
    5886                 :             : 
    5887                 :             : bool
    5888                 :           0 : ix86_can_use_return_insn_p (void)
    5889                 :             : {
    5890                 :           0 :   if (ix86_function_ms_hook_prologue (current_function_decl))
    5891                 :             :     return false;
    5892                 :             : 
    5893                 :           0 :   if (ix86_function_naked (current_function_decl))
    5894                 :             :     return false;
    5895                 :             : 
    5896                 :             :   /* Don't use `ret' instruction in interrupt handler.  */
    5897                 :           0 :   if (! reload_completed
    5898                 :           0 :       || frame_pointer_needed
    5899                 :           0 :       || cfun->machine->func_type != TYPE_NORMAL)
    5900                 :             :     return 0;
    5901                 :             : 
    5902                 :             :   /* Don't allow more than 32k pop, since that's all we can do
    5903                 :             :      with one instruction.  */
    5904                 :           0 :   if (crtl->args.pops_args && crtl->args.size >= 32768)
    5905                 :             :     return 0;
    5906                 :             : 
    5907                 :           0 :   struct ix86_frame &frame = cfun->machine->frame;
    5908                 :           0 :   return (frame.stack_pointer_offset == UNITS_PER_WORD
    5909                 :           0 :           && (frame.nregs + frame.nsseregs) == 0);
    5910                 :             : }
    5911                 :             : 
    5912                 :             : /* Return stack frame size.  get_frame_size () returns used stack slots
    5913                 :             :    during compilation, which may be optimized out later.  If stack frame
    5914                 :             :    is needed, stack_frame_required should be true.  */
    5915                 :             : 
    5916                 :             : static HOST_WIDE_INT
    5917                 :     7599095 : ix86_get_frame_size (void)
    5918                 :             : {
    5919                 :     7599095 :   if (cfun->machine->stack_frame_required)
    5920                 :     7541689 :     return get_frame_size ();
    5921                 :             :   else
    5922                 :             :     return 0;
    5923                 :             : }
    5924                 :             : 
    5925                 :             : /* Value should be nonzero if functions must have frame pointers.
    5926                 :             :    Zero means the frame pointer need not be set up (and parms may
    5927                 :             :    be accessed via the stack pointer) in functions that seem suitable.  */
    5928                 :             : 
    5929                 :             : static bool
    5930                 :     1098092 : ix86_frame_pointer_required (void)
    5931                 :             : {
    5932                 :             :   /* If we accessed previous frames, then the generated code expects
    5933                 :             :      to be able to access the saved ebp value in our frame.  */
    5934                 :     1098092 :   if (cfun->machine->accesses_prev_frame)
    5935                 :             :     return true;
    5936                 :             : 
    5937                 :             :   /* Several x86 os'es need a frame pointer for other reasons,
    5938                 :             :      usually pertaining to setjmp.  */
    5939                 :     1098059 :   if (SUBTARGET_FRAME_POINTER_REQUIRED)
    5940                 :             :     return true;
    5941                 :             : 
    5942                 :             :   /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
    5943                 :     1098059 :   if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
    5944                 :             :     return true;
    5945                 :             : 
    5946                 :             :   /* Win64 SEH, very large frames need a frame-pointer as maximum stack
    5947                 :             :      allocation is 4GB.  */
    5948                 :     1098059 :   if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
    5949                 :             :     return true;
    5950                 :             : 
    5951                 :             :   /* SSE saves require frame-pointer when stack is misaligned.  */
    5952                 :     1098059 :   if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
    5953                 :             :     return true;
    5954                 :             :   
    5955                 :             :   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
    5956                 :             :      turns off the frame pointer by default.  Turn it back on now if
    5957                 :             :      we've not got a leaf function.  */
    5958                 :     1098058 :   if (TARGET_OMIT_LEAF_FRAME_POINTER
    5959                 :     1098058 :       && (!crtl->is_leaf
    5960                 :           0 :           || ix86_current_function_calls_tls_descriptor))
    5961                 :           0 :     return true;
    5962                 :             : 
    5963                 :             :   /* Several versions of mcount for the x86 assumes that there is a
    5964                 :             :      frame, so we cannot allow profiling without a frame pointer.  */
    5965                 :     1098058 :   if (crtl->profile && !flag_fentry)
    5966                 :             :     return true;
    5967                 :             : 
    5968                 :             :   return false;
    5969                 :             : }
    5970                 :             : 
    5971                 :             : /* Record that the current function accesses previous call frames.  */
    5972                 :             : 
    5973                 :             : void
    5974                 :        1016 : ix86_setup_frame_addresses (void)
    5975                 :             : {
    5976                 :        1016 :   cfun->machine->accesses_prev_frame = 1;
    5977                 :        1016 : }
    5978                 :             : 
    5979                 :             : #ifndef USE_HIDDEN_LINKONCE
    5980                 :             : # if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
    5981                 :             : #  define USE_HIDDEN_LINKONCE 1
    5982                 :             : # else
    5983                 :             : #  define USE_HIDDEN_LINKONCE 0
    5984                 :             : # endif
    5985                 :             : #endif
    5986                 :             : 
    5987                 :             : /* Label count for call and return thunks.  It is used to make unique
    5988                 :             :    labels in call and return thunks.  */
    5989                 :             : static int indirectlabelno;
    5990                 :             : 
    5991                 :             : /* True if call thunk function is needed.  */
    5992                 :             : static bool indirect_thunk_needed = false;
    5993                 :             : 
    5994                 :             : /* Bit masks of integer registers, which contain branch target, used
    5995                 :             :    by call thunk functions.  */
    5996                 :             : static HARD_REG_SET indirect_thunks_used;
    5997                 :             : 
    5998                 :             : /* True if return thunk function is needed.  */
    5999                 :             : static bool indirect_return_needed = false;
    6000                 :             : 
    6001                 :             : /* True if return thunk function via CX is needed.  */
    6002                 :             : static bool indirect_return_via_cx;
    6003                 :             : 
    6004                 :             : #ifndef INDIRECT_LABEL
    6005                 :             : # define INDIRECT_LABEL "LIND"
    6006                 :             : #endif
    6007                 :             : 
    6008                 :             : /* Indicate what prefix is needed for an indirect branch.  */
    6009                 :             : enum indirect_thunk_prefix
    6010                 :             : {
    6011                 :             :   indirect_thunk_prefix_none,
    6012                 :             :   indirect_thunk_prefix_nt
    6013                 :             : };
    6014                 :             : 
    6015                 :             : /* Return the prefix needed for an indirect branch INSN.  */
    6016                 :             : 
    6017                 :             : enum indirect_thunk_prefix
    6018                 :          67 : indirect_thunk_need_prefix (rtx_insn *insn)
    6019                 :             : {
    6020                 :          67 :   enum indirect_thunk_prefix need_prefix;
    6021                 :          67 :   if ((cfun->machine->indirect_branch_type
    6022                 :          67 :             == indirect_branch_thunk_extern)
    6023                 :          67 :            && ix86_notrack_prefixed_insn_p (insn))
    6024                 :             :     {
    6025                 :             :       /* NOTRACK prefix is only used with external thunk so that it
    6026                 :             :          can be properly updated to support CET at run-time.  */
    6027                 :             :       need_prefix = indirect_thunk_prefix_nt;
    6028                 :             :     }
    6029                 :             :   else
    6030                 :             :     need_prefix = indirect_thunk_prefix_none;
    6031                 :          67 :   return need_prefix;
    6032                 :             : }
    6033                 :             : 
    6034                 :             : /* Fills in the label name that should be used for the indirect thunk.  */
    6035                 :             : 
    6036                 :             : static void
    6037                 :          73 : indirect_thunk_name (char name[32], unsigned int regno,
    6038                 :             :                      enum indirect_thunk_prefix need_prefix,
    6039                 :             :                      bool ret_p)
    6040                 :             : {
    6041                 :          73 :   if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
    6042                 :           0 :     gcc_unreachable ();
    6043                 :             : 
    6044                 :          73 :   if (USE_HIDDEN_LINKONCE)
    6045                 :             :     {
    6046                 :          73 :       const char *prefix;
    6047                 :             : 
    6048                 :          73 :       if (need_prefix == indirect_thunk_prefix_nt
    6049                 :          73 :           && regno != INVALID_REGNUM)
    6050                 :             :         {
    6051                 :             :           /* NOTRACK prefix is only used with external thunk via
    6052                 :             :              register so that NOTRACK prefix can be added to indirect
    6053                 :             :              branch via register to support CET at run-time.  */
    6054                 :             :           prefix = "_nt";
    6055                 :             :         }
    6056                 :             :       else
    6057                 :          71 :         prefix = "";
    6058                 :             : 
    6059                 :          73 :       const char *ret = ret_p ? "return" : "indirect";
    6060                 :             : 
    6061                 :          73 :       if (regno != INVALID_REGNUM)
    6062                 :             :         {
    6063                 :          55 :           const char *reg_prefix;
    6064                 :          55 :           if (LEGACY_INT_REGNO_P (regno))
    6065                 :          53 :             reg_prefix = TARGET_64BIT ? "r" : "e";
    6066                 :             :           else
    6067                 :             :             reg_prefix = "";
    6068                 :          55 :           sprintf (name, "__x86_%s_thunk%s_%s%s",
    6069                 :             :                    ret, prefix, reg_prefix, reg_names[regno]);
    6070                 :             :         }
    6071                 :             :       else
    6072                 :          18 :         sprintf (name, "__x86_%s_thunk%s", ret, prefix);
    6073                 :             :     }
    6074                 :             :   else
    6075                 :             :     {
    6076                 :             :       if (regno != INVALID_REGNUM)
    6077                 :             :         ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
    6078                 :             :       else
    6079                 :             :         {
    6080                 :             :           if (ret_p)
    6081                 :             :             ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
    6082                 :             :           else
    6083                 :          73 :             ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
    6084                 :             :         }
    6085                 :             :     }
    6086                 :          73 : }
    6087                 :             : 
    6088                 :             : /* Output a call and return thunk for indirect branch.  If REGNO != -1,
    6089                 :             :    the function address is in REGNO and the call and return thunk looks like:
    6090                 :             : 
    6091                 :             :         call    L2
    6092                 :             :    L1:
    6093                 :             :         pause
    6094                 :             :         lfence
    6095                 :             :         jmp     L1
    6096                 :             :    L2:
    6097                 :             :         mov     %REG, (%sp)
    6098                 :             :         ret
    6099                 :             : 
    6100                 :             :    Otherwise, the function address is on the top of stack and the
    6101                 :             :    call and return thunk looks like:
    6102                 :             : 
    6103                 :             :         call L2
    6104                 :             :   L1:
    6105                 :             :         pause
    6106                 :             :         lfence
    6107                 :             :         jmp L1
    6108                 :             :   L2:
    6109                 :             :         lea WORD_SIZE(%sp), %sp
    6110                 :             :         ret
    6111                 :             :  */
    6112                 :             : 
    6113                 :             : static void
    6114                 :          38 : output_indirect_thunk (unsigned int regno)
    6115                 :             : {
    6116                 :          38 :   char indirectlabel1[32];
    6117                 :          38 :   char indirectlabel2[32];
    6118                 :             : 
    6119                 :          38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
    6120                 :             :                                indirectlabelno++);
    6121                 :          38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
    6122                 :             :                                indirectlabelno++);
    6123                 :             : 
    6124                 :             :   /* Call */
    6125                 :          38 :   fputs ("\tcall\t", asm_out_file);
    6126                 :          38 :   assemble_name_raw (asm_out_file, indirectlabel2);
    6127                 :          38 :   fputc ('\n', asm_out_file);
    6128                 :             : 
    6129                 :          38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
    6130                 :             : 
    6131                 :             :   /* AMD and Intel CPUs prefer each a different instruction as loop filler.
    6132                 :             :      Usage of both pause + lfence is compromise solution.  */
    6133                 :          38 :   fprintf (asm_out_file, "\tpause\n\tlfence\n");
    6134                 :             : 
    6135                 :             :   /* Jump.  */
    6136                 :          38 :   fputs ("\tjmp\t", asm_out_file);
    6137                 :          38 :   assemble_name_raw (asm_out_file, indirectlabel1);
    6138                 :          38 :   fputc ('\n', asm_out_file);
    6139                 :             : 
    6140                 :          38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
    6141                 :             : 
    6142                 :             :   /* The above call insn pushed a word to stack.  Adjust CFI info.  */
    6143                 :          38 :   if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
    6144                 :             :     {
    6145                 :          38 :       if (! dwarf2out_do_cfi_asm ())
    6146                 :             :         {
    6147                 :           0 :           dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6148                 :           0 :           xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
    6149                 :           0 :           xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
    6150                 :           0 :           vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6151                 :             :         }
    6152                 :          38 :       dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6153                 :          38 :       xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
    6154                 :          38 :       xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
    6155                 :          38 :       vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6156                 :          38 :       dwarf2out_emit_cfi (xcfi);
    6157                 :             :     }
    6158                 :             : 
    6159                 :          38 :   if (regno != INVALID_REGNUM)
    6160                 :             :     {
    6161                 :             :       /* MOV.  */
    6162                 :          27 :       rtx xops[2];
    6163                 :          27 :       xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
    6164                 :          27 :       xops[1] = gen_rtx_REG (word_mode, regno);
    6165                 :          27 :       output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
    6166                 :             :     }
    6167                 :             :   else
    6168                 :             :     {
    6169                 :             :       /* LEA.  */
    6170                 :          11 :       rtx xops[2];
    6171                 :          11 :       xops[0] = stack_pointer_rtx;
    6172                 :          11 :       xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    6173                 :          11 :       output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
    6174                 :             :     }
    6175                 :             : 
    6176                 :          38 :   fputs ("\tret\n", asm_out_file);
    6177                 :          38 :   if ((ix86_harden_sls & harden_sls_return))
    6178                 :           1 :     fputs ("\tint3\n", asm_out_file);
    6179                 :          38 : }
    6180                 :             : 
    6181                 :             : /* Output a funtion with a call and return thunk for indirect branch.
    6182                 :             :    If REGNO != INVALID_REGNUM, the function address is in REGNO.
    6183                 :             :    Otherwise, the function address is on the top of stack.  Thunk is
    6184                 :             :    used for function return if RET_P is true.  */
    6185                 :             : 
    6186                 :             : static void
    6187                 :          22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
    6188                 :             :                                 unsigned int regno, bool ret_p)
    6189                 :             : {
    6190                 :          22 :   char name[32];
    6191                 :          22 :   tree decl;
    6192                 :             : 
    6193                 :             :   /* Create __x86_indirect_thunk.  */
    6194                 :          22 :   indirect_thunk_name (name, regno, need_prefix, ret_p);
    6195                 :          22 :   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6196                 :             :                      get_identifier (name),
    6197                 :             :                      build_function_type_list (void_type_node, NULL_TREE));
    6198                 :          22 :   DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6199                 :             :                                    NULL_TREE, void_type_node);
    6200                 :          22 :   TREE_PUBLIC (decl) = 1;
    6201                 :          22 :   TREE_STATIC (decl) = 1;
    6202                 :          22 :   DECL_IGNORED_P (decl) = 1;
    6203                 :             : 
    6204                 :             : #if TARGET_MACHO
    6205                 :             :   if (TARGET_MACHO)
    6206                 :             :     {
    6207                 :             :       switch_to_section (darwin_sections[picbase_thunk_section]);
    6208                 :             :       fputs ("\t.weak_definition\t", asm_out_file);
    6209                 :             :       assemble_name (asm_out_file, name);
    6210                 :             :       fputs ("\n\t.private_extern\t", asm_out_file);
    6211                 :             :       assemble_name (asm_out_file, name);
    6212                 :             :       putc ('\n', asm_out_file);
    6213                 :             :       ASM_OUTPUT_LABEL (asm_out_file, name);
    6214                 :             :       DECL_WEAK (decl) = 1;
    6215                 :             :     }
    6216                 :             :   else
    6217                 :             : #endif
    6218                 :          22 :     if (USE_HIDDEN_LINKONCE)
    6219                 :             :       {
    6220                 :          22 :         cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6221                 :             : 
    6222                 :          22 :         targetm.asm_out.unique_section (decl, 0);
    6223                 :          22 :         switch_to_section (get_named_section (decl, NULL, 0));
    6224                 :             : 
    6225                 :          22 :         targetm.asm_out.globalize_label (asm_out_file, name);
    6226                 :          22 :         fputs ("\t.hidden\t", asm_out_file);
    6227                 :          22 :         assemble_name (asm_out_file, name);
    6228                 :          22 :         putc ('\n', asm_out_file);
    6229                 :          22 :         ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6230                 :             :       }
    6231                 :             :     else
    6232                 :             :       {
    6233                 :             :         switch_to_section (text_section);
    6234                 :          22 :         ASM_OUTPUT_LABEL (asm_out_file, name);
    6235                 :             :       }
    6236                 :             : 
    6237                 :          22 :   DECL_INITIAL (decl) = make_node (BLOCK);
    6238                 :          22 :   current_function_decl = decl;
    6239                 :          22 :   allocate_struct_function (decl, false);
    6240                 :          22 :   init_function_start (decl);
    6241                 :             :   /* We're about to hide the function body from callees of final_* by
    6242                 :             :      emitting it directly; tell them we're a thunk, if they care.  */
    6243                 :          22 :   cfun->is_thunk = true;
    6244                 :          22 :   first_function_block_is_cold = false;
    6245                 :             :   /* Make sure unwind info is emitted for the thunk if needed.  */
    6246                 :          22 :   final_start_function (emit_barrier (), asm_out_file, 1);
    6247                 :             : 
    6248                 :          22 :   output_indirect_thunk (regno);
    6249                 :             : 
    6250                 :          22 :   final_end_function ();
    6251                 :          22 :   init_insn_lengths ();
    6252                 :          22 :   free_after_compilation (cfun);
    6253                 :          22 :   set_cfun (NULL);
    6254                 :          22 :   current_function_decl = NULL;
    6255                 :          22 : }
    6256                 :             : 
    6257                 :             : static int pic_labels_used;
    6258                 :             : 
    6259                 :             : /* Fills in the label name that should be used for a pc thunk for
    6260                 :             :    the given register.  */
    6261                 :             : 
    6262                 :             : static void
    6263                 :       35633 : get_pc_thunk_name (char name[32], unsigned int regno)
    6264                 :             : {
    6265                 :       35633 :   gcc_assert (!TARGET_64BIT);
    6266                 :             : 
    6267                 :       35633 :   if (USE_HIDDEN_LINKONCE)
    6268                 :       35633 :     sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
    6269                 :             :   else
    6270                 :       35633 :     ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
    6271                 :       35633 : }
    6272                 :             : 
    6273                 :             : 
    6274                 :             : /* This function generates code for -fpic that loads %ebx with
    6275                 :             :    the return address of the caller and then returns.  */
    6276                 :             : 
    6277                 :             : static void
    6278                 :      224703 : ix86_code_end (void)
    6279                 :             : {
    6280                 :      224703 :   rtx xops[2];
    6281                 :      224703 :   unsigned int regno;
    6282                 :             : 
    6283                 :      224703 :   if (indirect_return_needed)
    6284                 :           6 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6285                 :             :                                     INVALID_REGNUM, true);
    6286                 :      224703 :   if (indirect_return_via_cx)
    6287                 :           0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6288                 :             :                                     CX_REG, true);
    6289                 :      224703 :   if (indirect_thunk_needed)
    6290                 :           0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6291                 :             :                                     INVALID_REGNUM, false);
    6292                 :             : 
    6293                 :     2022327 :   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
    6294                 :             :     {
    6295                 :     1797624 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6296                 :           0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6297                 :             :                                         regno, false);
    6298                 :             :     }
    6299                 :             : 
    6300                 :     3819951 :   for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
    6301                 :             :     {
    6302                 :     3595248 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6303                 :           0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6304                 :             :                                         regno, false);
    6305                 :             :     }
    6306                 :             : 
    6307                 :     2022327 :   for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
    6308                 :             :     {
    6309                 :     1797624 :       char name[32];
    6310                 :     1797624 :       tree decl;
    6311                 :             : 
    6312                 :     1797624 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6313                 :          16 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6314                 :             :                                         regno, false);
    6315                 :             : 
    6316                 :     1797624 :       if (!(pic_labels_used & (1 << regno)))
    6317                 :     1793986 :         continue;
    6318                 :             : 
    6319                 :        3638 :       get_pc_thunk_name (name, regno);
    6320                 :             : 
    6321                 :        3638 :       decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6322                 :             :                          get_identifier (name),
    6323                 :             :                          build_function_type_list (void_type_node, NULL_TREE));
    6324                 :        3638 :       DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6325                 :             :                                        NULL_TREE, void_type_node);
    6326                 :        3638 :       TREE_PUBLIC (decl) = 1;
    6327                 :        3638 :       TREE_STATIC (decl) = 1;
    6328                 :        3638 :       DECL_IGNORED_P (decl) = 1;
    6329                 :             : 
    6330                 :             : #if TARGET_MACHO
    6331                 :             :       if (TARGET_MACHO)
    6332                 :             :         {
    6333                 :             :           switch_to_section (darwin_sections[picbase_thunk_section]);
    6334                 :             :           fputs ("\t.weak_definition\t", asm_out_file);
    6335                 :             :           assemble_name (asm_out_file, name);
    6336                 :             :           fputs ("\n\t.private_extern\t", asm_out_file);
    6337                 :             :           assemble_name (asm_out_file, name);
    6338                 :             :           putc ('\n', asm_out_file);
    6339                 :             :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6340                 :             :           DECL_WEAK (decl) = 1;
    6341                 :             :         }
    6342                 :             :       else
    6343                 :             : #endif
    6344                 :        3638 :       if (USE_HIDDEN_LINKONCE)
    6345                 :             :         {
    6346                 :        3638 :           cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6347                 :             : 
    6348                 :        3638 :           targetm.asm_out.unique_section (decl, 0);
    6349                 :        3638 :           switch_to_section (get_named_section (decl, NULL, 0));
    6350                 :             : 
    6351                 :        3638 :           targetm.asm_out.globalize_label (asm_out_file, name);
    6352                 :        3638 :           fputs ("\t.hidden\t", asm_out_file);
    6353                 :        3638 :           assemble_name (asm_out_file, name);
    6354                 :        3638 :           putc ('\n', asm_out_file);
    6355                 :        3638 :           ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6356                 :             :         }
    6357                 :             :       else
    6358                 :             :         {
    6359                 :             :           switch_to_section (text_section);
    6360                 :        3638 :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6361                 :             :         }
    6362                 :             : 
    6363                 :        3638 :       DECL_INITIAL (decl) = make_node (BLOCK);
    6364                 :        3638 :       current_function_decl = decl;
    6365                 :        3638 :       allocate_struct_function (decl, false);
    6366                 :        3638 :       init_function_start (decl);
    6367                 :             :       /* We're about to hide the function body from callees of final_* by
    6368                 :             :          emitting it directly; tell them we're a thunk, if they care.  */
    6369                 :        3638 :       cfun->is_thunk = true;
    6370                 :        3638 :       first_function_block_is_cold = false;
    6371                 :             :       /* Make sure unwind info is emitted for the thunk if needed.  */
    6372                 :        3638 :       final_start_function (emit_barrier (), asm_out_file, 1);
    6373                 :             : 
    6374                 :             :       /* Pad stack IP move with 4 instructions (two NOPs count
    6375                 :             :          as one instruction).  */
    6376                 :        3638 :       if (TARGET_PAD_SHORT_FUNCTION)
    6377                 :             :         {
    6378                 :             :           int i = 8;
    6379                 :             : 
    6380                 :           0 :           while (i--)
    6381                 :           0 :             fputs ("\tnop\n", asm_out_file);
    6382                 :             :         }
    6383                 :             : 
    6384                 :        3638 :       xops[0] = gen_rtx_REG (Pmode, regno);
    6385                 :        3638 :       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
    6386                 :        3638 :       output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
    6387                 :        3638 :       fputs ("\tret\n", asm_out_file);
    6388                 :        3638 :       final_end_function ();
    6389                 :        3638 :       init_insn_lengths ();
    6390                 :        3638 :       free_after_compilation (cfun);
    6391                 :        3638 :       set_cfun (NULL);
    6392                 :        3638 :       current_function_decl = NULL;
    6393                 :             :     }
    6394                 :             : 
    6395                 :      224703 :   if (flag_split_stack)
    6396                 :        4706 :     file_end_indicate_split_stack ();
    6397                 :      224703 : }
    6398                 :             : 
    6399                 :             : /* Emit code for the SET_GOT patterns.  */
    6400                 :             : 
    6401                 :             : const char *
    6402                 :       31995 : output_set_got (rtx dest, rtx label)
    6403                 :             : {
    6404                 :       31995 :   rtx xops[3];
    6405                 :             : 
    6406                 :       31995 :   xops[0] = dest;
    6407                 :             : 
    6408                 :       31995 :   if (TARGET_VXWORKS_RTP && flag_pic)
    6409                 :             :     {
    6410                 :             :       /* Load (*VXWORKS_GOTT_BASE) into the PIC register.  */
    6411                 :             :       xops[2] = gen_rtx_MEM (Pmode,
    6412                 :             :                              gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
    6413                 :             :       output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
    6414                 :             : 
    6415                 :             :       /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
    6416                 :             :          Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
    6417                 :             :          an unadorned address.  */
    6418                 :             :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
    6419                 :             :       SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
    6420                 :             :       output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
    6421                 :             :       return "";
    6422                 :             :     }
    6423                 :             : 
    6424                 :       31995 :   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
    6425                 :             : 
    6426                 :       31995 :   if (flag_pic)
    6427                 :             :     {
    6428                 :       31995 :       char name[32];
    6429                 :       31995 :       get_pc_thunk_name (name, REGNO (dest));
    6430                 :       31995 :       pic_labels_used |= 1 << REGNO (dest);
    6431                 :             : 
    6432                 :       31995 :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
    6433                 :       31995 :       xops[2] = gen_rtx_MEM (QImode, xops[2]);
    6434                 :       31995 :       output_asm_insn ("%!call\t%X2", xops);
    6435                 :             : 
    6436                 :             : #if TARGET_MACHO
    6437                 :             :       /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
    6438                 :             :          This is what will be referenced by the Mach-O PIC subsystem.  */
    6439                 :             :       if (machopic_should_output_picbase_label () || !label)
    6440                 :             :         ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
    6441                 :             : 
    6442                 :             :       /* When we are restoring the pic base at the site of a nonlocal label,
    6443                 :             :          and we decided to emit the pic base above, we will still output a
    6444                 :             :          local label used for calculating the correction offset (even though
    6445                 :             :          the offset will be 0 in that case).  */
    6446                 :             :       if (label)
    6447                 :             :         targetm.asm_out.internal_label (asm_out_file, "L",
    6448                 :             :                                            CODE_LABEL_NUMBER (label));
    6449                 :             : #endif
    6450                 :             :     }
    6451                 :             :   else
    6452                 :             :     {
    6453                 :           0 :       if (TARGET_MACHO)
    6454                 :             :         /* We don't need a pic base, we're not producing pic.  */
    6455                 :             :         gcc_unreachable ();
    6456                 :             : 
    6457                 :           0 :       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
    6458                 :           0 :       output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
    6459                 :           0 :       targetm.asm_out.internal_label (asm_out_file, "L",
    6460                 :           0 :                                       CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
    6461                 :             :     }
    6462                 :             : 
    6463                 :       31995 :   if (!TARGET_MACHO)
    6464                 :       31995 :     output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
    6465                 :             : 
    6466                 :       31995 :   return "";
    6467                 :             : }
    6468                 :             : 
    6469                 :             : /* Generate an "push" pattern for input ARG.  */
    6470                 :             : 
    6471                 :             : rtx
    6472                 :     1921989 : gen_push (rtx arg, bool ppx_p)
    6473                 :             : {
    6474                 :     1921989 :   struct machine_function *m = cfun->machine;
    6475                 :             : 
    6476                 :     1921989 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6477                 :     1675378 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6478                 :     1921989 :   m->fs.sp_offset += UNITS_PER_WORD;
    6479                 :             : 
    6480                 :     1921989 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6481                 :          25 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6482                 :             : 
    6483                 :     1921989 :   rtx stack = gen_rtx_MEM (word_mode,
    6484                 :     1921989 :                            gen_rtx_PRE_DEC (Pmode,
    6485                 :             :                                             stack_pointer_rtx));
    6486                 :     3843969 :   return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
    6487                 :             : }
    6488                 :             : 
    6489                 :             : rtx
    6490                 :          23 : gen_pushfl (void)
    6491                 :             : {
    6492                 :          23 :   struct machine_function *m = cfun->machine;
    6493                 :          23 :   rtx flags, mem;
    6494                 :             : 
    6495                 :          23 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6496                 :           0 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6497                 :          23 :   m->fs.sp_offset += UNITS_PER_WORD;
    6498                 :             : 
    6499                 :          23 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6500                 :             : 
    6501                 :          23 :   mem = gen_rtx_MEM (word_mode,
    6502                 :          23 :                      gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
    6503                 :             : 
    6504                 :          23 :   return gen_pushfl2 (word_mode, mem, flags);
    6505                 :             : }
    6506                 :             : 
    6507                 :             : /* Generate an "pop" pattern for input ARG.  */
    6508                 :             : 
    6509                 :             : rtx
    6510                 :     1564820 : gen_pop (rtx arg, bool ppx_p)
    6511                 :             : {
    6512                 :     1564820 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6513                 :          20 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6514                 :             : 
    6515                 :     1564820 :   rtx stack = gen_rtx_MEM (word_mode,
    6516                 :     1564820 :                            gen_rtx_POST_INC (Pmode,
    6517                 :             :                                              stack_pointer_rtx));
    6518                 :             : 
    6519                 :     3129631 :   return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
    6520                 :             : }
    6521                 :             : 
    6522                 :             : rtx
    6523                 :          21 : gen_popfl (void)
    6524                 :             : {
    6525                 :          21 :   rtx flags, mem;
    6526                 :             : 
    6527                 :          21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6528                 :             : 
    6529                 :          21 :   mem = gen_rtx_MEM (word_mode,
    6530                 :          21 :                      gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
    6531                 :             : 
    6532                 :          21 :   return gen_popfl1 (word_mode, flags, mem);
    6533                 :             : }
    6534                 :             : 
    6535                 :             : /* Generate a "push2" pattern for input ARG.  */
    6536                 :             : rtx
    6537                 :          15 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
    6538                 :             : {
    6539                 :          15 :   struct machine_function *m = cfun->machine;
    6540                 :          15 :   const int offset = UNITS_PER_WORD * 2;
    6541                 :             : 
    6542                 :          15 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6543                 :          10 :     m->fs.cfa_offset += offset;
    6544                 :          15 :   m->fs.sp_offset += offset;
    6545                 :             : 
    6546                 :          15 :   if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
    6547                 :           0 :     reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
    6548                 :             : 
    6549                 :          15 :   if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
    6550                 :           0 :     reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
    6551                 :             : 
    6552                 :          15 :   return ppx_p ? gen_push2p_di (mem, reg1, reg2):
    6553                 :           4 :                  gen_push2_di (mem, reg1, reg2);
    6554                 :             : }
    6555                 :             : 
    6556                 :             : /* Return >= 0 if there is an unused call-clobbered register available
    6557                 :             :    for the entire function.  */
    6558                 :             : 
    6559                 :             : static unsigned int
    6560                 :           0 : ix86_select_alt_pic_regnum (void)
    6561                 :             : {
    6562                 :           0 :   if (ix86_use_pseudo_pic_reg ())
    6563                 :             :     return INVALID_REGNUM;
    6564                 :             : 
    6565                 :           0 :   if (crtl->is_leaf
    6566                 :           0 :       && !crtl->profile
    6567                 :           0 :       && !ix86_current_function_calls_tls_descriptor)
    6568                 :             :     {
    6569                 :           0 :       int i, drap;
    6570                 :             :       /* Can't use the same register for both PIC and DRAP.  */
    6571                 :           0 :       if (crtl->drap_reg)
    6572                 :           0 :         drap = REGNO (crtl->drap_reg);
    6573                 :             :       else
    6574                 :             :         drap = -1;
    6575                 :           0 :       for (i = 2; i >= 0; --i)
    6576                 :           0 :         if (i != drap && !df_regs_ever_live_p (i))
    6577                 :           0 :           return i;
    6578                 :             :     }
    6579                 :             : 
    6580                 :             :   return INVALID_REGNUM;
    6581                 :             : }
    6582                 :             : 
    6583                 :             : /* Return true if REGNO is used by the epilogue.  */
    6584                 :             : 
    6585                 :             : bool
    6586                 :  1414707039 : ix86_epilogue_uses (int regno)
    6587                 :             : {
    6588                 :             :   /* If there are no caller-saved registers, we preserve all registers,
    6589                 :             :      except for MMX and x87 registers which aren't supported when saving
    6590                 :             :      and restoring registers.  Don't explicitly save SP register since
    6591                 :             :      it is always preserved.  */
    6592                 :  1414707039 :   return (epilogue_completed
    6593                 :   247375365 :           && (cfun->machine->call_saved_registers
    6594                 :   247375365 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    6595                 :       24840 :           && !fixed_regs[regno]
    6596                 :        4114 :           && !STACK_REGNO_P (regno)
    6597                 :  1414711153 :           && !MMX_REGNO_P (regno));
    6598                 :             : }
    6599                 :             : 
    6600                 :             : /* Return nonzero if register REGNO can be used as a scratch register
    6601                 :             :    in peephole2.  */
    6602                 :             : 
    6603                 :             : static bool
    6604                 :     1099042 : ix86_hard_regno_scratch_ok (unsigned int regno)
    6605                 :             : {
    6606                 :             :   /* If there are no caller-saved registers, we can't use any register
    6607                 :             :      as a scratch register after epilogue and use REGNO as scratch
    6608                 :             :      register only if it has been used before to avoid saving and
    6609                 :             :      restoring it.  */
    6610                 :     1099042 :   return ((cfun->machine->call_saved_registers
    6611                 :     1099042 :            != TYPE_NO_CALLER_SAVED_REGISTERS)
    6612                 :     1099042 :           || (!epilogue_completed
    6613                 :           0 :               && df_regs_ever_live_p (regno)));
    6614                 :             : }
    6615                 :             : 
    6616                 :             : /* Return TRUE if we need to save REGNO.  */
    6617                 :             : 
    6618                 :             : bool
    6619                 :   306145118 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
    6620                 :             : {
    6621                 :   306145118 :   rtx reg;
    6622                 :             : 
    6623                 :   306145118 :   switch (cfun->machine->call_saved_registers)
    6624                 :             :     {
    6625                 :             :     case TYPE_DEFAULT_CALL_SAVED_REGISTERS:
    6626                 :             :       break;
    6627                 :             : 
    6628                 :       30432 :     case TYPE_NO_CALLER_SAVED_REGISTERS:
    6629                 :             :       /* If there are no caller-saved registers, we preserve all
    6630                 :             :          registers, except for MMX and x87 registers which aren't
    6631                 :             :          supported when saving and restoring registers.  Don't
    6632                 :             :          explicitly save SP register since it is always preserved.
    6633                 :             : 
    6634                 :             :          Don't preserve registers used for function return value.  */
    6635                 :       30432 :       reg = crtl->return_rtx;
    6636                 :       30432 :       if (reg)
    6637                 :             :         {
    6638                 :         448 :           unsigned int i = REGNO (reg);
    6639                 :         448 :           unsigned int nregs = REG_NREGS (reg);
    6640                 :         882 :           while (nregs-- > 0)
    6641                 :         448 :             if ((i + nregs) == regno)
    6642                 :             :               return false;
    6643                 :             :         }
    6644                 :             : 
    6645                 :       30418 :       return (df_regs_ever_live_p (regno)
    6646                 :        4875 :               && !fixed_regs[regno]
    6647                 :        3993 :               && !STACK_REGNO_P (regno)
    6648                 :        3993 :               && !MMX_REGNO_P (regno)
    6649                 :       34411 :               && (regno != HARD_FRAME_POINTER_REGNUM
    6650                 :         236 :                   || !frame_pointer_needed));
    6651                 :             : 
    6652                 :             :     case TYPE_NO_CALLEE_SAVED_REGISTERS:
    6653                 :             :       return false;
    6654                 :             : 
    6655                 :        1664 :     case TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP:
    6656                 :        1664 :       if (regno != HARD_FRAME_POINTER_REGNUM)
    6657                 :             :         return false;
    6658                 :             :       break;
    6659                 :             :     }
    6660                 :             : 
    6661                 :   337421842 :   if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
    6662                 :     9276990 :       && pic_offset_table_rtx)
    6663                 :             :     {
    6664                 :      325590 :       if (ix86_use_pseudo_pic_reg ())
    6665                 :             :         {
    6666                 :             :           /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
    6667                 :             :           _mcount in prologue.  */
    6668                 :      325590 :           if (!TARGET_64BIT && flag_pic && crtl->profile)
    6669                 :             :             return true;
    6670                 :             :         }
    6671                 :           0 :       else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
    6672                 :           0 :                || crtl->profile
    6673                 :           0 :                || crtl->calls_eh_return
    6674                 :           0 :                || crtl->uses_const_pool
    6675                 :           0 :                || cfun->has_nonlocal_label)
    6676                 :           0 :         return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
    6677                 :             :     }
    6678                 :             : 
    6679                 :   306107506 :   if (crtl->calls_eh_return && maybe_eh_return)
    6680                 :             :     {
    6681                 :             :       unsigned i;
    6682                 :       13908 :       for (i = 0; ; i++)
    6683                 :             :         {
    6684                 :       21204 :           unsigned test = EH_RETURN_DATA_REGNO (i);
    6685                 :       14364 :           if (test == INVALID_REGNUM)
    6686                 :             :             break;
    6687                 :       14364 :           if (test == regno)
    6688                 :             :             return true;
    6689                 :       13908 :         }
    6690                 :             :     }
    6691                 :             : 
    6692                 :   306107050 :   if (ignore_outlined && cfun->machine->call_ms2sysv)
    6693                 :             :     {
    6694                 :     2637504 :       unsigned count = cfun->machine->call_ms2sysv_extra_regs
    6695                 :             :                        + xlogue_layout::MIN_REGS;
    6696                 :     2637504 :       if (xlogue_layout::is_stub_managed_reg (regno, count))
    6697                 :             :         return false;
    6698                 :             :     }
    6699                 :             : 
    6700                 :   305594337 :   if (crtl->drap_reg
    6701                 :     2111232 :       && regno == REGNO (crtl->drap_reg)
    6702                 :   305647442 :       && !cfun->machine->no_drap_save_restore)
    6703                 :             :     return true;
    6704                 :             : 
    6705                 :   305541232 :   return (df_regs_ever_live_p (regno)
    6706                 :   322585361 :           && !call_used_or_fixed_reg_p (regno)
    6707                 :   321981475 :           && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
    6708                 :             : }
    6709                 :             : 
    6710                 :             : /* Return number of saved general prupose registers.  */
    6711                 :             : 
    6712                 :             : static int
    6713                 :     7532232 : ix86_nsaved_regs (void)
    6714                 :             : {
    6715                 :     7532232 :   int nregs = 0;
    6716                 :     7532232 :   int regno;
    6717                 :             : 
    6718                 :   700497576 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6719                 :   692965344 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6720                 :     8367594 :       nregs ++;
    6721                 :     7532232 :   return nregs;
    6722                 :             : }
    6723                 :             : 
    6724                 :             : /* Return number of saved SSE registers.  */
    6725                 :             : 
    6726                 :             : static int
    6727                 :     7561147 : ix86_nsaved_sseregs (void)
    6728                 :             : {
    6729                 :     7561147 :   int nregs = 0;
    6730                 :     7561147 :   int regno;
    6731                 :             : 
    6732                 :     7561147 :   if (!TARGET_64BIT_MS_ABI)
    6733                 :     7338797 :     return 0;
    6734                 :    20678550 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6735                 :    20456200 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6736                 :     1865439 :       nregs ++;
    6737                 :             :   return nregs;
    6738                 :             : }
    6739                 :             : 
    6740                 :             : /* Given FROM and TO register numbers, say whether this elimination is
    6741                 :             :    allowed.  If stack alignment is needed, we can only replace argument
    6742                 :             :    pointer with hard frame pointer, or replace frame pointer with stack
    6743                 :             :    pointer.  Otherwise, frame pointer elimination is automatically
    6744                 :             :    handled and all other eliminations are valid.  */
    6745                 :             : 
    6746                 :             : static bool
    6747                 :    44864538 : ix86_can_eliminate (const int from, const int to)
    6748                 :             : {
    6749                 :    44864538 :   if (stack_realign_fp)
    6750                 :     1484176 :     return ((from == ARG_POINTER_REGNUM
    6751                 :     1484176 :              && to == HARD_FRAME_POINTER_REGNUM)
    6752                 :     1484176 :             || (from == FRAME_POINTER_REGNUM
    6753                 :     1484176 :                 && to == STACK_POINTER_REGNUM));
    6754                 :             :   else
    6755                 :    80506052 :     return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
    6756                 :             : }
    6757                 :             : 
    6758                 :             : /* Return the offset between two registers, one to be eliminated, and the other
    6759                 :             :    its replacement, at the start of a routine.  */
    6760                 :             : 
    6761                 :             : HOST_WIDE_INT
    6762                 :   139376585 : ix86_initial_elimination_offset (int from, int to)
    6763                 :             : {
    6764                 :   139376585 :   struct ix86_frame &frame = cfun->machine->frame;
    6765                 :             : 
    6766                 :   139376585 :   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    6767                 :     9682638 :     return frame.hard_frame_pointer_offset;
    6768                 :   129693947 :   else if (from == FRAME_POINTER_REGNUM
    6769                 :   129693947 :            && to == HARD_FRAME_POINTER_REGNUM)
    6770                 :     7503054 :     return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
    6771                 :             :   else
    6772                 :             :     {
    6773                 :   122190893 :       gcc_assert (to == STACK_POINTER_REGNUM);
    6774                 :             : 
    6775                 :   122190893 :       if (from == ARG_POINTER_REGNUM)
    6776                 :   114687839 :         return frame.stack_pointer_offset;
    6777                 :             : 
    6778                 :     7503054 :       gcc_assert (from == FRAME_POINTER_REGNUM);
    6779                 :     7503054 :       return frame.stack_pointer_offset - frame.frame_pointer_offset;
    6780                 :             :     }
    6781                 :             : }
    6782                 :             : 
    6783                 :             : /* Emits a warning for unsupported msabi to sysv pro/epilogues.  */
    6784                 :             : void
    6785                 :           0 : warn_once_call_ms2sysv_xlogues (const char *feature)
    6786                 :             : {
    6787                 :           0 :   static bool warned_once = false;
    6788                 :           0 :   if (!warned_once)
    6789                 :             :     {
    6790                 :           0 :       warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
    6791                 :             :                feature);
    6792                 :           0 :       warned_once = true;
    6793                 :             :     }
    6794                 :           0 : }
    6795                 :             : 
    6796                 :             : /* Return the probing interval for -fstack-clash-protection.  */
    6797                 :             : 
    6798                 :             : static HOST_WIDE_INT
    6799                 :         350 : get_probe_interval (void)
    6800                 :             : {
    6801                 :         218 :   if (flag_stack_clash_protection)
    6802                 :         265 :     return (HOST_WIDE_INT_1U
    6803                 :         265 :             << param_stack_clash_protection_probe_interval);
    6804                 :             :   else
    6805                 :             :     return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
    6806                 :             : }
    6807                 :             : 
    6808                 :             : /* When using -fsplit-stack, the allocation routines set a field in
    6809                 :             :    the TCB to the bottom of the stack plus this much space, measured
    6810                 :             :    in bytes.  */
    6811                 :             : 
    6812                 :             : #define SPLIT_STACK_AVAILABLE 256
    6813                 :             : 
    6814                 :             : /* Return true if push2/pop2 can be generated.  */
    6815                 :             : 
    6816                 :             : static bool
    6817                 :     7532642 : ix86_can_use_push2pop2 (void)
    6818                 :             : {
    6819                 :             :   /* Use push2/pop2 only if the incoming stack is 16-byte aligned.  */
    6820                 :     7532642 :   unsigned int incoming_stack_boundary
    6821                 :     7532642 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    6822                 :     7532642 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    6823                 :     7532642 :   return incoming_stack_boundary % 128 == 0;
    6824                 :             : }
    6825                 :             : 
    6826                 :             : /* Helper function to determine whether push2/pop2 can be used in prologue or
    6827                 :             :    epilogue for register save/restore.  */
    6828                 :             : static bool
    6829                 :     7532232 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
    6830                 :             : {
    6831                 :     7532232 :   if (!ix86_can_use_push2pop2 ())
    6832                 :             :     return false;
    6833                 :     7496433 :   int aligned = cfun->machine->fs.sp_offset % 16 == 0;
    6834                 :     7496433 :   return TARGET_APX_PUSH2POP2
    6835                 :        2015 :          && !cfun->machine->frame.save_regs_using_mov
    6836                 :        2015 :          && cfun->machine->func_type == TYPE_NORMAL
    6837                 :     7498440 :          && (nregs + aligned) >= 3;
    6838                 :             : }
    6839                 :             : 
    6840                 :             : /* Fill structure ix86_frame about frame of currently computed function.  */
    6841                 :             : 
    6842                 :             : static void
    6843                 :     7532232 : ix86_compute_frame_layout (void)
    6844                 :             : {
    6845                 :     7532232 :   struct ix86_frame *frame = &cfun->machine->frame;
    6846                 :     7532232 :   struct machine_function *m = cfun->machine;
    6847                 :     7532232 :   unsigned HOST_WIDE_INT stack_alignment_needed;
    6848                 :     7532232 :   HOST_WIDE_INT offset;
    6849                 :     7532232 :   unsigned HOST_WIDE_INT preferred_alignment;
    6850                 :     7532232 :   HOST_WIDE_INT size = ix86_get_frame_size ();
    6851                 :     7532232 :   HOST_WIDE_INT to_allocate;
    6852                 :             : 
    6853                 :             :   /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
    6854                 :             :    * ms_abi functions that call a sysv function.  We now need to prune away
    6855                 :             :    * cases where it should be disabled.  */
    6856                 :     7532232 :   if (TARGET_64BIT && m->call_ms2sysv)
    6857                 :             :     {
    6858                 :       35231 :       gcc_assert (TARGET_64BIT_MS_ABI);
    6859                 :       35231 :       gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
    6860                 :       35231 :       gcc_assert (!TARGET_SEH);
    6861                 :       35231 :       gcc_assert (TARGET_SSE);
    6862                 :       35231 :       gcc_assert (!ix86_using_red_zone ());
    6863                 :             : 
    6864                 :       35231 :       if (crtl->calls_eh_return)
    6865                 :             :         {
    6866                 :           0 :           gcc_assert (!reload_completed);
    6867                 :           0 :           m->call_ms2sysv = false;
    6868                 :           0 :           warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
    6869                 :             :         }
    6870                 :             : 
    6871                 :       35231 :       else if (ix86_static_chain_on_stack)
    6872                 :             :         {
    6873                 :           0 :           gcc_assert (!reload_completed);
    6874                 :           0 :           m->call_ms2sysv = false;
    6875                 :           0 :           warn_once_call_ms2sysv_xlogues ("static call chains");
    6876                 :             :         }
    6877                 :             : 
    6878                 :             :       /* Finally, compute which registers the stub will manage.  */
    6879                 :             :       else
    6880                 :             :         {
    6881                 :       35231 :           unsigned count = xlogue_layout::count_stub_managed_regs ();
    6882                 :       35231 :           m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
    6883                 :       35231 :           m->call_ms2sysv_pad_in = 0;
    6884                 :             :         }
    6885                 :             :     }
    6886                 :             : 
    6887                 :     7532232 :   frame->nregs = ix86_nsaved_regs ();
    6888                 :     7532232 :   frame->nsseregs = ix86_nsaved_sseregs ();
    6889                 :             : 
    6890                 :             :   /* 64-bit MS ABI seem to require stack alignment to be always 16,
    6891                 :             :      except for function prologues, leaf functions and when the defult
    6892                 :             :      incoming stack boundary is overriden at command line or via
    6893                 :             :      force_align_arg_pointer attribute.
    6894                 :             : 
    6895                 :             :      Darwin's ABI specifies 128b alignment for both 32 and  64 bit variants
    6896                 :             :      at call sites, including profile function calls.
    6897                 :             : 
    6898                 :             :      For APX push2/pop2, the stack also requires 128b alignment.  */
    6899                 :     7532232 :   if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
    6900                 :          55 :        && crtl->preferred_stack_boundary < 128)
    6901                 :     7532286 :       || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
    6902                 :      222349 :            && crtl->preferred_stack_boundary < 128)
    6903                 :           0 :           && (!crtl->is_leaf || cfun->calls_alloca != 0
    6904                 :           0 :               || ix86_current_function_calls_tls_descriptor
    6905                 :           0 :               || (TARGET_MACHO && crtl->profile)
    6906                 :           0 :               || ix86_incoming_stack_boundary < 128)))
    6907                 :             :     {
    6908                 :           1 :       crtl->preferred_stack_boundary = 128;
    6909                 :           1 :       if (crtl->stack_alignment_needed < 128)
    6910                 :           0 :         crtl->stack_alignment_needed = 128;
    6911                 :             :     }
    6912                 :             : 
    6913                 :     7532232 :   stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
    6914                 :     7532232 :   preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
    6915                 :             : 
    6916                 :     7532232 :   gcc_assert (!size || stack_alignment_needed);
    6917                 :     8305965 :   gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
    6918                 :     7532232 :   gcc_assert (preferred_alignment <= stack_alignment_needed);
    6919                 :             : 
    6920                 :             :   /* The only ABI saving SSE regs should be 64-bit ms_abi.  */
    6921                 :     7532232 :   gcc_assert (TARGET_64BIT || !frame->nsseregs);
    6922                 :     7532232 :   if (TARGET_64BIT && m->call_ms2sysv)
    6923                 :             :     {
    6924                 :       35231 :       gcc_assert (stack_alignment_needed >= 16);
    6925                 :       35231 :       gcc_assert (!frame->nsseregs);
    6926                 :             :     }
    6927                 :             : 
    6928                 :             :   /* For SEH we have to limit the amount of code movement into the prologue.
    6929                 :             :      At present we do this via a BLOCKAGE, at which point there's very little
    6930                 :             :      scheduling that can be done, which means that there's very little point
    6931                 :             :      in doing anything except PUSHs.  */
    6932                 :     7532232 :   if (TARGET_SEH)
    6933                 :             :     m->use_fast_prologue_epilogue = false;
    6934                 :     7532232 :   else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    6935                 :             :     {
    6936                 :     7222633 :       int count = frame->nregs;
    6937                 :     7222633 :       struct cgraph_node *node = cgraph_node::get (current_function_decl);
    6938                 :             : 
    6939                 :             :       /* The fast prologue uses move instead of push to save registers.  This
    6940                 :             :          is significantly longer, but also executes faster as modern hardware
    6941                 :             :          can execute the moves in parallel, but can't do that for push/pop.
    6942                 :             : 
    6943                 :             :          Be careful about choosing what prologue to emit:  When function takes
    6944                 :             :          many instructions to execute we may use slow version as well as in
    6945                 :             :          case function is known to be outside hot spot (this is known with
    6946                 :             :          feedback only).  Weight the size of function by number of registers
    6947                 :             :          to save as it is cheap to use one or two push instructions but very
    6948                 :             :          slow to use many of them.
    6949                 :             : 
    6950                 :             :          Calling this hook multiple times with the same frame requirements
    6951                 :             :          must produce the same layout, since the RA might otherwise be
    6952                 :             :          unable to reach a fixed point or might fail its final sanity checks.
    6953                 :             :          This means that once we've assumed that a function does or doesn't
    6954                 :             :          have a particular size, we have to stick to that assumption
    6955                 :             :          regardless of how the function has changed since.  */
    6956                 :     7222633 :       if (count)
    6957                 :     2539818 :         count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
    6958                 :     7222633 :       if (node->frequency < NODE_FREQUENCY_NORMAL
    6959                 :     6591973 :           || (flag_branch_probabilities
    6960                 :         997 :               && node->frequency < NODE_FREQUENCY_HOT))
    6961                 :      630995 :         m->use_fast_prologue_epilogue = false;
    6962                 :             :       else
    6963                 :             :         {
    6964                 :     6591638 :           if (count != frame->expensive_count)
    6965                 :             :             {
    6966                 :      276873 :               frame->expensive_count = count;
    6967                 :      276873 :               frame->expensive_p = expensive_function_p (count);
    6968                 :             :             }
    6969                 :     6591638 :           m->use_fast_prologue_epilogue = !frame->expensive_p;
    6970                 :             :         }
    6971                 :             :     }
    6972                 :             : 
    6973                 :     7532232 :   frame->save_regs_using_mov
    6974                 :     7532232 :     = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
    6975                 :             : 
    6976                 :             :   /* Skip return address and error code in exception handler.  */
    6977                 :     7532232 :   offset = INCOMING_FRAME_SP_OFFSET;
    6978                 :             : 
    6979                 :             :   /* Skip pushed static chain.  */
    6980                 :     7532232 :   if (ix86_static_chain_on_stack)
    6981                 :           0 :     offset += UNITS_PER_WORD;
    6982                 :             : 
    6983                 :             :   /* Skip saved base pointer.  */
    6984                 :     7532232 :   if (frame_pointer_needed)
    6985                 :     2633792 :     offset += UNITS_PER_WORD;
    6986                 :     7532232 :   frame->hfp_save_offset = offset;
    6987                 :             : 
    6988                 :             :   /* The traditional frame pointer location is at the top of the frame.  */
    6989                 :     7532232 :   frame->hard_frame_pointer_offset = offset;
    6990                 :             : 
    6991                 :             :   /* Register save area */
    6992                 :     7532232 :   offset += frame->nregs * UNITS_PER_WORD;
    6993                 :     7532232 :   frame->reg_save_offset = offset;
    6994                 :             : 
    6995                 :             :   /* Calculate the size of the va-arg area (not including padding, if any).  */
    6996                 :     7532232 :   frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
    6997                 :             : 
    6998                 :             :   /* Also adjust stack_realign_offset for the largest alignment of
    6999                 :             :      stack slot actually used.  */
    7000                 :     7532232 :   if (stack_realign_fp
    7001                 :     7264807 :       || (cfun->machine->max_used_stack_alignment != 0
    7002                 :         126 :           && (offset % cfun->machine->max_used_stack_alignment) != 0))
    7003                 :             :     {
    7004                 :             :       /* We may need a 16-byte aligned stack for the remainder of the
    7005                 :             :          register save area, but the stack frame for the local function
    7006                 :             :          may require a greater alignment if using AVX/2/512.  In order
    7007                 :             :          to avoid wasting space, we first calculate the space needed for
    7008                 :             :          the rest of the register saves, add that to the stack pointer,
    7009                 :             :          and then realign the stack to the boundary of the start of the
    7010                 :             :          frame for the local function.  */
    7011                 :      267483 :       HOST_WIDE_INT space_needed = 0;
    7012                 :      267483 :       HOST_WIDE_INT sse_reg_space_needed = 0;
    7013                 :             : 
    7014                 :      267483 :       if (TARGET_64BIT)
    7015                 :             :         {
    7016                 :      265688 :           if (m->call_ms2sysv)
    7017                 :             :             {
    7018                 :        6421 :               m->call_ms2sysv_pad_in = 0;
    7019                 :        6421 :               space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
    7020                 :             :             }
    7021                 :             : 
    7022                 :      259267 :           else if (frame->nsseregs)
    7023                 :             :             /* The only ABI that has saved SSE registers (Win64) also has a
    7024                 :             :                16-byte aligned default stack.  However, many programs violate
    7025                 :             :                the ABI, and Wine64 forces stack realignment to compensate.  */
    7026                 :        6457 :             space_needed = frame->nsseregs * 16;
    7027                 :             : 
    7028                 :      265688 :           sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
    7029                 :             : 
    7030                 :             :           /* 64-bit frame->va_arg_size should always be a multiple of 16, but
    7031                 :             :              rounding to be pedantic.  */
    7032                 :      265688 :           space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
    7033                 :             :         }
    7034                 :             :       else
    7035                 :        1795 :         space_needed = frame->va_arg_size;
    7036                 :             : 
    7037                 :             :       /* Record the allocation size required prior to the realignment AND.  */
    7038                 :      267483 :       frame->stack_realign_allocate = space_needed;
    7039                 :             : 
    7040                 :             :       /* The re-aligned stack starts at frame->stack_realign_offset.  Values
    7041                 :             :          before this point are not directly comparable with values below
    7042                 :             :          this point.  Use sp_valid_at to determine if the stack pointer is
    7043                 :             :          valid for a given offset, fp_valid_at for the frame pointer, or
    7044                 :             :          choose_baseaddr to have a base register chosen for you.
    7045                 :             : 
    7046                 :             :          Note that the result of (frame->stack_realign_offset
    7047                 :             :          & (stack_alignment_needed - 1)) may not equal zero.  */
    7048                 :      267483 :       offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
    7049                 :      267483 :       frame->stack_realign_offset = offset - space_needed;
    7050                 :      267483 :       frame->sse_reg_save_offset = frame->stack_realign_offset
    7051                 :      267483 :                                                         + sse_reg_space_needed;
    7052                 :      267483 :     }
    7053                 :             :   else
    7054                 :             :     {
    7055                 :     7264749 :       frame->stack_realign_offset = offset;
    7056                 :             : 
    7057                 :     7264749 :       if (TARGET_64BIT && m->call_ms2sysv)
    7058                 :             :         {
    7059                 :       28810 :           m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
    7060                 :       28810 :           offset += xlogue_layout::get_instance ().get_stack_space_used ();
    7061                 :             :         }
    7062                 :             : 
    7063                 :             :       /* Align and set SSE register save area.  */
    7064                 :     7235939 :       else if (frame->nsseregs)
    7065                 :             :         {
    7066                 :             :           /* If the incoming stack boundary is at least 16 bytes, or DRAP is
    7067                 :             :              required and the DRAP re-alignment boundary is at least 16 bytes,
    7068                 :             :              then we want the SSE register save area properly aligned.  */
    7069                 :      180095 :           if (ix86_incoming_stack_boundary >= 128
    7070                 :        6400 :                   || (stack_realign_drap && stack_alignment_needed >= 16))
    7071                 :      180095 :             offset = ROUND_UP (offset, 16);
    7072                 :      180095 :           offset += frame->nsseregs * 16;
    7073                 :             :         }
    7074                 :     7264749 :       frame->sse_reg_save_offset = offset;
    7075                 :     7264749 :       offset += frame->va_arg_size;
    7076                 :             :     }
    7077                 :             : 
    7078                 :             :   /* Align start of frame for local function.  When a function call
    7079                 :             :      is removed, it may become a leaf function.  But if argument may
    7080                 :             :      be passed on stack, we need to align the stack when there is no
    7081                 :             :      tail call.  */
    7082                 :     7532232 :   if (m->call_ms2sysv
    7083                 :     7497001 :       || frame->va_arg_size != 0
    7084                 :     7420033 :       || size != 0
    7085                 :     4071765 :       || !crtl->is_leaf
    7086                 :     1858815 :       || (!crtl->tail_call_emit
    7087                 :     1567265 :           && cfun->machine->outgoing_args_on_stack)
    7088                 :     1858785 :       || cfun->calls_alloca
    7089                 :     9389475 :       || ix86_current_function_calls_tls_descriptor)
    7090                 :     5675390 :     offset = ROUND_UP (offset, stack_alignment_needed);
    7091                 :             : 
    7092                 :             :   /* Frame pointer points here.  */
    7093                 :     7532232 :   frame->frame_pointer_offset = offset;
    7094                 :             : 
    7095                 :     7532232 :   offset += size;
    7096                 :             : 
    7097                 :             :   /* Add outgoing arguments area.  Can be skipped if we eliminated
    7098                 :             :      all the function calls as dead code.
    7099                 :             :      Skipping is however impossible when function calls alloca.  Alloca
    7100                 :             :      expander assumes that last crtl->outgoing_args_size
    7101                 :             :      of stack frame are unused.  */
    7102                 :     7532232 :   if (ACCUMULATE_OUTGOING_ARGS
    7103                 :     8109054 :       && (!crtl->is_leaf || cfun->calls_alloca
    7104                 :      353646 :           || ix86_current_function_calls_tls_descriptor))
    7105                 :             :     {
    7106                 :      223176 :       offset += crtl->outgoing_args_size;
    7107                 :      223176 :       frame->outgoing_arguments_size = crtl->outgoing_args_size;
    7108                 :             :     }
    7109                 :             :   else
    7110                 :     7309056 :     frame->outgoing_arguments_size = 0;
    7111                 :             : 
    7112                 :             :   /* Align stack boundary.  Only needed if we're calling another function
    7113                 :             :      or using alloca.  */
    7114                 :     2547448 :   if (!crtl->is_leaf || cfun->calls_alloca
    7115                 :    10076210 :       || ix86_current_function_calls_tls_descriptor)
    7116                 :     4990039 :     offset = ROUND_UP (offset, preferred_alignment);
    7117                 :             : 
    7118                 :             :   /* We've reached end of stack frame.  */
    7119                 :     7532232 :   frame->stack_pointer_offset = offset;
    7120                 :             : 
    7121                 :             :   /* Size prologue needs to allocate.  */
    7122                 :     7532232 :   to_allocate = offset - frame->sse_reg_save_offset;
    7123                 :             : 
    7124                 :     2633999 :   if ((!to_allocate && frame->nregs <= 1)
    7125                 :     5134680 :       || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
    7126                 :             :        /* If static stack checking is enabled and done with probes,
    7127                 :             :           the registers need to be saved before allocating the frame.  */
    7128                 :     5134112 :       || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
    7129                 :             :       /* If stack clash probing needs a loop, then it needs a
    7130                 :             :          scratch register.  But the returned register is only guaranteed
    7131                 :             :          to be safe to use after register saves are complete.  So if
    7132                 :             :          stack clash protections are enabled and the allocated frame is
    7133                 :             :          larger than the probe interval, then use pushes to save
    7134                 :             :          callee saved registers.  */
    7135                 :    12666274 :       || (flag_stack_clash_protection
    7136                 :         218 :           && !ix86_target_stack_probe ()
    7137                 :         218 :           && to_allocate > get_probe_interval ()))
    7138                 :     2398279 :     frame->save_regs_using_mov = false;
    7139                 :             : 
    7140                 :     7532232 :   if (ix86_using_red_zone ()
    7141                 :     6535984 :       && crtl->sp_is_unchanging
    7142                 :     5930227 :       && crtl->is_leaf
    7143                 :     2448073 :       && !ix86_pc_thunk_call_expanded
    7144                 :     9980305 :       && !ix86_current_function_calls_tls_descriptor)
    7145                 :             :     {
    7146                 :     2448073 :       frame->red_zone_size = to_allocate;
    7147                 :     2448073 :       if (frame->save_regs_using_mov)
    7148                 :      125209 :         frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
    7149                 :     2448073 :       if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
    7150                 :       98621 :         frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
    7151                 :             :     }
    7152                 :             :   else
    7153                 :     5084159 :     frame->red_zone_size = 0;
    7154                 :     7532232 :   frame->stack_pointer_offset -= frame->red_zone_size;
    7155                 :             : 
    7156                 :             :   /* The SEH frame pointer location is near the bottom of the frame.
    7157                 :             :      This is enforced by the fact that the difference between the
    7158                 :             :      stack pointer and the frame pointer is limited to 240 bytes in
    7159                 :             :      the unwind data structure.  */
    7160                 :     7532232 :   if (TARGET_SEH)
    7161                 :             :     {
    7162                 :             :       /* Force the frame pointer to point at or below the lowest register save
    7163                 :             :          area, see the SEH code in config/i386/winnt.cc for the rationale.  */
    7164                 :             :       frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
    7165                 :             : 
    7166                 :             :       /* If we can leave the frame pointer where it is, do so; however return
    7167                 :             :          the establisher frame for __builtin_frame_address (0) or else if the
    7168                 :             :          frame overflows the SEH maximum frame size.
    7169                 :             : 
    7170                 :             :          Note that the value returned by __builtin_frame_address (0) is quite
    7171                 :             :          constrained, because setjmp is piggybacked on the SEH machinery with
    7172                 :             :          recent versions of MinGW:
    7173                 :             : 
    7174                 :             :           #    elif defined(__SEH__)
    7175                 :             :           #     if defined(__aarch64__) || defined(_ARM64_)
    7176                 :             :           #      define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
    7177                 :             :           #     elif (__MINGW_GCC_VERSION < 40702)
    7178                 :             :           #      define setjmp(BUF) _setjmp((BUF), mingw_getsp())
    7179                 :             :           #     else
    7180                 :             :           #      define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
    7181                 :             :           #     endif
    7182                 :             : 
    7183                 :             :          and the second argument passed to _setjmp, if not null, is forwarded
    7184                 :             :          to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
    7185                 :             :          built an ExceptionRecord on the fly describing the setjmp buffer).  */
    7186                 :             :       const HOST_WIDE_INT diff
    7187                 :             :         = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
    7188                 :             :       if (diff <= 255 && !crtl->accesses_prior_frames)
    7189                 :             :         {
    7190                 :             :           /* The resulting diff will be a multiple of 16 lower than 255,
    7191                 :             :              i.e. at most 240 as required by the unwind data structure.  */
    7192                 :             :           frame->hard_frame_pointer_offset += (diff & 15);
    7193                 :             :         }
    7194                 :             :       else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
    7195                 :             :         {
    7196                 :             :           /* Ideally we'd determine what portion of the local stack frame
    7197                 :             :              (within the constraint of the lowest 240) is most heavily used.
    7198                 :             :              But without that complication, simply bias the frame pointer
    7199                 :             :              by 128 bytes so as to maximize the amount of the local stack
    7200                 :             :              frame that is addressable with 8-bit offsets.  */
    7201                 :             :           frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
    7202                 :             :         }
    7203                 :             :       else
    7204                 :             :         frame->hard_frame_pointer_offset = frame->hfp_save_offset;
    7205                 :             :     }
    7206                 :     7532232 : }
    7207                 :             : 
    7208                 :             : /* This is semi-inlined memory_address_length, but simplified
    7209                 :             :    since we know that we're always dealing with reg+offset, and
    7210                 :             :    to avoid having to create and discard all that rtl.  */
    7211                 :             : 
    7212                 :             : static inline int
    7213                 :      702210 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
    7214                 :             : {
    7215                 :      702210 :   int len = 4;
    7216                 :             : 
    7217                 :           0 :   if (offset == 0)
    7218                 :             :     {
    7219                 :             :       /* EBP and R13 cannot be encoded without an offset.  */
    7220                 :           0 :       len = (regno == BP_REG || regno == R13_REG);
    7221                 :             :     }
    7222                 :      698192 :   else if (IN_RANGE (offset, -128, 127))
    7223                 :      433060 :     len = 1;
    7224                 :             : 
    7225                 :             :   /* ESP and R12 must be encoded with a SIB byte.  */
    7226                 :           0 :   if (regno == SP_REG || regno == R12_REG)
    7227                 :           0 :     len++;
    7228                 :             : 
    7229                 :      702210 :   return len;
    7230                 :             : }
    7231                 :             : 
    7232                 :             : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
    7233                 :             :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7234                 :             : 
    7235                 :             : static bool
    7236                 :     2688899 : sp_valid_at (HOST_WIDE_INT cfa_offset)
    7237                 :             : {
    7238                 :     2688899 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7239                 :     2688899 :   if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
    7240                 :             :     {
    7241                 :             :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7242                 :       42665 :       gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
    7243                 :             :       return false;
    7244                 :             :     }
    7245                 :     2646234 :   return fs.sp_valid;
    7246                 :             : }
    7247                 :             : 
    7248                 :             : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
    7249                 :             :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7250                 :             : 
    7251                 :             : static inline bool
    7252                 :      725553 : fp_valid_at (HOST_WIDE_INT cfa_offset)
    7253                 :             : {
    7254                 :      725553 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7255                 :      725553 :   if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
    7256                 :             :     {
    7257                 :             :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7258                 :       28328 :       gcc_assert (cfa_offset >= fs.sp_realigned_offset);
    7259                 :             :       return false;
    7260                 :             :     }
    7261                 :      697225 :   return fs.fp_valid;
    7262                 :             : }
    7263                 :             : 
    7264                 :             : /* Choose a base register based upon alignment requested, speed and/or
    7265                 :             :    size.  */
    7266                 :             : 
    7267                 :             : static void
    7268                 :      725553 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
    7269                 :             :                 HOST_WIDE_INT &base_offset,
    7270                 :             :                 unsigned int align_reqested, unsigned int *align)
    7271                 :             : {
    7272                 :      725553 :   const struct machine_function *m = cfun->machine;
    7273                 :      725553 :   unsigned int hfp_align;
    7274                 :      725553 :   unsigned int drap_align;
    7275                 :      725553 :   unsigned int sp_align;
    7276                 :      725553 :   bool hfp_ok  = fp_valid_at (cfa_offset);
    7277                 :      725553 :   bool drap_ok = m->fs.drap_valid;
    7278                 :      725553 :   bool sp_ok   = sp_valid_at (cfa_offset);
    7279                 :             : 
    7280                 :      725553 :   hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
    7281                 :             : 
    7282                 :             :   /* Filter out any registers that don't meet the requested alignment
    7283                 :             :      criteria.  */
    7284                 :      725553 :   if (align_reqested)
    7285                 :             :     {
    7286                 :      683556 :       if (m->fs.realigned)
    7287                 :       28160 :         hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
    7288                 :             :       /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
    7289                 :             :          notes (which we would need to use a realigned stack pointer),
    7290                 :             :          so disable on SEH targets.  */
    7291                 :      655396 :       else if (m->fs.sp_realigned)
    7292                 :       28332 :         sp_align = crtl->stack_alignment_needed;
    7293                 :             : 
    7294                 :      683556 :       hfp_ok = hfp_ok && hfp_align >= align_reqested;
    7295                 :      683556 :       drap_ok = drap_ok && drap_align >= align_reqested;
    7296                 :      683556 :       sp_ok = sp_ok && sp_align >= align_reqested;
    7297                 :             :     }
    7298                 :             : 
    7299                 :      725553 :   if (m->use_fast_prologue_epilogue)
    7300                 :             :     {
    7301                 :             :       /* Choose the base register most likely to allow the most scheduling
    7302                 :             :          opportunities.  Generally FP is valid throughout the function,
    7303                 :             :          while DRAP must be reloaded within the epilogue.  But choose either
    7304                 :             :          over the SP due to increased encoding size.  */
    7305                 :             : 
    7306                 :      312157 :       if (hfp_ok)
    7307                 :             :         {
    7308                 :       97843 :           base_reg = hard_frame_pointer_rtx;
    7309                 :       97843 :           base_offset = m->fs.fp_offset - cfa_offset;
    7310                 :             :         }
    7311                 :      214314 :       else if (drap_ok)
    7312                 :             :         {
    7313                 :           0 :           base_reg = crtl->drap_reg;
    7314                 :           0 :           base_offset = 0 - cfa_offset;
    7315                 :             :         }
    7316                 :      214314 :       else if (sp_ok)
    7317                 :             :         {
    7318                 :      214314 :           base_reg = stack_pointer_rtx;
    7319                 :      214314 :           base_offset = m->fs.sp_offset - cfa_offset;
    7320                 :             :         }
    7321                 :             :     }
    7322                 :             :   else
    7323                 :             :     {
    7324                 :      413396 :       HOST_WIDE_INT toffset;
    7325                 :      413396 :       int len = 16, tlen;
    7326                 :             : 
    7327                 :             :       /* Choose the base register with the smallest address encoding.
    7328                 :             :          With a tie, choose FP > DRAP > SP.  */
    7329                 :      413396 :       if (sp_ok)
    7330                 :             :         {
    7331                 :      396354 :           base_reg = stack_pointer_rtx;
    7332                 :      396354 :           base_offset = m->fs.sp_offset - cfa_offset;
    7333                 :      788690 :           len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
    7334                 :             :         }
    7335                 :      413396 :       if (drap_ok)
    7336                 :             :         {
    7337                 :           0 :           toffset = 0 - cfa_offset;
    7338                 :           0 :           tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
    7339                 :           0 :           if (tlen <= len)
    7340                 :             :             {
    7341                 :           0 :               base_reg = crtl->drap_reg;
    7342                 :           0 :               base_offset = toffset;
    7343                 :           0 :               len = tlen;
    7344                 :             :             }
    7345                 :             :         }
    7346                 :      413396 :       if (hfp_ok)
    7347                 :             :         {
    7348                 :      305856 :           toffset = m->fs.fp_offset - cfa_offset;
    7349                 :      305856 :           tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
    7350                 :      305856 :           if (tlen <= len)
    7351                 :             :             {
    7352                 :      215206 :               base_reg = hard_frame_pointer_rtx;
    7353                 :      215206 :               base_offset = toffset;
    7354                 :             :             }
    7355                 :             :         }
    7356                 :             :     }
    7357                 :             : 
    7358                 :             :     /* Set the align return value.  */
    7359                 :      725553 :     if (align)
    7360                 :             :       {
    7361                 :      683556 :         if (base_reg == stack_pointer_rtx)
    7362                 :      412464 :           *align = sp_align;
    7363                 :      271092 :         else if (base_reg == crtl->drap_reg)
    7364                 :           0 :           *align = drap_align;
    7365                 :      271092 :         else if (base_reg == hard_frame_pointer_rtx)
    7366                 :      271092 :           *align = hfp_align;
    7367                 :             :       }
    7368                 :      725553 : }
    7369                 :             : 
    7370                 :             : /* Return an RTX that points to CFA_OFFSET within the stack frame and
    7371                 :             :    the alignment of address.  If ALIGN is non-null, it should point to
    7372                 :             :    an alignment value (in bits) that is preferred or zero and will
    7373                 :             :    recieve the alignment of the base register that was selected,
    7374                 :             :    irrespective of rather or not CFA_OFFSET is a multiple of that
    7375                 :             :    alignment value.  If it is possible for the base register offset to be
    7376                 :             :    non-immediate then SCRATCH_REGNO should specify a scratch register to
    7377                 :             :    use.
    7378                 :             : 
    7379                 :             :    The valid base registers are taken from CFUN->MACHINE->FS.  */
    7380                 :             : 
    7381                 :             : static rtx
    7382                 :      725553 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
    7383                 :             :                  unsigned int scratch_regno = INVALID_REGNUM)
    7384                 :             : {
    7385                 :      725553 :   rtx base_reg = NULL;
    7386                 :      725553 :   HOST_WIDE_INT base_offset = 0;
    7387                 :             : 
    7388                 :             :   /* If a specific alignment is requested, try to get a base register
    7389                 :             :      with that alignment first.  */
    7390                 :      725553 :   if (align && *align)
    7391                 :      683556 :     choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
    7392                 :             : 
    7393                 :      725553 :   if (!base_reg)
    7394                 :       41997 :     choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
    7395                 :             : 
    7396                 :      725553 :   gcc_assert (base_reg != NULL);
    7397                 :             : 
    7398                 :      725553 :   rtx base_offset_rtx = GEN_INT (base_offset);
    7399                 :             : 
    7400                 :      725553 :   if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
    7401                 :             :     {
    7402                 :           1 :       gcc_assert (scratch_regno != INVALID_REGNUM);
    7403                 :             : 
    7404                 :           1 :       rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
    7405                 :           1 :       emit_move_insn (scratch_reg, base_offset_rtx);
    7406                 :             : 
    7407                 :           1 :       return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
    7408                 :             :     }
    7409                 :             : 
    7410                 :      725552 :   return plus_constant (Pmode, base_reg, base_offset);
    7411                 :             : }
    7412                 :             : 
    7413                 :             : /* Emit code to save registers in the prologue.  */
    7414                 :             : 
    7415                 :             : static void
    7416                 :      431411 : ix86_emit_save_regs (void)
    7417                 :             : {
    7418                 :      431411 :   int regno;
    7419                 :      431411 :   rtx_insn *insn;
    7420                 :             : 
    7421                 :      431411 :   if (!TARGET_APX_PUSH2POP2
    7422                 :          10 :       || !ix86_can_use_push2pop2 ()
    7423                 :      431419 :       || cfun->machine->func_type != TYPE_NORMAL)
    7424                 :             :     {
    7425                 :    40120572 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7426                 :    39689168 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7427                 :             :           {
    7428                 :     1259655 :             insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7429                 :     1259655 :                                         TARGET_APX_PPX));
    7430                 :     1259655 :             RTX_FRAME_RELATED_P (insn) = 1;
    7431                 :             :           }
    7432                 :             :     }
    7433                 :             :   else
    7434                 :             :     {
    7435                 :           7 :       int regno_list[2];
    7436                 :           7 :       regno_list[0] = regno_list[1] = -1;
    7437                 :           7 :       int loaded_regnum = 0;
    7438                 :           7 :       bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    7439                 :             : 
    7440                 :         651 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7441                 :         644 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7442                 :             :           {
    7443                 :          41 :             if (aligned)
    7444                 :             :               {
    7445                 :          36 :                 regno_list[loaded_regnum++] = regno;
    7446                 :          36 :                 if (loaded_regnum == 2)
    7447                 :             :                   {
    7448                 :          15 :                     gcc_assert (regno_list[0] != -1
    7449                 :             :                                 && regno_list[1] != -1
    7450                 :             :                                 && regno_list[0] != regno_list[1]);
    7451                 :          15 :                     const int offset = UNITS_PER_WORD * 2;
    7452                 :          15 :                     rtx mem = gen_rtx_MEM (TImode,
    7453                 :          15 :                                            gen_rtx_PRE_DEC (Pmode,
    7454                 :             :                                                             stack_pointer_rtx));
    7455                 :          15 :                     insn = emit_insn (gen_push2 (mem,
    7456                 :             :                                                  gen_rtx_REG (word_mode,
    7457                 :             :                                                               regno_list[0]),
    7458                 :             :                                                  gen_rtx_REG (word_mode,
    7459                 :             :                                                               regno_list[1]),
    7460                 :          15 :                                                  TARGET_APX_PPX));
    7461                 :          15 :                     RTX_FRAME_RELATED_P (insn) = 1;
    7462                 :          15 :                     rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
    7463                 :             : 
    7464                 :          45 :                     for (int i = 0; i < 2; i++)
    7465                 :             :                       {
    7466                 :          60 :                         rtx dwarf_reg = gen_rtx_REG (word_mode,
    7467                 :          30 :                                                      regno_list[i]);
    7468                 :          30 :                         rtx sp_offset = plus_constant (Pmode,
    7469                 :             :                                                        stack_pointer_rtx,
    7470                 :          30 :                                                        + UNITS_PER_WORD
    7471                 :          30 :                                                          * (1 - i));
    7472                 :          30 :                         rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
    7473                 :             :                                                               sp_offset),
    7474                 :             :                                                dwarf_reg);
    7475                 :          30 :                         RTX_FRAME_RELATED_P (tmp) = 1;
    7476                 :          30 :                         XVECEXP (dwarf, 0, i + 1) = tmp;
    7477                 :             :                       }
    7478                 :          15 :                     rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
    7479                 :             :                                               plus_constant (Pmode,
    7480                 :             :                                                              stack_pointer_rtx,
    7481                 :             :                                                              -offset));
    7482                 :          15 :                     RTX_FRAME_RELATED_P (sp_tmp) = 1;
    7483                 :          15 :                     XVECEXP (dwarf, 0, 0) = sp_tmp;
    7484                 :          15 :                     add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
    7485                 :             : 
    7486                 :          15 :                     loaded_regnum = 0;
    7487                 :          15 :                     regno_list[0] = regno_list[1] = -1;
    7488                 :             :                   }
    7489                 :             :               }
    7490                 :             :             else
    7491                 :             :               {
    7492                 :           5 :                 insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7493                 :           5 :                                             TARGET_APX_PPX));
    7494                 :           5 :                 RTX_FRAME_RELATED_P (insn) = 1;
    7495                 :           5 :                 aligned = true;
    7496                 :             :               }
    7497                 :             :           }
    7498                 :           7 :       if (loaded_regnum == 1)
    7499                 :             :         {
    7500                 :           6 :           insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
    7501                 :           6 :                                                    regno_list[0]),
    7502                 :           6 :                                       TARGET_APX_PPX));
    7503                 :           6 :           RTX_FRAME_RELATED_P (insn) = 1;
    7504                 :             :         }
    7505                 :             :     }
    7506                 :      431411 : }
    7507                 :             : 
    7508                 :             : /* Emit a single register save at CFA - CFA_OFFSET.  */
    7509                 :             : 
    7510                 :             : static void
    7511                 :      331609 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
    7512                 :             :                               HOST_WIDE_INT cfa_offset)
    7513                 :             : {
    7514                 :      331609 :   struct machine_function *m = cfun->machine;
    7515                 :      331609 :   rtx reg = gen_rtx_REG (mode, regno);
    7516                 :      331609 :   rtx mem, addr, base, insn;
    7517                 :      331609 :   unsigned int align = GET_MODE_ALIGNMENT (mode);
    7518                 :             : 
    7519                 :      331609 :   addr = choose_baseaddr (cfa_offset, &align);
    7520                 :      331609 :   mem = gen_frame_mem (mode, addr);
    7521                 :             : 
    7522                 :             :   /* The location aligment depends upon the base register.  */
    7523                 :      331609 :   align = MIN (GET_MODE_ALIGNMENT (mode), align);
    7524                 :      331609 :   gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    7525                 :      331609 :   set_mem_align (mem, align);
    7526                 :             : 
    7527                 :      331609 :   insn = emit_insn (gen_rtx_SET (mem, reg));
    7528                 :      331609 :   RTX_FRAME_RELATED_P (insn) = 1;
    7529                 :             : 
    7530                 :      331609 :   base = addr;
    7531                 :      331609 :   if (GET_CODE (base) == PLUS)
    7532                 :      324930 :     base = XEXP (base, 0);
    7533                 :      331609 :   gcc_checking_assert (REG_P (base));
    7534                 :             : 
    7535                 :             :   /* When saving registers into a re-aligned local stack frame, avoid
    7536                 :             :      any tricky guessing by dwarf2out.  */
    7537                 :      331609 :   if (m->fs.realigned)
    7538                 :             :     {
    7539                 :       12800 :       gcc_checking_assert (stack_realign_drap);
    7540                 :             : 
    7541                 :       12800 :       if (regno == REGNO (crtl->drap_reg))
    7542                 :             :         {
    7543                 :             :           /* A bit of a hack.  We force the DRAP register to be saved in
    7544                 :             :              the re-aligned stack frame, which provides us with a copy
    7545                 :             :              of the CFA that will last past the prologue.  Install it.  */
    7546                 :           0 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7547                 :           0 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7548                 :           0 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7549                 :           0 :           mem = gen_rtx_MEM (mode, addr);
    7550                 :           0 :           add_reg_note (insn, REG_CFA_DEF_CFA, mem);
    7551                 :             :         }
    7552                 :             :       else
    7553                 :             :         {
    7554                 :             :           /* The frame pointer is a stable reference within the
    7555                 :             :              aligned frame.  Use it.  */
    7556                 :       12800 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7557                 :       12800 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7558                 :       12800 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7559                 :       12800 :           mem = gen_rtx_MEM (mode, addr);
    7560                 :       12800 :           add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7561                 :             :         }
    7562                 :             :     }
    7563                 :             : 
    7564                 :      318809 :   else if (base == stack_pointer_rtx && m->fs.sp_realigned
    7565                 :       12881 :            && cfa_offset >= m->fs.sp_realigned_offset)
    7566                 :             :     {
    7567                 :       12881 :       gcc_checking_assert (stack_realign_fp);
    7568                 :       12881 :       add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7569                 :             :     }
    7570                 :             : 
    7571                 :             :   /* The memory may not be relative to the current CFA register,
    7572                 :             :      which means that we may need to generate a new pattern for
    7573                 :             :      use by the unwind info.  */
    7574                 :      305928 :   else if (base != m->fs.cfa_reg)
    7575                 :             :     {
    7576                 :       45090 :       addr = plus_constant (Pmode, m->fs.cfa_reg,
    7577                 :       45090 :                             m->fs.cfa_offset - cfa_offset);
    7578                 :       45090 :       mem = gen_rtx_MEM (mode, addr);
    7579                 :       45090 :       add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
    7580                 :             :     }
    7581                 :      331609 : }
    7582                 :             : 
    7583                 :             : /* Emit code to save registers using MOV insns.
    7584                 :             :    First register is stored at CFA - CFA_OFFSET.  */
    7585                 :             : static void
    7586                 :          63 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7587                 :             : {
    7588                 :          63 :   unsigned int regno;
    7589                 :             : 
    7590                 :        5859 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7591                 :        5796 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7592                 :             :       {
    7593                 :          88 :         ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
    7594                 :          88 :         cfa_offset -= UNITS_PER_WORD;
    7595                 :             :       }
    7596                 :          63 : }
    7597                 :             : 
    7598                 :             : /* Emit code to save SSE registers using MOV insns.
    7599                 :             :    First register is stored at CFA - CFA_OFFSET.  */
    7600                 :             : static void
    7601                 :       33153 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7602                 :             : {
    7603                 :       33153 :   unsigned int regno;
    7604                 :             : 
    7605                 :     3083229 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7606                 :     3050076 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7607                 :             :       {
    7608                 :      331521 :         ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
    7609                 :      331521 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    7610                 :             :       }
    7611                 :       33153 : }
    7612                 :             : 
    7613                 :             : static GTY(()) rtx queued_cfa_restores;
    7614                 :             : 
    7615                 :             : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
    7616                 :             :    manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
    7617                 :             :    Don't add the note if the previously saved value will be left untouched
    7618                 :             :    within stack red-zone till return, as unwinders can find the same value
    7619                 :             :    in the register and on the stack.  */
    7620                 :             : 
    7621                 :             : static void
    7622                 :     2277879 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
    7623                 :             : {
    7624                 :     2277879 :   if (!crtl->shrink_wrapped
    7625                 :     2267005 :       && cfa_offset <= cfun->machine->fs.red_zone_offset)
    7626                 :             :     return;
    7627                 :             : 
    7628                 :      783715 :   if (insn)
    7629                 :             :     {
    7630                 :      389157 :       add_reg_note (insn, REG_CFA_RESTORE, reg);
    7631                 :      389157 :       RTX_FRAME_RELATED_P (insn) = 1;
    7632                 :             :     }
    7633                 :             :   else
    7634                 :      394558 :     queued_cfa_restores
    7635                 :      394558 :       = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
    7636                 :             : }
    7637                 :             : 
    7638                 :             : /* Add queued REG_CFA_RESTORE notes if any to INSN.  */
    7639                 :             : 
    7640                 :             : static void
    7641                 :     2340771 : ix86_add_queued_cfa_restore_notes (rtx insn)
    7642                 :             : {
    7643                 :     2340771 :   rtx last;
    7644                 :     2340771 :   if (!queued_cfa_restores)
    7645                 :             :     return;
    7646                 :      394558 :   for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
    7647                 :             :     ;
    7648                 :       44603 :   XEXP (last, 1) = REG_NOTES (insn);
    7649                 :       44603 :   REG_NOTES (insn) = queued_cfa_restores;
    7650                 :       44603 :   queued_cfa_restores = NULL_RTX;
    7651                 :       44603 :   RTX_FRAME_RELATED_P (insn) = 1;
    7652                 :             : }
    7653                 :             : 
    7654                 :             : /* Expand prologue or epilogue stack adjustment.
    7655                 :             :    The pattern exist to put a dependency on all ebp-based memory accesses.
    7656                 :             :    STYLE should be negative if instructions should be marked as frame related,
    7657                 :             :    zero if %r11 register is live and cannot be freely used and positive
    7658                 :             :    otherwise.  */
    7659                 :             : 
    7660                 :             : static rtx
    7661                 :     1380774 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
    7662                 :             :                            int style, bool set_cfa)
    7663                 :             : {
    7664                 :     1380774 :   struct machine_function *m = cfun->machine;
    7665                 :     1380774 :   rtx addend = offset;
    7666                 :     1380774 :   rtx insn;
    7667                 :     1380774 :   bool add_frame_related_expr = false;
    7668                 :             : 
    7669                 :     1380774 :   if (!x86_64_immediate_operand (offset, Pmode))
    7670                 :             :     {
    7671                 :             :       /* r11 is used by indirect sibcall return as well, set before the
    7672                 :             :          epilogue and used after the epilogue.  */
    7673                 :         209 :       if (style)
    7674                 :         174 :         addend = gen_rtx_REG (Pmode, R11_REG);
    7675                 :             :       else
    7676                 :             :         {
    7677                 :          35 :           gcc_assert (src != hard_frame_pointer_rtx
    7678                 :             :                       && dest != hard_frame_pointer_rtx);
    7679                 :             :           addend = hard_frame_pointer_rtx;
    7680                 :             :         }
    7681                 :         209 :       emit_insn (gen_rtx_SET (addend, offset));
    7682                 :         209 :       if (style < 0)
    7683                 :          86 :         add_frame_related_expr = true;
    7684                 :             :     }
    7685                 :             : 
    7686                 :     1380774 :   insn = emit_insn (gen_pro_epilogue_adjust_stack_add
    7687                 :     1380774 :                     (Pmode, dest, src, addend));
    7688                 :     1380774 :   if (style >= 0)
    7689                 :      595502 :     ix86_add_queued_cfa_restore_notes (insn);
    7690                 :             : 
    7691                 :     1380774 :   if (set_cfa)
    7692                 :             :     {
    7693                 :     1032181 :       rtx r;
    7694                 :             : 
    7695                 :     1032181 :       gcc_assert (m->fs.cfa_reg == src);
    7696                 :     1032181 :       m->fs.cfa_offset += INTVAL (offset);
    7697                 :     1032181 :       m->fs.cfa_reg = dest;
    7698                 :             : 
    7699                 :     1032181 :       r = gen_rtx_PLUS (Pmode, src, offset);
    7700                 :     1032181 :       r = gen_rtx_SET (dest, r);
    7701                 :     1032181 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
    7702                 :     1032181 :       RTX_FRAME_RELATED_P (insn) = 1;
    7703                 :             :     }
    7704                 :      348593 :   else if (style < 0)
    7705                 :             :     {
    7706                 :      283914 :       RTX_FRAME_RELATED_P (insn) = 1;
    7707                 :      283914 :       if (add_frame_related_expr)
    7708                 :             :         {
    7709                 :          20 :           rtx r = gen_rtx_PLUS (Pmode, src, offset);
    7710                 :          20 :           r = gen_rtx_SET (dest, r);
    7711                 :          20 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
    7712                 :             :         }
    7713                 :             :     }
    7714                 :             : 
    7715                 :     1380774 :   if (dest == stack_pointer_rtx)
    7716                 :             :     {
    7717                 :     1380774 :       HOST_WIDE_INT ooffset = m->fs.sp_offset;
    7718                 :     1380774 :       bool valid = m->fs.sp_valid;
    7719                 :     1380774 :       bool realigned = m->fs.sp_realigned;
    7720                 :             : 
    7721                 :     1380774 :       if (src == hard_frame_pointer_rtx)
    7722                 :             :         {
    7723                 :       28949 :           valid = m->fs.fp_valid;
    7724                 :       28949 :           realigned = false;
    7725                 :       28949 :           ooffset = m->fs.fp_offset;
    7726                 :             :         }
    7727                 :     1351825 :       else if (src == crtl->drap_reg)
    7728                 :             :         {
    7729                 :           0 :           valid = m->fs.drap_valid;
    7730                 :           0 :           realigned = false;
    7731                 :           0 :           ooffset = 0;
    7732                 :             :         }
    7733                 :             :       else
    7734                 :             :         {
    7735                 :             :           /* Else there are two possibilities: SP itself, which we set
    7736                 :             :              up as the default above.  Or EH_RETURN_STACKADJ_RTX, which is
    7737                 :             :              taken care of this by hand along the eh_return path.  */
    7738                 :     1351825 :           gcc_checking_assert (src == stack_pointer_rtx
    7739                 :             :                                || offset == const0_rtx);
    7740                 :             :         }
    7741                 :             : 
    7742                 :     1380774 :       m->fs.sp_offset = ooffset - INTVAL (offset);
    7743                 :     1380774 :       m->fs.sp_valid = valid;
    7744                 :     1380774 :       m->fs.sp_realigned = realigned;
    7745                 :             :     }
    7746                 :     1380774 :   return insn;
    7747                 :             : }
    7748                 :             : 
    7749                 :             : /* Find an available register to be used as dynamic realign argument
    7750                 :             :    pointer regsiter.  Such a register will be written in prologue and
    7751                 :             :    used in begin of body, so it must not be
    7752                 :             :         1. parameter passing register.
    7753                 :             :         2. GOT pointer.
    7754                 :             :    We reuse static-chain register if it is available.  Otherwise, we
    7755                 :             :    use DI for i386 and R13 for x86-64.  We chose R13 since it has
    7756                 :             :    shorter encoding.
    7757                 :             : 
    7758                 :             :    Return: the regno of chosen register.  */
    7759                 :             : 
    7760                 :             : static unsigned int
    7761                 :        7040 : find_drap_reg (void)
    7762                 :             : {
    7763                 :        7040 :   tree decl = cfun->decl;
    7764                 :             : 
    7765                 :             :   /* Always use callee-saved register if there are no caller-saved
    7766                 :             :      registers.  */
    7767                 :        7040 :   if (TARGET_64BIT)
    7768                 :             :     {
    7769                 :             :       /* Use R13 for nested function or function need static chain.
    7770                 :             :          Since function with tail call may use any caller-saved
    7771                 :             :          registers in epilogue, DRAP must not use caller-saved
    7772                 :             :          register in such case.  */
    7773                 :        6755 :       if (DECL_STATIC_CHAIN (decl)
    7774                 :        6713 :           || (cfun->machine->call_saved_registers
    7775                 :        6713 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7776                 :       13468 :           || crtl->tail_call_emit)
    7777                 :         197 :         return R13_REG;
    7778                 :             : 
    7779                 :             :       return R10_REG;
    7780                 :             :     }
    7781                 :             :   else
    7782                 :             :     {
    7783                 :             :       /* Use DI for nested function or function need static chain.
    7784                 :             :          Since function with tail call may use any caller-saved
    7785                 :             :          registers in epilogue, DRAP must not use caller-saved
    7786                 :             :          register in such case.  */
    7787                 :         285 :       if (DECL_STATIC_CHAIN (decl)
    7788                 :         285 :           || (cfun->machine->call_saved_registers
    7789                 :         285 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7790                 :         285 :           || crtl->tail_call_emit
    7791                 :         548 :           || crtl->calls_eh_return)
    7792                 :             :         return DI_REG;
    7793                 :             : 
    7794                 :             :       /* Reuse static chain register if it isn't used for parameter
    7795                 :             :          passing.  */
    7796                 :         263 :       if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
    7797                 :             :         {
    7798                 :         263 :           unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
    7799                 :         263 :           if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
    7800                 :             :             return CX_REG;
    7801                 :             :         }
    7802                 :           0 :       return DI_REG;
    7803                 :             :     }
    7804                 :             : }
    7805                 :             : 
    7806                 :             : /* Return minimum incoming stack alignment.  */
    7807                 :             : 
    7808                 :             : static unsigned int
    7809                 :     1511477 : ix86_minimum_incoming_stack_boundary (bool sibcall)
    7810                 :             : {
    7811                 :     1511477 :   unsigned int incoming_stack_boundary;
    7812                 :             : 
    7813                 :             :   /* Stack of interrupt handler is aligned to 128 bits in 64bit mode.  */
    7814                 :     1511477 :   if (cfun->machine->func_type != TYPE_NORMAL)
    7815                 :         118 :     incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
    7816                 :             :   /* Prefer the one specified at command line. */
    7817                 :     1511359 :   else if (ix86_user_incoming_stack_boundary)
    7818                 :             :     incoming_stack_boundary = ix86_user_incoming_stack_boundary;
    7819                 :             :   /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
    7820                 :             :      if -mstackrealign is used, it isn't used for sibcall check and
    7821                 :             :      estimated stack alignment is 128bit.  */
    7822                 :     1511337 :   else if (!sibcall
    7823                 :     1392833 :            && ix86_force_align_arg_pointer
    7824                 :        4578 :            && crtl->stack_alignment_estimated == 128)
    7825                 :         599 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7826                 :             :   else
    7827                 :     1510738 :     incoming_stack_boundary = ix86_default_incoming_stack_boundary;
    7828                 :             : 
    7829                 :             :   /* Incoming stack alignment can be changed on individual functions
    7830                 :             :      via force_align_arg_pointer attribute.  We use the smallest
    7831                 :             :      incoming stack boundary.  */
    7832                 :     1511477 :   if (incoming_stack_boundary > MIN_STACK_BOUNDARY
    7833                 :     3022345 :       && lookup_attribute ("force_align_arg_pointer",
    7834                 :     1510868 :                            TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    7835                 :        5707 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7836                 :             : 
    7837                 :             :   /* The incoming stack frame has to be aligned at least at
    7838                 :             :      parm_stack_boundary.  */
    7839                 :     1511477 :   if (incoming_stack_boundary < crtl->parm_stack_boundary)
    7840                 :             :     incoming_stack_boundary = crtl->parm_stack_boundary;
    7841                 :             : 
    7842                 :             :   /* Stack at entrance of main is aligned by runtime.  We use the
    7843                 :             :      smallest incoming stack boundary. */
    7844                 :     1511477 :   if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
    7845                 :      138474 :       && DECL_NAME (current_function_decl)
    7846                 :      138474 :       && MAIN_NAME_P (DECL_NAME (current_function_decl))
    7847                 :     1513933 :       && DECL_FILE_SCOPE_P (current_function_decl))
    7848                 :     1511477 :     incoming_stack_boundary = MAIN_STACK_BOUNDARY;
    7849                 :             : 
    7850                 :     1511477 :   return incoming_stack_boundary;
    7851                 :             : }
    7852                 :             : 
    7853                 :             : /* Update incoming stack boundary and estimated stack alignment.  */
    7854                 :             : 
    7855                 :             : static void
    7856                 :     1392968 : ix86_update_stack_boundary (void)
    7857                 :             : {
    7858                 :     1392968 :   ix86_incoming_stack_boundary
    7859                 :     1392968 :     = ix86_minimum_incoming_stack_boundary (false);
    7860                 :             : 
    7861                 :             :   /* x86_64 vararg needs 16byte stack alignment for register save area.  */
    7862                 :     1392968 :   if (TARGET_64BIT
    7863                 :     1268152 :       && cfun->stdarg
    7864                 :       20999 :       && crtl->stack_alignment_estimated < 128)
    7865                 :        9983 :     crtl->stack_alignment_estimated = 128;
    7866                 :             : 
    7867                 :             :   /* __tls_get_addr needs to be called with 16-byte aligned stack.  */
    7868                 :     1392968 :   if (ix86_tls_descriptor_calls_expanded_in_cfun
    7869                 :        1324 :       && crtl->preferred_stack_boundary < 128)
    7870                 :         978 :     crtl->preferred_stack_boundary = 128;
    7871                 :     1392968 : }
    7872                 :             : 
    7873                 :             : /* Handle the TARGET_GET_DRAP_RTX hook.  Return NULL if no DRAP is
    7874                 :             :    needed or an rtx for DRAP otherwise.  */
    7875                 :             : 
    7876                 :             : static rtx
    7877                 :     1508834 : ix86_get_drap_rtx (void)
    7878                 :             : {
    7879                 :             :   /* We must use DRAP if there are outgoing arguments on stack or
    7880                 :             :      the stack pointer register is clobbered by asm statment and
    7881                 :             :      ACCUMULATE_OUTGOING_ARGS is false.  */
    7882                 :     1508834 :   if (ix86_force_drap
    7883                 :     1508834 :       || ((cfun->machine->outgoing_args_on_stack
    7884                 :     1179602 :            || crtl->sp_is_clobbered_by_asm)
    7885                 :      327286 :           && !ACCUMULATE_OUTGOING_ARGS))
    7886                 :      307086 :     crtl->need_drap = true;
    7887                 :             : 
    7888                 :     1508834 :   if (stack_realign_drap)
    7889                 :             :     {
    7890                 :             :       /* Assign DRAP to vDRAP and returns vDRAP */
    7891                 :        7040 :       unsigned int regno = find_drap_reg ();
    7892                 :        7040 :       rtx drap_vreg;
    7893                 :        7040 :       rtx arg_ptr;
    7894                 :        7040 :       rtx_insn *seq, *insn;
    7895                 :             : 
    7896                 :        7040 :       arg_ptr = gen_rtx_REG (Pmode, regno);
    7897                 :        7040 :       crtl->drap_reg = arg_ptr;
    7898                 :             : 
    7899                 :        7040 :       start_sequence ();
    7900                 :        7040 :       drap_vreg = copy_to_reg (arg_ptr);
    7901                 :        7040 :       seq = get_insns ();
    7902                 :        7040 :       end_sequence ();
    7903                 :             : 
    7904                 :        7040 :       insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
    7905                 :        7040 :       if (!optimize)
    7906                 :             :         {
    7907                 :        1870 :           add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
    7908                 :        1870 :           RTX_FRAME_RELATED_P (insn) = 1;
    7909                 :             :         }
    7910                 :        7040 :       return drap_vreg;
    7911                 :             :     }
    7912                 :             :   else
    7913                 :             :     return NULL;
    7914                 :             : }
    7915                 :             : 
    7916                 :             : /* Handle the TARGET_INTERNAL_ARG_POINTER hook.  */
    7917                 :             : 
    7918                 :             : static rtx
    7919                 :     1392968 : ix86_internal_arg_pointer (void)
    7920                 :             : {
    7921                 :     1392968 :   return virtual_incoming_args_rtx;
    7922                 :             : }
    7923                 :             : 
    7924                 :             : struct scratch_reg {
    7925                 :             :   rtx reg;
    7926                 :             :   bool saved;
    7927                 :             : };
    7928                 :             : 
    7929                 :             : /* Return a short-lived scratch register for use on function entry.
    7930                 :             :    In 32-bit mode, it is valid only after the registers are saved
    7931                 :             :    in the prologue.  This register must be released by means of
    7932                 :             :    release_scratch_register_on_entry once it is dead.  */
    7933                 :             : 
    7934                 :             : static void
    7935                 :          18 : get_scratch_register_on_entry (struct scratch_reg *sr)
    7936                 :             : {
    7937                 :          18 :   int regno;
    7938                 :             : 
    7939                 :          18 :   sr->saved = false;
    7940                 :             : 
    7941                 :          18 :   if (TARGET_64BIT)
    7942                 :             :     {
    7943                 :             :       /* We always use R11 in 64-bit mode.  */
    7944                 :             :       regno = R11_REG;
    7945                 :             :     }
    7946                 :             :   else
    7947                 :             :     {
    7948                 :           0 :       tree decl = current_function_decl, fntype = TREE_TYPE (decl);
    7949                 :           0 :       bool fastcall_p
    7950                 :           0 :         = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    7951                 :           0 :       bool thiscall_p
    7952                 :           0 :         = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    7953                 :           0 :       bool static_chain_p = DECL_STATIC_CHAIN (decl);
    7954                 :           0 :       int regparm = ix86_function_regparm (fntype, decl);
    7955                 :           0 :       int drap_regno
    7956                 :           0 :         = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
    7957                 :             : 
    7958                 :             :       /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
    7959                 :             :           for the static chain register.  */
    7960                 :           0 :       if ((regparm < 1 || (fastcall_p && !static_chain_p))
    7961                 :           0 :           && drap_regno != AX_REG)
    7962                 :             :         regno = AX_REG;
    7963                 :             :       /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
    7964                 :             :           for the static chain register.  */
    7965                 :           0 :       else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
    7966                 :             :         regno = AX_REG;
    7967                 :           0 :       else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
    7968                 :             :         regno = DX_REG;
    7969                 :             :       /* ecx is the static chain register.  */
    7970                 :           0 :       else if (regparm < 3 && !fastcall_p && !thiscall_p
    7971                 :           0 :                && !static_chain_p
    7972                 :           0 :                && drap_regno != CX_REG)
    7973                 :             :         regno = CX_REG;
    7974                 :           0 :       else if (ix86_save_reg (BX_REG, true, false))
    7975                 :             :         regno = BX_REG;
    7976                 :             :       /* esi is the static chain register.  */
    7977                 :           0 :       else if (!(regparm == 3 && static_chain_p)
    7978                 :           0 :                && ix86_save_reg (SI_REG, true, false))
    7979                 :             :         regno = SI_REG;
    7980                 :           0 :       else if (ix86_save_reg (DI_REG, true, false))
    7981                 :             :         regno = DI_REG;
    7982                 :             :       else
    7983                 :             :         {
    7984                 :           0 :           regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
    7985                 :           0 :           sr->saved = true;
    7986                 :             :         }
    7987                 :             :     }
    7988                 :             : 
    7989                 :          18 :   sr->reg = gen_rtx_REG (Pmode, regno);
    7990                 :          18 :   if (sr->saved)
    7991                 :             :     {
    7992                 :           0 :       rtx_insn *insn = emit_insn (gen_push (sr->reg));
    7993                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    7994                 :             :     }
    7995                 :          18 : }
    7996                 :             : 
    7997                 :             : /* Release a scratch register obtained from the preceding function.
    7998                 :             : 
    7999                 :             :    If RELEASE_VIA_POP is true, we just pop the register off the stack
    8000                 :             :    to release it.  This is what non-Linux systems use with -fstack-check.
    8001                 :             : 
    8002                 :             :    Otherwise we use OFFSET to locate the saved register and the
    8003                 :             :    allocated stack space becomes part of the local frame and is
    8004                 :             :    deallocated by the epilogue.  */
    8005                 :             : 
    8006                 :             : static void
    8007                 :          18 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
    8008                 :             :                                    bool release_via_pop)
    8009                 :             : {
    8010                 :          18 :   if (sr->saved)
    8011                 :             :     {
    8012                 :           0 :       if (release_via_pop)
    8013                 :             :         {
    8014                 :           0 :           struct machine_function *m = cfun->machine;
    8015                 :           0 :           rtx x, insn = emit_insn (gen_pop (sr->reg));
    8016                 :             : 
    8017                 :             :           /* The RX FRAME_RELATED_P mechanism doesn't know about pop.  */
    8018                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8019                 :           0 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8020                 :           0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8021                 :           0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
    8022                 :           0 :           m->fs.sp_offset -= UNITS_PER_WORD;
    8023                 :             :         }
    8024                 :             :       else
    8025                 :             :         {
    8026                 :           0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    8027                 :           0 :           x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
    8028                 :           0 :           emit_insn (x);
    8029                 :             :         }
    8030                 :             :     }
    8031                 :          18 : }
    8032                 :             : 
    8033                 :             : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
    8034                 :             : 
    8035                 :             :    If INT_REGISTERS_SAVED is true, then integer registers have already been
    8036                 :             :    pushed on the stack.
    8037                 :             : 
    8038                 :             :    If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
    8039                 :             :    beyond SIZE bytes.
    8040                 :             : 
    8041                 :             :    This assumes no knowledge of the current probing state, i.e. it is never
    8042                 :             :    allowed to allocate more than PROBE_INTERVAL bytes of stack space without
    8043                 :             :    a suitable probe.  */
    8044                 :             : 
    8045                 :             : static void
    8046                 :         114 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
    8047                 :             :                              const bool int_registers_saved,
    8048                 :             :                              const bool protection_area)
    8049                 :             : {
    8050                 :         114 :   struct machine_function *m = cfun->machine;
    8051                 :             : 
    8052                 :             :   /* If this function does not statically allocate stack space, then
    8053                 :             :      no probes are needed.  */
    8054                 :         114 :   if (!size)
    8055                 :             :     {
    8056                 :             :       /* However, the allocation of space via pushes for register
    8057                 :             :          saves could be viewed as allocating space, but without the
    8058                 :             :          need to probe.  */
    8059                 :          47 :       if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
    8060                 :          24 :         dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8061                 :             :       else
    8062                 :          23 :         dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
    8063                 :          47 :       return;
    8064                 :             :     }
    8065                 :             : 
    8066                 :             :   /* If we are a noreturn function, then we have to consider the
    8067                 :             :      possibility that we're called via a jump rather than a call.
    8068                 :             : 
    8069                 :             :      Thus we don't have the implicit probe generated by saving the
    8070                 :             :      return address into the stack at the call.  Thus, the stack
    8071                 :             :      pointer could be anywhere in the guard page.  The safe thing
    8072                 :             :      to do is emit a probe now.
    8073                 :             : 
    8074                 :             :      The probe can be avoided if we have already emitted any callee
    8075                 :             :      register saves into the stack or have a frame pointer (which will
    8076                 :             :      have been saved as well).  Those saves will function as implicit
    8077                 :             :      probes.
    8078                 :             : 
    8079                 :             :      ?!? This should be revamped to work like aarch64 and s390 where
    8080                 :             :      we track the offset from the most recent probe.  Normally that
    8081                 :             :      offset would be zero.  For a noreturn function we would reset
    8082                 :             :      it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT).   Then
    8083                 :             :      we just probe when we cross PROBE_INTERVAL.  */
    8084                 :          67 :   if (TREE_THIS_VOLATILE (cfun->decl)
    8085                 :           8 :       && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
    8086                 :             :     {
    8087                 :             :       /* We can safely use any register here since we're just going to push
    8088                 :             :          its value and immediately pop it back.  But we do try and avoid
    8089                 :             :          argument passing registers so as not to introduce dependencies in
    8090                 :             :          the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
    8091                 :           7 :       rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
    8092                 :           7 :       rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
    8093                 :           7 :       rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
    8094                 :           7 :       m->fs.sp_offset -= UNITS_PER_WORD;
    8095                 :           7 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8096                 :             :         {
    8097                 :           7 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    8098                 :           7 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8099                 :           7 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8100                 :           7 :           add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
    8101                 :           7 :           RTX_FRAME_RELATED_P (insn_push) = 1;
    8102                 :           7 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8103                 :           7 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8104                 :           7 :           add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
    8105                 :           7 :           RTX_FRAME_RELATED_P (insn_pop) = 1;
    8106                 :             :         }
    8107                 :           7 :       emit_insn (gen_blockage ());
    8108                 :             :     }
    8109                 :             : 
    8110                 :          67 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8111                 :          67 :   const int dope = 4 * UNITS_PER_WORD;
    8112                 :             : 
    8113                 :             :   /* If there is protection area, take it into account in the size.  */
    8114                 :          67 :   if (protection_area)
    8115                 :          25 :     size += probe_interval + dope;
    8116                 :             : 
    8117                 :             :   /* If we allocate less than the size of the guard statically,
    8118                 :             :      then no probing is necessary, but we do need to allocate
    8119                 :             :      the stack.  */
    8120                 :          42 :   else if (size < (1 << param_stack_clash_protection_guard_size))
    8121                 :             :     {
    8122                 :          28 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8123                 :             :                                  GEN_INT (-size), -1,
    8124                 :          28 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    8125                 :          28 :       dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8126                 :          28 :       return;
    8127                 :             :     }
    8128                 :             : 
    8129                 :             :   /* We're allocating a large enough stack frame that we need to
    8130                 :             :      emit probes.  Either emit them inline or in a loop depending
    8131                 :             :      on the size.  */
    8132                 :          39 :   if (size <= 4 * probe_interval)
    8133                 :             :     {
    8134                 :             :       HOST_WIDE_INT i;
    8135                 :          49 :       for (i = probe_interval; i <= size; i += probe_interval)
    8136                 :             :         {
    8137                 :             :           /* Allocate PROBE_INTERVAL bytes.  */
    8138                 :          28 :           rtx insn
    8139                 :          28 :             = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8140                 :             :                                          GEN_INT (-probe_interval), -1,
    8141                 :          28 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    8142                 :          28 :           add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
    8143                 :             : 
    8144                 :             :           /* And probe at *sp.  */
    8145                 :          28 :           emit_stack_probe (stack_pointer_rtx);
    8146                 :          28 :           emit_insn (gen_blockage ());
    8147                 :             :         }
    8148                 :             : 
    8149                 :             :       /* We need to allocate space for the residual, but we do not need
    8150                 :             :          to probe the residual...  */
    8151                 :          21 :       HOST_WIDE_INT residual = (i - probe_interval - size);
    8152                 :          21 :       if (residual)
    8153                 :             :         {
    8154                 :          21 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8155                 :             :                                      GEN_INT (residual), -1,
    8156                 :          21 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8157                 :             : 
    8158                 :             :           /* ...except if there is a protection area to maintain.  */
    8159                 :          21 :           if (protection_area)
    8160                 :          12 :             emit_stack_probe (stack_pointer_rtx);
    8161                 :             :         }
    8162                 :             : 
    8163                 :          21 :       dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
    8164                 :             :     }
    8165                 :             :   else
    8166                 :             :     {
    8167                 :             :       /* We expect the GP registers to be saved when probes are used
    8168                 :             :          as the probing sequences might need a scratch register and
    8169                 :             :          the routine to allocate one assumes the integer registers
    8170                 :             :          have already been saved.  */
    8171                 :          18 :       gcc_assert (int_registers_saved);
    8172                 :             : 
    8173                 :          18 :       struct scratch_reg sr;
    8174                 :          18 :       get_scratch_register_on_entry (&sr);
    8175                 :             : 
    8176                 :             :       /* If we needed to save a register, then account for any space
    8177                 :             :          that was pushed (we are not going to pop the register when
    8178                 :             :          we do the restore).  */
    8179                 :          18 :       if (sr.saved)
    8180                 :           0 :         size -= UNITS_PER_WORD;
    8181                 :             : 
    8182                 :             :       /* Step 1: round SIZE down to a multiple of the interval.  */
    8183                 :          18 :       HOST_WIDE_INT rounded_size = size & -probe_interval;
    8184                 :             : 
    8185                 :             :       /* Step 2: compute final value of the loop counter.  Use lea if
    8186                 :             :          possible.  */
    8187                 :          18 :       rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    8188                 :          18 :       rtx insn;
    8189                 :          18 :       if (address_no_seg_operand (addr, Pmode))
    8190                 :           6 :         insn = emit_insn (gen_rtx_SET (sr.reg, addr));
    8191                 :             :       else
    8192                 :             :         {
    8193                 :          12 :           emit_move_insn (sr.reg, GEN_INT (-rounded_size));
    8194                 :          12 :           insn = emit_insn (gen_rtx_SET (sr.reg,
    8195                 :             :                                          gen_rtx_PLUS (Pmode, sr.reg,
    8196                 :             :                                                        stack_pointer_rtx)));
    8197                 :             :         }
    8198                 :          18 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8199                 :             :         {
    8200                 :          16 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8201                 :          16 :                         plus_constant (Pmode, sr.reg,
    8202                 :          16 :                                        m->fs.cfa_offset + rounded_size));
    8203                 :          16 :           RTX_FRAME_RELATED_P (insn) = 1;
    8204                 :             :         }
    8205                 :             : 
    8206                 :             :       /* Step 3: the loop.  */
    8207                 :          18 :       rtx size_rtx = GEN_INT (rounded_size);
    8208                 :          18 :       insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
    8209                 :             :                                                     size_rtx));
    8210                 :          18 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8211                 :             :         {
    8212                 :          16 :           m->fs.cfa_offset += rounded_size;
    8213                 :          16 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8214                 :          16 :                         plus_constant (Pmode, stack_pointer_rtx,
    8215                 :          16 :                                        m->fs.cfa_offset));
    8216                 :          16 :           RTX_FRAME_RELATED_P (insn) = 1;
    8217                 :             :         }
    8218                 :          18 :       m->fs.sp_offset += rounded_size;
    8219                 :          18 :       emit_insn (gen_blockage ());
    8220                 :             : 
    8221                 :             :       /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
    8222                 :             :          is equal to ROUNDED_SIZE.  */
    8223                 :             : 
    8224                 :          18 :       if (size != rounded_size)
    8225                 :             :         {
    8226                 :          18 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8227                 :             :                                      GEN_INT (rounded_size - size), -1,
    8228                 :          18 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8229                 :             : 
    8230                 :          18 :           if (protection_area)
    8231                 :          13 :             emit_stack_probe (stack_pointer_rtx);
    8232                 :             :         }
    8233                 :             : 
    8234                 :          18 :       dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
    8235                 :             : 
    8236                 :             :       /* This does not deallocate the space reserved for the scratch
    8237                 :             :          register.  That will be deallocated in the epilogue.  */
    8238                 :          18 :       release_scratch_register_on_entry (&sr, size, false);
    8239                 :             :     }
    8240                 :             : 
    8241                 :             :   /* Adjust back to account for the protection area.  */
    8242                 :          39 :   if (protection_area)
    8243                 :          25 :     pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8244                 :          25 :                                GEN_INT (probe_interval + dope), -1,
    8245                 :          25 :                                m->fs.cfa_reg == stack_pointer_rtx);
    8246                 :             : 
    8247                 :             :   /* Make sure nothing is scheduled before we are done.  */
    8248                 :          39 :   emit_insn (gen_blockage ());
    8249                 :             : }
    8250                 :             : 
    8251                 :             : /* Adjust the stack pointer up to REG while probing it.  */
    8252                 :             : 
    8253                 :             : const char *
    8254                 :          18 : output_adjust_stack_and_probe (rtx reg)
    8255                 :             : {
    8256                 :          18 :   static int labelno = 0;
    8257                 :          18 :   char loop_lab[32];
    8258                 :          18 :   rtx xops[2];
    8259                 :             : 
    8260                 :          18 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8261                 :             : 
    8262                 :             :   /* Loop.  */
    8263                 :          18 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8264                 :             : 
    8265                 :             :   /* SP = SP + PROBE_INTERVAL.  */
    8266                 :          18 :   xops[0] = stack_pointer_rtx;
    8267                 :          23 :   xops[1] = GEN_INT (get_probe_interval ());
    8268                 :          18 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8269                 :             : 
    8270                 :             :   /* Probe at SP.  */
    8271                 :          18 :   xops[1] = const0_rtx;
    8272                 :          18 :   output_asm_insn ("or%z0\t{%1, (%0)|DWORD PTR [%0], %1}", xops);
    8273                 :             : 
    8274                 :             :   /* Test if SP == LAST_ADDR.  */
    8275                 :          18 :   xops[0] = stack_pointer_rtx;
    8276                 :          18 :   xops[1] = reg;
    8277                 :          18 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8278                 :             : 
    8279                 :             :   /* Branch.  */
    8280                 :          18 :   fputs ("\tjne\t", asm_out_file);
    8281                 :          18 :   assemble_name_raw (asm_out_file, loop_lab);
    8282                 :          18 :   fputc ('\n', asm_out_file);
    8283                 :             : 
    8284                 :          18 :   return "";
    8285                 :             : }
    8286                 :             : 
    8287                 :             : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
    8288                 :             :    inclusive.  These are offsets from the current stack pointer.
    8289                 :             : 
    8290                 :             :    INT_REGISTERS_SAVED is true if integer registers have already been
    8291                 :             :    pushed on the stack.  */
    8292                 :             : 
    8293                 :             : static void
    8294                 :           0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
    8295                 :             :                              const bool int_registers_saved)
    8296                 :             : {
    8297                 :           0 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8298                 :             : 
    8299                 :             :   /* See if we have a constant small number of probes to generate.  If so,
    8300                 :             :      that's the easy case.  The run-time loop is made up of 6 insns in the
    8301                 :             :      generic case while the compile-time loop is made up of n insns for n #
    8302                 :             :      of intervals.  */
    8303                 :           0 :   if (size <= 6 * probe_interval)
    8304                 :             :     {
    8305                 :             :       HOST_WIDE_INT i;
    8306                 :             : 
    8307                 :             :       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
    8308                 :             :          it exceeds SIZE.  If only one probe is needed, this will not
    8309                 :             :          generate any code.  Then probe at FIRST + SIZE.  */
    8310                 :           0 :       for (i = probe_interval; i < size; i += probe_interval)
    8311                 :           0 :         emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8312                 :           0 :                                          -(first + i)));
    8313                 :             : 
    8314                 :           0 :       emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8315                 :           0 :                                        -(first + size)));
    8316                 :             :     }
    8317                 :             : 
    8318                 :             :   /* Otherwise, do the same as above, but in a loop.  Note that we must be
    8319                 :             :      extra careful with variables wrapping around because we might be at
    8320                 :             :      the very top (or the very bottom) of the address space and we have
    8321                 :             :      to be able to handle this case properly; in particular, we use an
    8322                 :             :      equality test for the loop condition.  */
    8323                 :             :   else
    8324                 :             :     {
    8325                 :             :       /* We expect the GP registers to be saved when probes are used
    8326                 :             :          as the probing sequences might need a scratch register and
    8327                 :             :          the routine to allocate one assumes the integer registers
    8328                 :             :          have already been saved.  */
    8329                 :           0 :       gcc_assert (int_registers_saved);
    8330                 :             : 
    8331                 :           0 :       HOST_WIDE_INT rounded_size, last;
    8332                 :           0 :       struct scratch_reg sr;
    8333                 :             : 
    8334                 :           0 :       get_scratch_register_on_entry (&sr);
    8335                 :             : 
    8336                 :             : 
    8337                 :             :       /* Step 1: round SIZE to the previous multiple of the interval.  */
    8338                 :             : 
    8339                 :           0 :       rounded_size = ROUND_DOWN (size, probe_interval);
    8340                 :             : 
    8341                 :             : 
    8342                 :             :       /* Step 2: compute initial and final value of the loop counter.  */
    8343                 :             : 
    8344                 :             :       /* TEST_OFFSET = FIRST.  */
    8345                 :           0 :       emit_move_insn (sr.reg, GEN_INT (-first));
    8346                 :             : 
    8347                 :             :       /* LAST_OFFSET = FIRST + ROUNDED_SIZE.  */
    8348                 :           0 :       last = first + rounded_size;
    8349                 :             : 
    8350                 :             : 
    8351                 :             :       /* Step 3: the loop
    8352                 :             : 
    8353                 :             :          do
    8354                 :             :            {
    8355                 :             :              TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
    8356                 :             :              probe at TEST_ADDR
    8357                 :             :            }
    8358                 :             :          while (TEST_ADDR != LAST_ADDR)
    8359                 :             : 
    8360                 :             :          probes at FIRST + N * PROBE_INTERVAL for values of N from 1
    8361                 :             :          until it is equal to ROUNDED_SIZE.  */
    8362                 :             : 
    8363                 :           0 :       emit_insn
    8364                 :           0 :         (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
    8365                 :             : 
    8366                 :             : 
    8367                 :             :       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
    8368                 :             :          that SIZE is equal to ROUNDED_SIZE.  */
    8369                 :             : 
    8370                 :           0 :       if (size != rounded_size)
    8371                 :           0 :         emit_stack_probe (plus_constant (Pmode,
    8372                 :           0 :                                          gen_rtx_PLUS (Pmode,
    8373                 :             :                                                        stack_pointer_rtx,
    8374                 :             :                                                        sr.reg),
    8375                 :           0 :                                          rounded_size - size));
    8376                 :             : 
    8377                 :           0 :       release_scratch_register_on_entry (&sr, size, true);
    8378                 :             :     }
    8379                 :             : 
    8380                 :             :   /* Make sure nothing is scheduled before we are done.  */
    8381                 :           0 :   emit_insn (gen_blockage ());
    8382                 :           0 : }
    8383                 :             : 
    8384                 :             : /* Probe a range of stack addresses from REG to END, inclusive.  These are
    8385                 :             :    offsets from the current stack pointer.  */
    8386                 :             : 
    8387                 :             : const char *
    8388                 :           0 : output_probe_stack_range (rtx reg, rtx end)
    8389                 :             : {
    8390                 :           0 :   static int labelno = 0;
    8391                 :           0 :   char loop_lab[32];
    8392                 :           0 :   rtx xops[3];
    8393                 :             : 
    8394                 :           0 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8395                 :             : 
    8396                 :             :   /* Loop.  */
    8397                 :           0 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8398                 :             : 
    8399                 :             :   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
    8400                 :           0 :   xops[0] = reg;
    8401                 :           0 :   xops[1] = GEN_INT (get_probe_interval ());
    8402                 :           0 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8403                 :             : 
    8404                 :             :   /* Probe at TEST_ADDR.  */
    8405                 :           0 :   xops[0] = stack_pointer_rtx;
    8406                 :           0 :   xops[1] = reg;
    8407                 :           0 :   xops[2] = const0_rtx;
    8408                 :           0 :   output_asm_insn ("or%z0\t{%2, (%0,%1)|DWORD PTR [%0+%1], %2}", xops);
    8409                 :             : 
    8410                 :             :   /* Test if TEST_ADDR == LAST_ADDR.  */
    8411                 :           0 :   xops[0] = reg;
    8412                 :           0 :   xops[1] = end;
    8413                 :           0 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8414                 :             : 
    8415                 :             :   /* Branch.  */
    8416                 :           0 :   fputs ("\tjne\t", asm_out_file);
    8417                 :           0 :   assemble_name_raw (asm_out_file, loop_lab);
    8418                 :           0 :   fputc ('\n', asm_out_file);
    8419                 :             : 
    8420                 :           0 :   return "";
    8421                 :             : }
    8422                 :             : 
    8423                 :             : /* Set stack_frame_required to false if stack frame isn't required.
    8424                 :             :    Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
    8425                 :             :    slot used if stack frame is required and CHECK_STACK_SLOT is true.  */
    8426                 :             : 
    8427                 :             : static void
    8428                 :     1392283 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
    8429                 :             :                                     bool check_stack_slot)
    8430                 :             : {
    8431                 :     1392283 :   HARD_REG_SET set_up_by_prologue, prologue_used;
    8432                 :     1392283 :   basic_block bb;
    8433                 :             : 
    8434                 :     5569132 :   CLEAR_HARD_REG_SET (prologue_used);
    8435                 :     1392283 :   CLEAR_HARD_REG_SET (set_up_by_prologue);
    8436                 :     1392283 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
    8437                 :     1392283 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
    8438                 :     1392283 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode,
    8439                 :             :                        HARD_FRAME_POINTER_REGNUM);
    8440                 :             : 
    8441                 :             :   /* The preferred stack alignment is the minimum stack alignment.  */
    8442                 :     1392283 :   if (stack_alignment > crtl->preferred_stack_boundary)
    8443                 :      135521 :     stack_alignment = crtl->preferred_stack_boundary;
    8444                 :             : 
    8445                 :     1392283 :   bool require_stack_frame = false;
    8446                 :             : 
    8447                 :    14274479 :   FOR_EACH_BB_FN (bb, cfun)
    8448                 :             :     {
    8449                 :    12882196 :       rtx_insn *insn;
    8450                 :   149530571 :       FOR_BB_INSNS (bb, insn)
    8451                 :   136648375 :         if (NONDEBUG_INSN_P (insn)
    8452                 :   136648375 :             && requires_stack_frame_p (insn, prologue_used,
    8453                 :             :                                        set_up_by_prologue))
    8454                 :             :           {
    8455                 :    30544640 :             require_stack_frame = true;
    8456                 :             : 
    8457                 :    30544640 :             if (check_stack_slot)
    8458                 :             :               {
    8459                 :             :                 /* Find the maximum stack alignment.  */
    8460                 :    27025330 :                 subrtx_iterator::array_type array;
    8461                 :   186491755 :                 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
    8462                 :   159466425 :                   if (MEM_P (*iter)
    8463                 :   159466425 :                       && (reg_mentioned_p (stack_pointer_rtx,
    8464                 :             :                                            *iter)
    8465                 :    12057628 :                           || reg_mentioned_p (frame_pointer_rtx,
    8466                 :             :                                               *iter)))
    8467                 :             :                     {
    8468                 :     9590133 :                       unsigned int alignment = MEM_ALIGN (*iter);
    8469                 :     9590133 :                       if (alignment > stack_alignment)
    8470                 :       25726 :                         stack_alignment = alignment;
    8471                 :             :                     }
    8472                 :    27025330 :               }
    8473                 :             :           }
    8474                 :             :     }
    8475                 :             : 
    8476                 :     1392283 :   cfun->machine->stack_frame_required = require_stack_frame;
    8477                 :     1392283 : }
    8478                 :             : 
    8479                 :             : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
    8480                 :             :    will guide prologue/epilogue to be generated in correct form.  */
    8481                 :             : 
    8482                 :             : static void
    8483                 :     3156003 : ix86_finalize_stack_frame_flags (void)
    8484                 :             : {
    8485                 :             :   /* Check if stack realign is really needed after reload, and
    8486                 :             :      stores result in cfun */
    8487                 :     3156003 :   unsigned int incoming_stack_boundary
    8488                 :     3156003 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    8489                 :     3156003 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    8490                 :     3156003 :   unsigned int stack_alignment
    8491                 :     1085426 :     = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
    8492                 :     4241429 :        ? crtl->max_used_stack_slot_alignment
    8493                 :     3156003 :        : crtl->stack_alignment_needed);
    8494                 :     3156003 :   unsigned int stack_realign
    8495                 :     3156003 :     = (incoming_stack_boundary < stack_alignment);
    8496                 :     3156003 :   bool recompute_frame_layout_p = false;
    8497                 :             : 
    8498                 :     3156003 :   if (crtl->stack_realign_finalized)
    8499                 :             :     {
    8500                 :             :       /* After stack_realign_needed is finalized, we can't no longer
    8501                 :             :          change it.  */
    8502                 :     1763720 :       gcc_assert (crtl->stack_realign_needed == stack_realign);
    8503                 :     1763720 :       return;
    8504                 :             :     }
    8505                 :             : 
    8506                 :             :   /* It is always safe to compute max_used_stack_alignment.  We
    8507                 :             :      compute it only if 128-bit aligned load/store may be generated
    8508                 :             :      on misaligned stack slot which will lead to segfault. */
    8509                 :     2784566 :   bool check_stack_slot
    8510                 :     1392283 :     = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
    8511                 :     1392283 :   ix86_find_max_used_stack_alignment (stack_alignment,
    8512                 :             :                                       check_stack_slot);
    8513                 :             : 
    8514                 :             :   /* If the only reason for frame_pointer_needed is that we conservatively
    8515                 :             :      assumed stack realignment might be needed or -fno-omit-frame-pointer
    8516                 :             :      is used, but in the end nothing that needed the stack alignment had
    8517                 :             :      been spilled nor stack access, clear frame_pointer_needed and say we
    8518                 :             :      don't need stack realignment.
    8519                 :             : 
    8520                 :             :      When vector register is used for piecewise move and store, we don't
    8521                 :             :      increase stack_alignment_needed as there is no register spill for
    8522                 :             :      piecewise move and store.  Since stack_realign_needed is set to true
    8523                 :             :      by checking stack_alignment_estimated which is updated by pseudo
    8524                 :             :      vector register usage, we also need to check stack_realign_needed to
    8525                 :             :      eliminate frame pointer.  */
    8526                 :     1392283 :   if ((stack_realign
    8527                 :     1334177 :        || (!flag_omit_frame_pointer && optimize)
    8528                 :     1323950 :        || crtl->stack_realign_needed)
    8529                 :       68895 :       && frame_pointer_needed
    8530                 :       68895 :       && crtl->is_leaf
    8531                 :       44955 :       && crtl->sp_is_unchanging
    8532                 :       44903 :       && !ix86_current_function_calls_tls_descriptor
    8533                 :       44903 :       && !crtl->accesses_prior_frames
    8534                 :       44903 :       && !cfun->calls_alloca
    8535                 :       44903 :       && !crtl->calls_eh_return
    8536                 :             :       /* See ira_setup_eliminable_regset for the rationale.  */
    8537                 :       44903 :       && !(STACK_CHECK_MOVING_SP
    8538                 :       44903 :            && flag_stack_check
    8539                 :           0 :            && flag_exceptions
    8540                 :           0 :            && cfun->can_throw_non_call_exceptions)
    8541                 :       44903 :       && !ix86_frame_pointer_required ()
    8542                 :       44902 :       && ix86_get_frame_size () == 0
    8543                 :       28915 :       && ix86_nsaved_sseregs () == 0
    8544                 :     1421198 :       && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
    8545                 :             :     {
    8546                 :       28915 :       if (cfun->machine->stack_frame_required)
    8547                 :             :         {
    8548                 :             :           /* Stack frame is required.  If stack alignment needed is less
    8549                 :             :              than incoming stack boundary, don't realign stack.  */
    8550                 :         213 :           stack_realign = incoming_stack_boundary < stack_alignment;
    8551                 :         213 :           if (!stack_realign)
    8552                 :             :             {
    8553                 :         213 :               crtl->max_used_stack_slot_alignment
    8554                 :         213 :                 = incoming_stack_boundary;
    8555                 :         213 :               crtl->stack_alignment_needed
    8556                 :         213 :                 = incoming_stack_boundary;
    8557                 :             :               /* Also update preferred_stack_boundary for leaf
    8558                 :             :                  functions.  */
    8559                 :         213 :               crtl->preferred_stack_boundary
    8560                 :         213 :                 = incoming_stack_boundary;
    8561                 :             :             }
    8562                 :             :         }
    8563                 :             :       else
    8564                 :             :         {
    8565                 :             :           /* If drap has been set, but it actually isn't live at the
    8566                 :             :              start of the function, there is no reason to set it up.  */
    8567                 :       28702 :           if (crtl->drap_reg)
    8568                 :             :             {
    8569                 :          37 :               basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    8570                 :          74 :               if (! REGNO_REG_SET_P (DF_LR_IN (bb),
    8571                 :             :                                      REGNO (crtl->drap_reg)))
    8572                 :             :                 {
    8573                 :          37 :                   crtl->drap_reg = NULL_RTX;
    8574                 :          37 :                   crtl->need_drap = false;
    8575                 :             :                 }
    8576                 :             :             }
    8577                 :             :           else
    8578                 :       28665 :             cfun->machine->no_drap_save_restore = true;
    8579                 :             : 
    8580                 :       28702 :           frame_pointer_needed = false;
    8581                 :       28702 :           stack_realign = false;
    8582                 :       28702 :           crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
    8583                 :       28702 :           crtl->stack_alignment_needed = incoming_stack_boundary;
    8584                 :       28702 :           crtl->stack_alignment_estimated = incoming_stack_boundary;
    8585                 :       28702 :           if (crtl->preferred_stack_boundary > incoming_stack_boundary)
    8586                 :           0 :             crtl->preferred_stack_boundary = incoming_stack_boundary;
    8587                 :       28702 :           df_finish_pass (true);
    8588                 :       28702 :           df_scan_alloc (NULL);
    8589                 :       28702 :           df_scan_blocks ();
    8590                 :       28702 :           df_compute_regs_ever_live (true);
    8591                 :       28702 :           df_analyze ();
    8592                 :             : 
    8593                 :       28702 :           if (flag_var_tracking)
    8594                 :             :             {
    8595                 :             :               /* Since frame pointer is no longer available, replace it with
    8596                 :             :                  stack pointer - UNITS_PER_WORD in debug insns.  */
    8597                 :         127 :               df_ref ref, next;
    8598                 :         127 :               for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
    8599                 :         127 :                    ref; ref = next)
    8600                 :             :                 {
    8601                 :           0 :                   next = DF_REF_NEXT_REG (ref);
    8602                 :           0 :                   if (!DF_REF_INSN_INFO (ref))
    8603                 :           0 :                     continue;
    8604                 :             : 
    8605                 :             :                   /* Make sure the next ref is for a different instruction,
    8606                 :             :                      so that we're not affected by the rescan.  */
    8607                 :           0 :                   rtx_insn *insn = DF_REF_INSN (ref);
    8608                 :           0 :                   while (next && DF_REF_INSN (next) == insn)
    8609                 :           0 :                     next = DF_REF_NEXT_REG (next);
    8610                 :             : 
    8611                 :           0 :                   if (DEBUG_INSN_P (insn))
    8612                 :             :                     {
    8613                 :             :                       bool changed = false;
    8614                 :           0 :                       for (; ref != next; ref = DF_REF_NEXT_REG (ref))
    8615                 :             :                         {
    8616                 :           0 :                           rtx *loc = DF_REF_LOC (ref);
    8617                 :           0 :                           if (*loc == hard_frame_pointer_rtx)
    8618                 :             :                             {
    8619                 :           0 :                               *loc = plus_constant (Pmode,
    8620                 :             :                                                     stack_pointer_rtx,
    8621                 :           0 :                                                     -UNITS_PER_WORD);
    8622                 :           0 :                               changed = true;
    8623                 :             :                             }
    8624                 :             :                         }
    8625                 :           0 :                       if (changed)
    8626                 :           0 :                         df_insn_rescan (insn);
    8627                 :             :                     }
    8628                 :             :                 }
    8629                 :             :             }
    8630                 :             : 
    8631                 :             :           recompute_frame_layout_p = true;
    8632                 :             :         }
    8633                 :             :     }
    8634                 :     1363368 :   else if (crtl->max_used_stack_slot_alignment >= 128
    8635                 :      612355 :            && cfun->machine->stack_frame_required)
    8636                 :             :     {
    8637                 :             :       /* We don't need to realign stack.  max_used_stack_alignment is
    8638                 :             :          used to decide how stack frame should be aligned.  This is
    8639                 :             :          independent of any psABIs nor 32-bit vs 64-bit.  */
    8640                 :      571677 :       cfun->machine->max_used_stack_alignment
    8641                 :      571677 :         = stack_alignment / BITS_PER_UNIT;
    8642                 :             :     }
    8643                 :             : 
    8644                 :     1392283 :   if (crtl->stack_realign_needed != stack_realign)
    8645                 :       29101 :     recompute_frame_layout_p = true;
    8646                 :     1392283 :   crtl->stack_realign_needed = stack_realign;
    8647                 :     1392283 :   crtl->stack_realign_finalized = true;
    8648                 :     1392283 :   if (recompute_frame_layout_p)
    8649                 :       29178 :     ix86_compute_frame_layout ();
    8650                 :             : }
    8651                 :             : 
    8652                 :             : /* Delete SET_GOT right after entry block if it is allocated to reg.  */
    8653                 :             : 
    8654                 :             : static void
    8655                 :           0 : ix86_elim_entry_set_got (rtx reg)
    8656                 :             : {
    8657                 :           0 :   basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    8658                 :           0 :   rtx_insn *c_insn = BB_HEAD (bb);
    8659                 :           0 :   if (!NONDEBUG_INSN_P (c_insn))
    8660                 :           0 :     c_insn = next_nonnote_nondebug_insn (c_insn);
    8661                 :           0 :   if (c_insn && NONJUMP_INSN_P (c_insn))
    8662                 :             :     {
    8663                 :           0 :       rtx pat = PATTERN (c_insn);
    8664                 :           0 :       if (GET_CODE (pat) == PARALLEL)
    8665                 :             :         {
    8666                 :           0 :           rtx set = XVECEXP (pat, 0, 0);
    8667                 :           0 :           if (GET_CODE (set) == SET
    8668                 :           0 :               && GET_CODE (SET_SRC (set)) == UNSPEC
    8669                 :           0 :               && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
    8670                 :           0 :               && REGNO (SET_DEST (set)) == REGNO (reg))
    8671                 :           0 :             delete_insn (c_insn);
    8672                 :             :         }
    8673                 :             :     }
    8674                 :           0 : }
    8675                 :             : 
    8676                 :             : static rtx
    8677                 :      197890 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
    8678                 :             : {
    8679                 :      197890 :   rtx addr, mem;
    8680                 :             : 
    8681                 :      197890 :   if (offset)
    8682                 :      189156 :     addr = plus_constant (Pmode, frame_reg, offset);
    8683                 :      197890 :   mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
    8684                 :      197890 :   return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
    8685                 :             : }
    8686                 :             : 
    8687                 :             : static inline rtx
    8688                 :      102965 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
    8689                 :             : {
    8690                 :      102965 :   return gen_frame_set (reg, frame_reg, offset, false);
    8691                 :             : }
    8692                 :             : 
    8693                 :             : static inline rtx
    8694                 :       94925 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
    8695                 :             : {
    8696                 :       94925 :   return gen_frame_set (reg, frame_reg, offset, true);
    8697                 :             : }
    8698                 :             : 
    8699                 :             : static void
    8700                 :        7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
    8701                 :             : {
    8702                 :        7045 :   struct machine_function *m = cfun->machine;
    8703                 :        7045 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    8704                 :        7045 :                           + m->call_ms2sysv_extra_regs;
    8705                 :        7045 :   rtvec v = rtvec_alloc (ncregs + 1);
    8706                 :        7045 :   unsigned int align, i, vi = 0;
    8707                 :        7045 :   rtx_insn *insn;
    8708                 :        7045 :   rtx sym, addr;
    8709                 :        7045 :   rtx rax = gen_rtx_REG (word_mode, AX_REG);
    8710                 :        7045 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    8711                 :             : 
    8712                 :             :   /* AL should only be live with sysv_abi.  */
    8713                 :        7045 :   gcc_assert (!ix86_eax_live_at_start_p ());
    8714                 :        7045 :   gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
    8715                 :             : 
    8716                 :             :   /* Setup RAX as the stub's base pointer.  We use stack_realign_offset rather
    8717                 :             :      we've actually realigned the stack or not.  */
    8718                 :        7045 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    8719                 :        7045 :   addr = choose_baseaddr (frame.stack_realign_offset
    8720                 :        7045 :                           + xlogue.get_stub_ptr_offset (), &align, AX_REG);
    8721                 :        7045 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    8722                 :             : 
    8723                 :        7045 :   emit_insn (gen_rtx_SET (rax, addr));
    8724                 :             : 
    8725                 :             :   /* Get the stub symbol.  */
    8726                 :        8327 :   sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
    8727                 :             :                                                   : XLOGUE_STUB_SAVE);
    8728                 :        7045 :   RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    8729                 :             : 
    8730                 :      101970 :   for (i = 0; i < ncregs; ++i)
    8731                 :             :     {
    8732                 :       94925 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    8733                 :       94925 :       rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
    8734                 :       94925 :                              r.regno);
    8735                 :       94925 :       RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
    8736                 :             :     }
    8737                 :             : 
    8738                 :        7045 :   gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
    8739                 :             : 
    8740                 :        7045 :   insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
    8741                 :        7045 :   RTX_FRAME_RELATED_P (insn) = true;
    8742                 :        7045 : }
    8743                 :             : 
    8744                 :             : /* Generate and return an insn body to AND X with Y.  */
    8745                 :             : 
    8746                 :             : static rtx_insn *
    8747                 :       29567 : gen_and2_insn (rtx x, rtx y)
    8748                 :             : {
    8749                 :       29567 :   enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
    8750                 :             : 
    8751                 :       29567 :   gcc_assert (insn_operand_matches (icode, 0, x));
    8752                 :       29567 :   gcc_assert (insn_operand_matches (icode, 1, x));
    8753                 :       29567 :   gcc_assert (insn_operand_matches (icode, 2, y));
    8754                 :             : 
    8755                 :       29567 :   return GEN_FCN (icode) (x, x, y);
    8756                 :             : }
    8757                 :             : 
    8758                 :             : /* Expand the prologue into a bunch of separate insns.  */
    8759                 :             : 
    8760                 :             : void
    8761                 :     1392360 : ix86_expand_prologue (void)
    8762                 :             : {
    8763                 :     1392360 :   struct machine_function *m = cfun->machine;
    8764                 :     1392360 :   rtx insn, t;
    8765                 :     1392360 :   HOST_WIDE_INT allocate;
    8766                 :     1392360 :   bool int_registers_saved;
    8767                 :     1392360 :   bool sse_registers_saved;
    8768                 :     1392360 :   bool save_stub_call_needed;
    8769                 :     1392360 :   rtx static_chain = NULL_RTX;
    8770                 :             : 
    8771                 :     1392360 :   ix86_last_zero_store_uid = 0;
    8772                 :     1392360 :   if (ix86_function_naked (current_function_decl))
    8773                 :             :     {
    8774                 :          77 :       if (flag_stack_usage_info)
    8775                 :           0 :         current_function_static_stack_size = 0;
    8776                 :          77 :       return;
    8777                 :             :     }
    8778                 :             : 
    8779                 :     1392283 :   ix86_finalize_stack_frame_flags ();
    8780                 :             : 
    8781                 :             :   /* DRAP should not coexist with stack_realign_fp */
    8782                 :     1392283 :   gcc_assert (!(crtl->drap_reg && stack_realign_fp));
    8783                 :             : 
    8784                 :     1392283 :   memset (&m->fs, 0, sizeof (m->fs));
    8785                 :             : 
    8786                 :             :   /* Initialize CFA state for before the prologue.  */
    8787                 :     1392283 :   m->fs.cfa_reg = stack_pointer_rtx;
    8788                 :     1392283 :   m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
    8789                 :             : 
    8790                 :             :   /* Track SP offset to the CFA.  We continue tracking this after we've
    8791                 :             :      swapped the CFA register away from SP.  In the case of re-alignment
    8792                 :             :      this is fudged; we're interested to offsets within the local frame.  */
    8793                 :     1392283 :   m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    8794                 :     1392283 :   m->fs.sp_valid = true;
    8795                 :     1392283 :   m->fs.sp_realigned = false;
    8796                 :             : 
    8797                 :     1392283 :   const struct ix86_frame &frame = cfun->machine->frame;
    8798                 :             : 
    8799                 :     1392283 :   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
    8800                 :             :     {
    8801                 :             :       /* We should have already generated an error for any use of
    8802                 :             :          ms_hook on a nested function.  */
    8803                 :           0 :       gcc_checking_assert (!ix86_static_chain_on_stack);
    8804                 :             : 
    8805                 :             :       /* Check if profiling is active and we shall use profiling before
    8806                 :             :          prologue variant. If so sorry.  */
    8807                 :           0 :       if (crtl->profile && flag_fentry != 0)
    8808                 :           0 :         sorry ("%<ms_hook_prologue%> attribute is not compatible "
    8809                 :             :                "with %<-mfentry%> for 32-bit");
    8810                 :             : 
    8811                 :             :       /* In ix86_asm_output_function_label we emitted:
    8812                 :             :          8b ff     movl.s %edi,%edi
    8813                 :             :          55        push   %ebp
    8814                 :             :          8b ec     movl.s %esp,%ebp
    8815                 :             : 
    8816                 :             :          This matches the hookable function prologue in Win32 API
    8817                 :             :          functions in Microsoft Windows XP Service Pack 2 and newer.
    8818                 :             :          Wine uses this to enable Windows apps to hook the Win32 API
    8819                 :             :          functions provided by Wine.
    8820                 :             : 
    8821                 :             :          What that means is that we've already set up the frame pointer.  */
    8822                 :             : 
    8823                 :           0 :       if (frame_pointer_needed
    8824                 :           0 :           && !(crtl->drap_reg && crtl->stack_realign_needed))
    8825                 :             :         {
    8826                 :           0 :           rtx push, mov;
    8827                 :             : 
    8828                 :             :           /* We've decided to use the frame pointer already set up.
    8829                 :             :              Describe this to the unwinder by pretending that both
    8830                 :             :              push and mov insns happen right here.
    8831                 :             : 
    8832                 :             :              Putting the unwind info here at the end of the ms_hook
    8833                 :             :              is done so that we can make absolutely certain we get
    8834                 :             :              the required byte sequence at the start of the function,
    8835                 :             :              rather than relying on an assembler that can produce
    8836                 :             :              the exact encoding required.
    8837                 :             : 
    8838                 :             :              However it does mean (in the unpatched case) that we have
    8839                 :             :              a 1 insn window where the asynchronous unwind info is
    8840                 :             :              incorrect.  However, if we placed the unwind info at
    8841                 :             :              its correct location we would have incorrect unwind info
    8842                 :             :              in the patched case.  Which is probably all moot since
    8843                 :             :              I don't expect Wine generates dwarf2 unwind info for the
    8844                 :             :              system libraries that use this feature.  */
    8845                 :             : 
    8846                 :           0 :           insn = emit_insn (gen_blockage ());
    8847                 :             : 
    8848                 :           0 :           push = gen_push (hard_frame_pointer_rtx);
    8849                 :           0 :           mov = gen_rtx_SET (hard_frame_pointer_rtx,
    8850                 :             :                              stack_pointer_rtx);
    8851                 :           0 :           RTX_FRAME_RELATED_P (push) = 1;
    8852                 :           0 :           RTX_FRAME_RELATED_P (mov) = 1;
    8853                 :             : 
    8854                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8855                 :           0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    8856                 :             :                         gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
    8857                 :             : 
    8858                 :             :           /* Note that gen_push incremented m->fs.cfa_offset, even
    8859                 :             :              though we didn't emit the push insn here.  */
    8860                 :           0 :           m->fs.cfa_reg = hard_frame_pointer_rtx;
    8861                 :           0 :           m->fs.fp_offset = m->fs.cfa_offset;
    8862                 :           0 :           m->fs.fp_valid = true;
    8863                 :           0 :         }
    8864                 :             :       else
    8865                 :             :         {
    8866                 :             :           /* The frame pointer is not needed so pop %ebp again.
    8867                 :             :              This leaves us with a pristine state.  */
    8868                 :           0 :           emit_insn (gen_pop (hard_frame_pointer_rtx));
    8869                 :             :         }
    8870                 :             :     }
    8871                 :             : 
    8872                 :             :   /* The first insn of a function that accepts its static chain on the
    8873                 :             :      stack is to push the register that would be filled in by a direct
    8874                 :             :      call.  This insn will be skipped by the trampoline.  */
    8875                 :     1392283 :   else if (ix86_static_chain_on_stack)
    8876                 :             :     {
    8877                 :           0 :       static_chain = ix86_static_chain (cfun->decl, false);
    8878                 :           0 :       insn = emit_insn (gen_push (static_chain));
    8879                 :           0 :       emit_insn (gen_blockage ());
    8880                 :             : 
    8881                 :             :       /* We don't want to interpret this push insn as a register save,
    8882                 :             :          only as a stack adjustment.  The real copy of the register as
    8883                 :             :          a save will be done later, if needed.  */
    8884                 :           0 :       t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8885                 :           0 :       t = gen_rtx_SET (stack_pointer_rtx, t);
    8886                 :           0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
    8887                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    8888                 :             :     }
    8889                 :             : 
    8890                 :             :   /* Emit prologue code to adjust stack alignment and setup DRAP, in case
    8891                 :             :      of DRAP is needed and stack realignment is really needed after reload */
    8892                 :     1392283 :   if (stack_realign_drap)
    8893                 :             :     {
    8894                 :        6840 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    8895                 :             : 
    8896                 :             :       /* Can't use DRAP in interrupt function.  */
    8897                 :        6840 :       if (cfun->machine->func_type != TYPE_NORMAL)
    8898                 :           0 :         sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
    8899                 :             :                "in interrupt service routine.  This may be worked "
    8900                 :             :                "around by avoiding functions with aggregate return.");
    8901                 :             : 
    8902                 :             :       /* Only need to push parameter pointer reg if it is caller saved.  */
    8903                 :        6840 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    8904                 :             :         {
    8905                 :             :           /* Push arg pointer reg */
    8906                 :         142 :           insn = emit_insn (gen_push (crtl->drap_reg));
    8907                 :         142 :           RTX_FRAME_RELATED_P (insn) = 1;
    8908                 :             :         }
    8909                 :             : 
    8910                 :             :       /* Grab the argument pointer.  */
    8911                 :        6840 :       t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
    8912                 :        6840 :       insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    8913                 :        6840 :       RTX_FRAME_RELATED_P (insn) = 1;
    8914                 :        6840 :       m->fs.cfa_reg = crtl->drap_reg;
    8915                 :        6840 :       m->fs.cfa_offset = 0;
    8916                 :             : 
    8917                 :             :       /* Align the stack.  */
    8918                 :        6840 :       insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
    8919                 :        6840 :                                        GEN_INT (-align_bytes)));
    8920                 :        6840 :       RTX_FRAME_RELATED_P (insn) = 1;
    8921                 :             : 
    8922                 :             :       /* Replicate the return address on the stack so that return
    8923                 :             :          address can be reached via (argp - 1) slot.  This is needed
    8924                 :             :          to implement macro RETURN_ADDR_RTX and intrinsic function
    8925                 :             :          expand_builtin_return_addr etc.  */
    8926                 :        7125 :       t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
    8927                 :        6840 :       t = gen_frame_mem (word_mode, t);
    8928                 :        6840 :       insn = emit_insn (gen_push (t));
    8929                 :        6840 :       RTX_FRAME_RELATED_P (insn) = 1;
    8930                 :             : 
    8931                 :             :       /* For the purposes of frame and register save area addressing,
    8932                 :             :          we've started over with a new frame.  */
    8933                 :        6840 :       m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    8934                 :        6840 :       m->fs.realigned = true;
    8935                 :             : 
    8936                 :        6840 :       if (static_chain)
    8937                 :             :         {
    8938                 :             :           /* Replicate static chain on the stack so that static chain
    8939                 :             :              can be reached via (argp - 2) slot.  This is needed for
    8940                 :             :              nested function with stack realignment.  */
    8941                 :           0 :           insn = emit_insn (gen_push (static_chain));
    8942                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8943                 :             :         }
    8944                 :             :     }
    8945                 :             : 
    8946                 :     1392283 :   int_registers_saved = (frame.nregs == 0);
    8947                 :     1392283 :   sse_registers_saved = (frame.nsseregs == 0);
    8948                 :     1392283 :   save_stub_call_needed = (m->call_ms2sysv);
    8949                 :     1392283 :   gcc_assert (sse_registers_saved || !save_stub_call_needed);
    8950                 :             : 
    8951                 :     1392283 :   if (frame_pointer_needed && !m->fs.fp_valid)
    8952                 :             :     {
    8953                 :             :       /* Note: AT&T enter does NOT have reversed args.  Enter is probably
    8954                 :             :          slower on all targets.  Also sdb didn't like it.  */
    8955                 :      459493 :       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
    8956                 :      459493 :       RTX_FRAME_RELATED_P (insn) = 1;
    8957                 :             : 
    8958                 :      459493 :       if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
    8959                 :             :         {
    8960                 :      459493 :           insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
    8961                 :      459493 :           RTX_FRAME_RELATED_P (insn) = 1;
    8962                 :             : 
    8963                 :      459493 :           if (m->fs.cfa_reg == stack_pointer_rtx)
    8964                 :      452653 :             m->fs.cfa_reg = hard_frame_pointer_rtx;
    8965                 :      459493 :           m->fs.fp_offset = m->fs.sp_offset;
    8966                 :      459493 :           m->fs.fp_valid = true;
    8967                 :             :         }
    8968                 :             :     }
    8969                 :             : 
    8970                 :     1392283 :   if (!int_registers_saved)
    8971                 :             :     {
    8972                 :             :       /* If saving registers via PUSH, do so now.  */
    8973                 :      431474 :       if (!frame.save_regs_using_mov)
    8974                 :             :         {
    8975                 :      431411 :           ix86_emit_save_regs ();
    8976                 :      431411 :           int_registers_saved = true;
    8977                 :      431411 :           gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
    8978                 :             :         }
    8979                 :             : 
    8980                 :             :       /* When using red zone we may start register saving before allocating
    8981                 :             :          the stack frame saving one cycle of the prologue.  However, avoid
    8982                 :             :          doing this if we have to probe the stack; at least on x86_64 the
    8983                 :             :          stack probe can turn into a call that clobbers a red zone location. */
    8984                 :          63 :       else if (ix86_using_red_zone ()
    8985                 :          63 :                && (! TARGET_STACK_PROBE
    8986                 :           0 :                    || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
    8987                 :             :         {
    8988                 :          59 :           ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    8989                 :          59 :           cfun->machine->red_zone_used = true;
    8990                 :          59 :           int_registers_saved = true;
    8991                 :             :         }
    8992                 :             :     }
    8993                 :             : 
    8994                 :     1392283 :   if (frame.red_zone_size != 0)
    8995                 :      133924 :     cfun->machine->red_zone_used = true;
    8996                 :             : 
    8997                 :     1392283 :   if (stack_realign_fp)
    8998                 :             :     {
    8999                 :       22727 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9000                 :       23078 :       gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
    9001                 :             : 
    9002                 :             :       /* Record last valid frame pointer offset.  */
    9003                 :       22727 :       m->fs.sp_realigned_fp_last = frame.reg_save_offset;
    9004                 :             : 
    9005                 :             :       /* The computation of the size of the re-aligned stack frame means
    9006                 :             :          that we must allocate the size of the register save area before
    9007                 :             :          performing the actual alignment.  Otherwise we cannot guarantee
    9008                 :             :          that there's enough storage above the realignment point.  */
    9009                 :       22727 :       allocate = frame.reg_save_offset - m->fs.sp_offset
    9010                 :       22727 :                  + frame.stack_realign_allocate;
    9011                 :       22727 :       if (allocate)
    9012                 :        2699 :         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9013                 :             :                                    GEN_INT (-allocate), -1, false);
    9014                 :             : 
    9015                 :             :       /* Align the stack.  */
    9016                 :       22727 :       emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
    9017                 :       22727 :       m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
    9018                 :       22727 :       m->fs.sp_realigned_offset = m->fs.sp_offset
    9019                 :       22727 :                                               - frame.stack_realign_allocate;
    9020                 :             :       /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
    9021                 :             :          Beyond this point, stack access should be done via choose_baseaddr or
    9022                 :             :          by using sp_valid_at and fp_valid_at to determine the correct base
    9023                 :             :          register.  Henceforth, any CFA offset should be thought of as logical
    9024                 :             :          and not physical.  */
    9025                 :       22727 :       gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
    9026                 :       22727 :       gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
    9027                 :       22727 :       m->fs.sp_realigned = true;
    9028                 :             : 
    9029                 :             :       /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
    9030                 :             :          is needed to describe where a register is saved using a realigned
    9031                 :             :          stack pointer, so we need to invalidate the stack pointer for that
    9032                 :             :          target.  */
    9033                 :       22727 :       if (TARGET_SEH)
    9034                 :             :         m->fs.sp_valid = false;
    9035                 :             : 
    9036                 :             :       /* If SP offset is non-immediate after allocation of the stack frame,
    9037                 :             :          then emit SSE saves or stub call prior to allocating the rest of the
    9038                 :             :          stack frame.  This is less efficient for the out-of-line stub because
    9039                 :             :          we can't combine allocations across the call barrier, but it's better
    9040                 :             :          than using a scratch register.  */
    9041                 :       22727 :       else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
    9042                 :             :                                                    - m->fs.sp_realigned_offset),
    9043                 :       22727 :                                           Pmode))
    9044                 :             :         {
    9045                 :           3 :           if (!sse_registers_saved)
    9046                 :             :             {
    9047                 :           1 :               ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9048                 :           1 :               sse_registers_saved = true;
    9049                 :             :             }
    9050                 :           2 :           else if (save_stub_call_needed)
    9051                 :             :             {
    9052                 :           1 :               ix86_emit_outlined_ms2sysv_save (frame);
    9053                 :           1 :               save_stub_call_needed = false;
    9054                 :             :             }
    9055                 :             :         }
    9056                 :             :     }
    9057                 :             : 
    9058                 :     1392283 :   allocate = frame.stack_pointer_offset - m->fs.sp_offset;
    9059                 :             : 
    9060                 :     1392283 :   if (flag_stack_usage_info)
    9061                 :             :     {
    9062                 :             :       /* We start to count from ARG_POINTER.  */
    9063                 :         357 :       HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
    9064                 :             : 
    9065                 :             :       /* If it was realigned, take into account the fake frame.  */
    9066                 :         357 :       if (stack_realign_drap)
    9067                 :             :         {
    9068                 :           1 :           if (ix86_static_chain_on_stack)
    9069                 :           0 :             stack_size += UNITS_PER_WORD;
    9070                 :             : 
    9071                 :           1 :           if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9072                 :           0 :             stack_size += UNITS_PER_WORD;
    9073                 :             : 
    9074                 :             :           /* This over-estimates by 1 minimal-stack-alignment-unit but
    9075                 :             :              mitigates that by counting in the new return address slot.  */
    9076                 :           1 :           current_function_dynamic_stack_size
    9077                 :           1 :             += crtl->stack_alignment_needed / BITS_PER_UNIT;
    9078                 :             :         }
    9079                 :             : 
    9080                 :         357 :       current_function_static_stack_size = stack_size;
    9081                 :             :     }
    9082                 :             : 
    9083                 :             :   /* On SEH target with very large frame size, allocate an area to save
    9084                 :             :      SSE registers (as the very large allocation won't be described).  */
    9085                 :     1392283 :   if (TARGET_SEH
    9086                 :             :       && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
    9087                 :             :       && !sse_registers_saved)
    9088                 :             :     {
    9089                 :             :       HOST_WIDE_INT sse_size
    9090                 :             :         = frame.sse_reg_save_offset - frame.reg_save_offset;
    9091                 :             : 
    9092                 :             :       gcc_assert (int_registers_saved);
    9093                 :             : 
    9094                 :             :       /* No need to do stack checking as the area will be immediately
    9095                 :             :          written.  */
    9096                 :             :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9097                 :             :                                  GEN_INT (-sse_size), -1,
    9098                 :             :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9099                 :             :       allocate -= sse_size;
    9100                 :             :       ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9101                 :             :       sse_registers_saved = true;
    9102                 :             :     }
    9103                 :             : 
    9104                 :             :   /* If stack clash protection is requested, then probe the stack, unless it
    9105                 :             :      is already probed on the target.  */
    9106                 :     1392283 :   if (allocate >= 0
    9107                 :     1392279 :       && flag_stack_clash_protection
    9108                 :     1392367 :       && !ix86_target_stack_probe ())
    9109                 :             :     {
    9110                 :          84 :       ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
    9111                 :          84 :       allocate = 0;
    9112                 :             :     }
    9113                 :             : 
    9114                 :             :   /* The stack has already been decremented by the instruction calling us
    9115                 :             :      so probe if the size is non-negative to preserve the protection area.  */
    9116                 :     1392199 :   else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    9117                 :             :     {
    9118                 :          47 :       const HOST_WIDE_INT probe_interval = get_probe_interval ();
    9119                 :             : 
    9120                 :          47 :       if (STACK_CHECK_MOVING_SP)
    9121                 :             :         {
    9122                 :          47 :           if (crtl->is_leaf
    9123                 :          18 :               && !cfun->calls_alloca
    9124                 :          18 :               && allocate <= probe_interval)
    9125                 :             :             ;
    9126                 :             : 
    9127                 :             :           else
    9128                 :             :             {
    9129                 :          30 :               ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
    9130                 :          30 :               allocate = 0;
    9131                 :             :             }
    9132                 :             :         }
    9133                 :             : 
    9134                 :             :       else
    9135                 :             :         {
    9136                 :             :           HOST_WIDE_INT size = allocate;
    9137                 :             : 
    9138                 :             :           if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
    9139                 :             :             size = 0x80000000 - get_stack_check_protect () - 1;
    9140                 :             : 
    9141                 :             :           if (TARGET_STACK_PROBE)
    9142                 :             :             {
    9143                 :             :               if (crtl->is_leaf && !cfun->calls_alloca)
    9144                 :             :                 {
    9145                 :             :                   if (size > probe_interval)
    9146                 :             :                     ix86_emit_probe_stack_range (0, size, int_registers_saved);
    9147                 :             :                 }
    9148                 :             :               else
    9149                 :             :                 ix86_emit_probe_stack_range (0,
    9150                 :             :                                              size + get_stack_check_protect (),
    9151                 :             :                                              int_registers_saved);
    9152                 :             :             }
    9153                 :             :           else
    9154                 :             :             {
    9155                 :             :               if (crtl->is_leaf && !cfun->calls_alloca)
    9156                 :             :                 {
    9157                 :             :                   if (size > probe_interval
    9158                 :             :                       && size > get_stack_check_protect ())
    9159                 :             :                     ix86_emit_probe_stack_range (get_stack_check_protect (),
    9160                 :             :                                                  (size
    9161                 :             :                                                   - get_stack_check_protect ()),
    9162                 :             :                                                  int_registers_saved);
    9163                 :             :                 }
    9164                 :             :               else
    9165                 :             :                 ix86_emit_probe_stack_range (get_stack_check_protect (), size,
    9166                 :             :                                              int_registers_saved);
    9167                 :             :             }
    9168                 :             :         }
    9169                 :             :     }
    9170                 :             : 
    9171                 :     1392279 :   if (allocate == 0)
    9172                 :             :     ;
    9173                 :      782497 :   else if (!ix86_target_stack_probe ()
    9174                 :      782497 :            || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
    9175                 :             :     {
    9176                 :      782453 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9177                 :             :                                  GEN_INT (-allocate), -1,
    9178                 :      782453 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9179                 :             :     }
    9180                 :             :   else
    9181                 :             :     {
    9182                 :          44 :       rtx eax = gen_rtx_REG (Pmode, AX_REG);
    9183                 :          44 :       rtx r10 = NULL;
    9184                 :          44 :       const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
    9185                 :          44 :       bool eax_live = ix86_eax_live_at_start_p ();
    9186                 :          44 :       bool r10_live = false;
    9187                 :             : 
    9188                 :          44 :       if (TARGET_64BIT)
    9189                 :          44 :         r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
    9190                 :             : 
    9191                 :          44 :       if (eax_live)
    9192                 :             :         {
    9193                 :           0 :           insn = emit_insn (gen_push (eax));
    9194                 :           0 :           allocate -= UNITS_PER_WORD;
    9195                 :             :           /* Note that SEH directives need to continue tracking the stack
    9196                 :             :              pointer even after the frame pointer has been set up.  */
    9197                 :           0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9198                 :             :             {
    9199                 :           0 :               if (sp_is_cfa_reg)
    9200                 :           0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9201                 :           0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9202                 :           0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9203                 :           0 :                             gen_rtx_SET (stack_pointer_rtx,
    9204                 :             :                                          plus_constant (Pmode,
    9205                 :             :                                                         stack_pointer_rtx,
    9206                 :             :                                                         -UNITS_PER_WORD)));
    9207                 :             :             }
    9208                 :             :         }
    9209                 :             : 
    9210                 :          44 :       if (r10_live)
    9211                 :             :         {
    9212                 :           0 :           r10 = gen_rtx_REG (Pmode, R10_REG);
    9213                 :           0 :           insn = emit_insn (gen_push (r10));
    9214                 :           0 :           allocate -= UNITS_PER_WORD;
    9215                 :           0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9216                 :             :             {
    9217                 :           0 :               if (sp_is_cfa_reg)
    9218                 :           0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9219                 :           0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9220                 :           0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9221                 :           0 :                             gen_rtx_SET (stack_pointer_rtx,
    9222                 :             :                                          plus_constant (Pmode,
    9223                 :             :                                                         stack_pointer_rtx,
    9224                 :             :                                                         -UNITS_PER_WORD)));
    9225                 :             :             }
    9226                 :             :         }
    9227                 :             : 
    9228                 :          44 :       emit_move_insn (eax, GEN_INT (allocate));
    9229                 :          44 :       emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
    9230                 :             : 
    9231                 :             :       /* Use the fact that AX still contains ALLOCATE.  */
    9232                 :          44 :       insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
    9233                 :          44 :                         (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
    9234                 :             : 
    9235                 :          44 :       if (sp_is_cfa_reg || TARGET_SEH)
    9236                 :             :         {
    9237                 :          36 :           if (sp_is_cfa_reg)
    9238                 :          36 :             m->fs.cfa_offset += allocate;
    9239                 :          36 :           RTX_FRAME_RELATED_P (insn) = 1;
    9240                 :          36 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9241                 :          36 :                         gen_rtx_SET (stack_pointer_rtx,
    9242                 :             :                                      plus_constant (Pmode, stack_pointer_rtx,
    9243                 :             :                                                     -allocate)));
    9244                 :             :         }
    9245                 :          44 :       m->fs.sp_offset += allocate;
    9246                 :             : 
    9247                 :             :       /* Use stack_pointer_rtx for relative addressing so that code works for
    9248                 :             :          realigned stack.  But this means that we need a blockage to prevent
    9249                 :             :          stores based on the frame pointer from being scheduled before.  */
    9250                 :          44 :       if (r10_live && eax_live)
    9251                 :             :         {
    9252                 :           0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9253                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
    9254                 :             :                           gen_frame_mem (word_mode, t));
    9255                 :           0 :           t = plus_constant (Pmode, t, UNITS_PER_WORD);
    9256                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
    9257                 :             :                           gen_frame_mem (word_mode, t));
    9258                 :           0 :           emit_insn (gen_memory_blockage ());
    9259                 :             :         }
    9260                 :          44 :       else if (eax_live || r10_live)
    9261                 :             :         {
    9262                 :           0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9263                 :           0 :           emit_move_insn (gen_rtx_REG (word_mode,
    9264                 :             :                                        (eax_live ? AX_REG : R10_REG)),
    9265                 :             :                           gen_frame_mem (word_mode, t));
    9266                 :           0 :           emit_insn (gen_memory_blockage ());
    9267                 :             :         }
    9268                 :             :     }
    9269                 :     1392283 :   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
    9270                 :             : 
    9271                 :             :   /* If we havn't already set up the frame pointer, do so now.  */
    9272                 :     1392283 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9273                 :             :     {
    9274                 :           0 :       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
    9275                 :           0 :                             GEN_INT (frame.stack_pointer_offset
    9276                 :             :                                      - frame.hard_frame_pointer_offset));
    9277                 :           0 :       insn = emit_insn (insn);
    9278                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9279                 :           0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
    9280                 :             : 
    9281                 :           0 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9282                 :           0 :         m->fs.cfa_reg = hard_frame_pointer_rtx;
    9283                 :           0 :       m->fs.fp_offset = frame.hard_frame_pointer_offset;
    9284                 :           0 :       m->fs.fp_valid = true;
    9285                 :             :     }
    9286                 :             : 
    9287                 :     1392283 :   if (!int_registers_saved)
    9288                 :           4 :     ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9289                 :     1392283 :   if (!sse_registers_saved)
    9290                 :       33152 :     ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9291                 :     1359131 :   else if (save_stub_call_needed)
    9292                 :        7044 :     ix86_emit_outlined_ms2sysv_save (frame);
    9293                 :             : 
    9294                 :             :   /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
    9295                 :             :      in PROLOGUE.  */
    9296                 :     1392283 :   if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
    9297                 :             :     {
    9298                 :           0 :       rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
    9299                 :           0 :       insn = emit_insn (gen_set_got (pic));
    9300                 :           0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9301                 :           0 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    9302                 :           0 :       emit_insn (gen_prologue_use (pic));
    9303                 :             :       /* Deleting already emmitted SET_GOT if exist and allocated to
    9304                 :             :          REAL_PIC_OFFSET_TABLE_REGNUM.  */
    9305                 :           0 :       ix86_elim_entry_set_got (pic);
    9306                 :             :     }
    9307                 :             : 
    9308                 :     1392283 :   if (crtl->drap_reg && !crtl->stack_realign_needed)
    9309                 :             :     {
    9310                 :             :       /* vDRAP is setup but after reload it turns out stack realign
    9311                 :             :          isn't necessary, here we will emit prologue to setup DRAP
    9312                 :             :          without stack realign adjustment */
    9313                 :         157 :       t = choose_baseaddr (0, NULL);
    9314                 :         157 :       emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9315                 :             :     }
    9316                 :             : 
    9317                 :             :   /* Prevent instructions from being scheduled into register save push
    9318                 :             :      sequence when access to the redzone area is done through frame pointer.
    9319                 :             :      The offset between the frame pointer and the stack pointer is calculated
    9320                 :             :      relative to the value of the stack pointer at the end of the function
    9321                 :             :      prologue, and moving instructions that access redzone area via frame
    9322                 :             :      pointer inside push sequence violates this assumption.  */
    9323                 :     1392283 :   if (frame_pointer_needed && frame.red_zone_size)
    9324                 :      121875 :     emit_insn (gen_memory_blockage ());
    9325                 :             : 
    9326                 :             :   /* SEH requires that the prologue end within 256 bytes of the start of
    9327                 :             :      the function.  Prevent instruction schedules that would extend that.
    9328                 :             :      Further, prevent alloca modifications to the stack pointer from being
    9329                 :             :      combined with prologue modifications.  */
    9330                 :             :   if (TARGET_SEH)
    9331                 :             :     emit_insn (gen_prologue_use (stack_pointer_rtx));
    9332                 :             : }
    9333                 :             : 
    9334                 :             : /* Emit code to restore REG using a POP or POPP insn.  */
    9335                 :             : 
    9336                 :             : static void
    9337                 :     1564773 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
    9338                 :             : {
    9339                 :     1564773 :   struct machine_function *m = cfun->machine;
    9340                 :     1564773 :   rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
    9341                 :             : 
    9342                 :     1564773 :   ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
    9343                 :     1564773 :   m->fs.sp_offset -= UNITS_PER_WORD;
    9344                 :             : 
    9345                 :     1564773 :   if (m->fs.cfa_reg == crtl->drap_reg
    9346                 :     1564773 :       && REGNO (reg) == REGNO (crtl->drap_reg))
    9347                 :             :     {
    9348                 :             :       /* Previously we'd represented the CFA as an expression
    9349                 :             :          like *(%ebp - 8).  We've just popped that value from
    9350                 :             :          the stack, which means we need to reset the CFA to
    9351                 :             :          the drap register.  This will remain until we restore
    9352                 :             :          the stack pointer.  */
    9353                 :        4185 :       add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9354                 :        4185 :       RTX_FRAME_RELATED_P (insn) = 1;
    9355                 :             : 
    9356                 :             :       /* This means that the DRAP register is valid for addressing too.  */
    9357                 :        4185 :       m->fs.drap_valid = true;
    9358                 :        4185 :       return;
    9359                 :             :     }
    9360                 :             : 
    9361                 :     1560588 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9362                 :             :     {
    9363                 :     1336501 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    9364                 :     1128239 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9365                 :     1128239 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9366                 :     1128239 :       RTX_FRAME_RELATED_P (insn) = 1;
    9367                 :             : 
    9368                 :     1336501 :       m->fs.cfa_offset -= UNITS_PER_WORD;
    9369                 :             :     }
    9370                 :             : 
    9371                 :             :   /* When the frame pointer is the CFA, and we pop it, we are
    9372                 :             :      swapping back to the stack pointer as the CFA.  This happens
    9373                 :             :      for stack frames that don't allocate other data, so we assume
    9374                 :             :      the stack pointer is now pointing at the return address, i.e.
    9375                 :             :      the function entry state, which makes the offset be 1 word.  */
    9376                 :     1560588 :   if (reg == hard_frame_pointer_rtx)
    9377                 :             :     {
    9378                 :      226792 :       m->fs.fp_valid = false;
    9379                 :      226792 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9380                 :             :         {
    9381                 :      222592 :           m->fs.cfa_reg = stack_pointer_rtx;
    9382                 :      222592 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    9383                 :             : 
    9384                 :      222592 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9385                 :      222592 :                         plus_constant (Pmode, stack_pointer_rtx,
    9386                 :      222592 :                                        m->fs.cfa_offset));
    9387                 :      222592 :           RTX_FRAME_RELATED_P (insn) = 1;
    9388                 :             :         }
    9389                 :             :     }
    9390                 :             : }
    9391                 :             : 
    9392                 :             : /* Emit code to restore REG using a POP2 insn.  */
    9393                 :             : static void
    9394                 :          15 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
    9395                 :             : {
    9396                 :          15 :   struct machine_function *m = cfun->machine;
    9397                 :          15 :   const int offset = UNITS_PER_WORD * 2;
    9398                 :          15 :   rtx_insn *insn;
    9399                 :             : 
    9400                 :          15 :   rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
    9401                 :             :                                                    stack_pointer_rtx));
    9402                 :             : 
    9403                 :          15 :   if (ppx_p)
    9404                 :          11 :     insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
    9405                 :             :   else
    9406                 :           4 :     insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
    9407                 :             : 
    9408                 :          15 :   RTX_FRAME_RELATED_P (insn) = 1;
    9409                 :             : 
    9410                 :          15 :   rtx dwarf = NULL_RTX;
    9411                 :          15 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
    9412                 :          15 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
    9413                 :          15 :   REG_NOTES (insn) = dwarf;
    9414                 :          15 :   m->fs.sp_offset -= offset;
    9415                 :             : 
    9416                 :          15 :   if (m->fs.cfa_reg == crtl->drap_reg
    9417                 :          15 :       && (REGNO (reg1) == REGNO (crtl->drap_reg)
    9418                 :           3 :           || REGNO (reg2) == REGNO (crtl->drap_reg)))
    9419                 :             :     {
    9420                 :             :       /* Previously we'd represented the CFA as an expression
    9421                 :             :          like *(%ebp - 8).  We've just popped that value from
    9422                 :             :          the stack, which means we need to reset the CFA to
    9423                 :             :          the drap register.  This will remain until we restore
    9424                 :             :          the stack pointer.  */
    9425                 :           1 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9426                 :           1 :                     REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
    9427                 :           1 :       RTX_FRAME_RELATED_P (insn) = 1;
    9428                 :             : 
    9429                 :             :       /* This means that the DRAP register is valid for addressing too.  */
    9430                 :           1 :       m->fs.drap_valid = true;
    9431                 :           1 :       return;
    9432                 :             :     }
    9433                 :             : 
    9434                 :          14 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9435                 :             :     {
    9436                 :          10 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    9437                 :          10 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9438                 :          10 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9439                 :          10 :       RTX_FRAME_RELATED_P (insn) = 1;
    9440                 :             : 
    9441                 :          10 :       m->fs.cfa_offset -= offset;
    9442                 :             :     }
    9443                 :             : 
    9444                 :             :   /* When the frame pointer is the CFA, and we pop it, we are
    9445                 :             :      swapping back to the stack pointer as the CFA.  This happens
    9446                 :             :      for stack frames that don't allocate other data, so we assume
    9447                 :             :      the stack pointer is now pointing at the return address, i.e.
    9448                 :             :      the function entry state, which makes the offset be 1 word.  */
    9449                 :          14 :   if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
    9450                 :             :     {
    9451                 :           0 :       m->fs.fp_valid = false;
    9452                 :           0 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9453                 :             :         {
    9454                 :           0 :           m->fs.cfa_reg = stack_pointer_rtx;
    9455                 :           0 :           m->fs.cfa_offset -= offset;
    9456                 :             : 
    9457                 :           0 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9458                 :           0 :                         plus_constant (Pmode, stack_pointer_rtx,
    9459                 :           0 :                                        m->fs.cfa_offset));
    9460                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9461                 :             :         }
    9462                 :             :     }
    9463                 :             : }
    9464                 :             : 
    9465                 :             : /* Emit code to restore saved registers using POP insns.  */
    9466                 :             : 
    9467                 :             : static void
    9468                 :     1269402 : ix86_emit_restore_regs_using_pop (bool ppx_p)
    9469                 :             : {
    9470                 :     1269402 :   unsigned int regno;
    9471                 :             : 
    9472                 :   118054386 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9473                 :   116784984 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
    9474                 :     1337728 :       ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
    9475                 :     1269402 : }
    9476                 :             : 
    9477                 :             : /* Emit code to restore saved registers using POP2 insns.  */
    9478                 :             : 
    9479                 :             : static void
    9480                 :         397 : ix86_emit_restore_regs_using_pop2 (void)
    9481                 :             : {
    9482                 :         397 :   int regno;
    9483                 :         397 :   int regno_list[2];
    9484                 :         397 :   regno_list[0] = regno_list[1] = -1;
    9485                 :         397 :   int loaded_regnum = 0;
    9486                 :         397 :   bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    9487                 :             : 
    9488                 :       36921 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9489                 :       36524 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
    9490                 :             :       {
    9491                 :          41 :         if (aligned)
    9492                 :             :           {
    9493                 :          35 :             regno_list[loaded_regnum++] = regno;
    9494                 :          35 :             if (loaded_regnum == 2)
    9495                 :             :               {
    9496                 :          15 :                 gcc_assert (regno_list[0] != -1
    9497                 :             :                             && regno_list[1] != -1
    9498                 :             :                             && regno_list[0] != regno_list[1]);
    9499                 :             : 
    9500                 :          15 :                 ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
    9501                 :             :                                                                regno_list[0]),
    9502                 :             :                                                   gen_rtx_REG (word_mode,
    9503                 :             :                                                                regno_list[1]),
    9504                 :          15 :                                                   TARGET_APX_PPX);
    9505                 :          15 :                 loaded_regnum = 0;
    9506                 :          15 :                 regno_list[0] = regno_list[1] = -1;
    9507                 :             :               }
    9508                 :             :           }
    9509                 :             :         else
    9510                 :             :           {
    9511                 :          12 :             ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
    9512                 :           6 :                                              TARGET_APX_PPX);
    9513                 :           6 :             aligned = true;
    9514                 :             :           }
    9515                 :             :       }
    9516                 :             : 
    9517                 :         397 :   if (loaded_regnum == 1)
    9518                 :           5 :     ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
    9519                 :           5 :                                      TARGET_APX_PPX);
    9520                 :         397 : }
    9521                 :             : 
    9522                 :             : /* Emit code and notes for the LEAVE instruction.  If insn is non-null,
    9523                 :             :    omits the emit and only attaches the notes.  */
    9524                 :             : 
    9525                 :             : static void
    9526                 :      233774 : ix86_emit_leave (rtx_insn *insn)
    9527                 :             : {
    9528                 :      233774 :   struct machine_function *m = cfun->machine;
    9529                 :             : 
    9530                 :      233774 :   if (!insn)
    9531                 :      232643 :     insn = emit_insn (gen_leave (word_mode));
    9532                 :             : 
    9533                 :      233774 :   ix86_add_queued_cfa_restore_notes (insn);
    9534                 :             : 
    9535                 :      233774 :   gcc_assert (m->fs.fp_valid);
    9536                 :      233774 :   m->fs.sp_valid = true;
    9537                 :      233774 :   m->fs.sp_realigned = false;
    9538                 :      233774 :   m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
    9539                 :      233774 :   m->fs.fp_valid = false;
    9540                 :             : 
    9541                 :      233774 :   if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9542                 :             :     {
    9543                 :      231020 :       m->fs.cfa_reg = stack_pointer_rtx;
    9544                 :      231020 :       m->fs.cfa_offset = m->fs.sp_offset;
    9545                 :             : 
    9546                 :      231020 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9547                 :      231020 :                     plus_constant (Pmode, stack_pointer_rtx,
    9548                 :      231020 :                                    m->fs.sp_offset));
    9549                 :      231020 :       RTX_FRAME_RELATED_P (insn) = 1;
    9550                 :             :     }
    9551                 :      233774 :   ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
    9552                 :             :                              m->fs.fp_offset);
    9553                 :      233774 : }
    9554                 :             : 
    9555                 :             : /* Emit code to restore saved registers using MOV insns.
    9556                 :             :    First register is restored from CFA - CFA_OFFSET.  */
    9557                 :             : static void
    9558                 :       41621 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
    9559                 :             :                                   bool maybe_eh_return)
    9560                 :             : {
    9561                 :       41621 :   struct machine_function *m = cfun->machine;
    9562                 :       41621 :   unsigned int regno;
    9563                 :             : 
    9564                 :     3870753 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9565                 :     3829132 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
    9566                 :             :       {
    9567                 :       41840 :         rtx reg = gen_rtx_REG (word_mode, regno);
    9568                 :       41840 :         rtx mem;
    9569                 :       41840 :         rtx_insn *insn;
    9570                 :             : 
    9571                 :       41840 :         mem = choose_baseaddr (cfa_offset, NULL);
    9572                 :       41840 :         mem = gen_frame_mem (word_mode, mem);
    9573                 :       41840 :         insn = emit_move_insn (reg, mem);
    9574                 :             : 
    9575                 :       41840 :         if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
    9576                 :             :           {
    9577                 :             :             /* Previously we'd represented the CFA as an expression
    9578                 :             :                like *(%ebp - 8).  We've just popped that value from
    9579                 :             :                the stack, which means we need to reset the CFA to
    9580                 :             :                the drap register.  This will remain until we restore
    9581                 :             :                the stack pointer.  */
    9582                 :        2754 :             add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9583                 :        2754 :             RTX_FRAME_RELATED_P (insn) = 1;
    9584                 :             : 
    9585                 :             :             /* This means that the DRAP register is valid for addressing.  */
    9586                 :        2754 :             m->fs.drap_valid = true;
    9587                 :             :           }
    9588                 :             :         else
    9589                 :       39086 :           ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
    9590                 :             : 
    9591                 :       43669 :         cfa_offset -= UNITS_PER_WORD;
    9592                 :             :       }
    9593                 :       41621 : }
    9594                 :             : 
    9595                 :             : /* Emit code to restore saved registers using MOV insns.
    9596                 :             :    First register is restored from CFA - CFA_OFFSET.  */
    9597                 :             : static void
    9598                 :       33729 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
    9599                 :             :                                       bool maybe_eh_return)
    9600                 :             : {
    9601                 :       33729 :   unsigned int regno;
    9602                 :             : 
    9603                 :     3136797 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    9604                 :     3103068 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
    9605                 :             :       {
    9606                 :      337281 :         rtx reg = gen_rtx_REG (V4SFmode, regno);
    9607                 :      337281 :         rtx mem;
    9608                 :      337281 :         unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
    9609                 :             : 
    9610                 :      337281 :         mem = choose_baseaddr (cfa_offset, &align);
    9611                 :      337281 :         mem = gen_rtx_MEM (V4SFmode, mem);
    9612                 :             : 
    9613                 :             :         /* The location aligment depends upon the base register.  */
    9614                 :      337281 :         align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
    9615                 :      337281 :         gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    9616                 :      337281 :         set_mem_align (mem, align);
    9617                 :      337281 :         emit_insn (gen_rtx_SET (reg, mem));
    9618                 :             : 
    9619                 :      337281 :         ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
    9620                 :             : 
    9621                 :      337281 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    9622                 :             :       }
    9623                 :       33729 : }
    9624                 :             : 
    9625                 :             : static void
    9626                 :        7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
    9627                 :             :                                   bool use_call, int style)
    9628                 :             : {
    9629                 :        7621 :   struct machine_function *m = cfun->machine;
    9630                 :        7621 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    9631                 :        7621 :                           + m->call_ms2sysv_extra_regs;
    9632                 :        7621 :   rtvec v;
    9633                 :        7621 :   unsigned int elems_needed, align, i, vi = 0;
    9634                 :        7621 :   rtx_insn *insn;
    9635                 :        7621 :   rtx sym, tmp;
    9636                 :        7621 :   rtx rsi = gen_rtx_REG (word_mode, SI_REG);
    9637                 :        7621 :   rtx r10 = NULL_RTX;
    9638                 :        7621 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    9639                 :        7621 :   HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
    9640                 :        7621 :   HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
    9641                 :        7621 :   rtx rsi_frame_load = NULL_RTX;
    9642                 :        7621 :   HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
    9643                 :        7621 :   enum xlogue_stub stub;
    9644                 :             : 
    9645                 :        7621 :   gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
    9646                 :             : 
    9647                 :             :   /* If using a realigned stack, we should never start with padding.  */
    9648                 :        7621 :   gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
    9649                 :             : 
    9650                 :             :   /* Setup RSI as the stub's base pointer.  */
    9651                 :        7621 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    9652                 :        7621 :   tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
    9653                 :        7621 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    9654                 :             : 
    9655                 :        7621 :   emit_insn (gen_rtx_SET (rsi, tmp));
    9656                 :             : 
    9657                 :             :   /* Get a symbol for the stub.  */
    9658                 :        7621 :   if (frame_pointer_needed)
    9659                 :        5955 :     stub = use_call ? XLOGUE_STUB_RESTORE_HFP
    9660                 :             :                     : XLOGUE_STUB_RESTORE_HFP_TAIL;
    9661                 :             :   else
    9662                 :        1666 :     stub = use_call ? XLOGUE_STUB_RESTORE
    9663                 :             :                     : XLOGUE_STUB_RESTORE_TAIL;
    9664                 :        7621 :   sym = xlogue.get_stub_rtx (stub);
    9665                 :             : 
    9666                 :        7621 :   elems_needed = ncregs;
    9667                 :        7621 :   if (use_call)
    9668                 :        6298 :     elems_needed += 1;
    9669                 :             :   else
    9670                 :        1515 :     elems_needed += frame_pointer_needed ? 5 : 3;
    9671                 :        7621 :   v = rtvec_alloc (elems_needed);
    9672                 :             : 
    9673                 :             :   /* We call the epilogue stub when we need to pop incoming args or we are
    9674                 :             :      doing a sibling call as the tail.  Otherwise, we will emit a jmp to the
    9675                 :             :      epilogue stub and it is the tail-call.  */
    9676                 :        7621 :   if (use_call)
    9677                 :        6298 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9678                 :             :   else
    9679                 :             :     {
    9680                 :        1323 :       RTVEC_ELT (v, vi++) = ret_rtx;
    9681                 :        1323 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9682                 :        1323 :       if (frame_pointer_needed)
    9683                 :             :         {
    9684                 :        1131 :           rtx rbp = gen_rtx_REG (DImode, BP_REG);
    9685                 :        1131 :           gcc_assert (m->fs.fp_valid);
    9686                 :        1131 :           gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
    9687                 :             : 
    9688                 :        1131 :           tmp = plus_constant (DImode, rbp, 8);
    9689                 :        1131 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
    9690                 :        1131 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
    9691                 :        1131 :           tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
    9692                 :        1131 :           RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
    9693                 :             :         }
    9694                 :             :       else
    9695                 :             :         {
    9696                 :             :           /* If no hard frame pointer, we set R10 to the SP restore value.  */
    9697                 :         192 :           gcc_assert (!m->fs.fp_valid);
    9698                 :         192 :           gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
    9699                 :         192 :           gcc_assert (m->fs.sp_valid);
    9700                 :             : 
    9701                 :         192 :           r10 = gen_rtx_REG (DImode, R10_REG);
    9702                 :         192 :           tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
    9703                 :         192 :           emit_insn (gen_rtx_SET (r10, tmp));
    9704                 :             : 
    9705                 :         192 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
    9706                 :             :         }
    9707                 :             :     }
    9708                 :             : 
    9709                 :             :   /* Generate frame load insns and restore notes.  */
    9710                 :      110586 :   for (i = 0; i < ncregs; ++i)
    9711                 :             :     {
    9712                 :      102965 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    9713                 :      102965 :       machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
    9714                 :      102965 :       rtx reg, frame_load;
    9715                 :             : 
    9716                 :      102965 :       reg = gen_rtx_REG (mode, r.regno);
    9717                 :      102965 :       frame_load = gen_frame_load (reg, rsi, r.offset);
    9718                 :             : 
    9719                 :             :       /* Save RSI frame load insn & note to add last.  */
    9720                 :      102965 :       if (r.regno == SI_REG)
    9721                 :             :         {
    9722                 :        7621 :           gcc_assert (!rsi_frame_load);
    9723                 :        7621 :           rsi_frame_load = frame_load;
    9724                 :        7621 :           rsi_restore_offset = r.offset;
    9725                 :             :         }
    9726                 :             :       else
    9727                 :             :         {
    9728                 :       95344 :           RTVEC_ELT (v, vi++) = frame_load;
    9729                 :       95344 :           ix86_add_cfa_restore_note (NULL, reg, r.offset);
    9730                 :             :         }
    9731                 :             :     }
    9732                 :             : 
    9733                 :             :   /* Add RSI frame load & restore note at the end.  */
    9734                 :        7621 :   gcc_assert (rsi_frame_load);
    9735                 :        7621 :   gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
    9736                 :        7621 :   RTVEC_ELT (v, vi++) = rsi_frame_load;
    9737                 :        7621 :   ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
    9738                 :             :                              rsi_restore_offset);
    9739                 :             : 
    9740                 :             :   /* Finally, for tail-call w/o a hard frame pointer, set SP to R10.  */
    9741                 :        7621 :   if (!use_call && !frame_pointer_needed)
    9742                 :             :     {
    9743                 :         192 :       gcc_assert (m->fs.sp_valid);
    9744                 :         192 :       gcc_assert (!m->fs.sp_realigned);
    9745                 :             : 
    9746                 :             :       /* At this point, R10 should point to frame.stack_realign_offset.  */
    9747                 :         192 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9748                 :         192 :         m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
    9749                 :         192 :       m->fs.sp_offset = frame.stack_realign_offset;
    9750                 :             :     }
    9751                 :             : 
    9752                 :        7621 :   gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
    9753                 :        7621 :   tmp = gen_rtx_PARALLEL (VOIDmode, v);
    9754                 :        7621 :   if (use_call)
    9755                 :        6298 :       insn = emit_insn (tmp);
    9756                 :             :   else
    9757                 :             :     {
    9758                 :        1323 :       insn = emit_jump_insn (tmp);
    9759                 :        1323 :       JUMP_LABEL (insn) = ret_rtx;
    9760                 :             : 
    9761                 :        1323 :       if (frame_pointer_needed)
    9762                 :        1131 :         ix86_emit_leave (insn);
    9763                 :             :       else
    9764                 :             :         {
    9765                 :             :           /* Need CFA adjust note.  */
    9766                 :         192 :           tmp = gen_rtx_SET (stack_pointer_rtx, r10);
    9767                 :         192 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
    9768                 :             :         }
    9769                 :             :     }
    9770                 :             : 
    9771                 :        7621 :   RTX_FRAME_RELATED_P (insn) = true;
    9772                 :        7621 :   ix86_add_queued_cfa_restore_notes (insn);
    9773                 :             : 
    9774                 :             :   /* If we're not doing a tail-call, we need to adjust the stack.  */
    9775                 :        7621 :   if (use_call && m->fs.sp_valid)
    9776                 :             :     {
    9777                 :        3586 :       HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
    9778                 :        3586 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9779                 :             :                                 GEN_INT (dealloc), style,
    9780                 :        3586 :                                 m->fs.cfa_reg == stack_pointer_rtx);
    9781                 :             :     }
    9782                 :        7621 : }
    9783                 :             : 
    9784                 :             : /* Restore function stack, frame, and registers.  */
    9785                 :             : 
    9786                 :             : void
    9787                 :     1504021 : ix86_expand_epilogue (int style)
    9788                 :             : {
    9789                 :     1504021 :   struct machine_function *m = cfun->machine;
    9790                 :     1504021 :   struct machine_frame_state frame_state_save = m->fs;
    9791                 :     1504021 :   bool restore_regs_via_mov;
    9792                 :     1504021 :   bool using_drap;
    9793                 :     1504021 :   bool restore_stub_is_tail = false;
    9794                 :             : 
    9795                 :     1504021 :   if (ix86_function_naked (current_function_decl))
    9796                 :             :     {
    9797                 :             :       /* The program should not reach this point.  */
    9798                 :          77 :       emit_insn (gen_ud2 ());
    9799                 :      111787 :       return;
    9800                 :             :     }
    9801                 :             : 
    9802                 :     1503944 :   ix86_finalize_stack_frame_flags ();
    9803                 :     1503944 :   const struct ix86_frame &frame = cfun->machine->frame;
    9804                 :             : 
    9805                 :     1503944 :   m->fs.sp_realigned = stack_realign_fp;
    9806                 :       29709 :   m->fs.sp_valid = stack_realign_fp
    9807                 :     1481175 :                    || !frame_pointer_needed
    9808                 :     1941768 :                    || crtl->sp_is_unchanging;
    9809                 :     1503944 :   gcc_assert (!m->fs.sp_valid
    9810                 :             :               || m->fs.sp_offset == frame.stack_pointer_offset);
    9811                 :             : 
    9812                 :             :   /* The FP must be valid if the frame pointer is present.  */
    9813                 :     1503944 :   gcc_assert (frame_pointer_needed == m->fs.fp_valid);
    9814                 :     1503944 :   gcc_assert (!m->fs.fp_valid
    9815                 :             :               || m->fs.fp_offset == frame.hard_frame_pointer_offset);
    9816                 :             : 
    9817                 :             :   /* We must have *some* valid pointer to the stack frame.  */
    9818                 :     1503944 :   gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
    9819                 :             : 
    9820                 :             :   /* The DRAP is never valid at this point.  */
    9821                 :     1503944 :   gcc_assert (!m->fs.drap_valid);
    9822                 :             : 
    9823                 :             :   /* See the comment about red zone and frame
    9824                 :             :      pointer usage in ix86_expand_prologue.  */
    9825                 :     1503944 :   if (frame_pointer_needed && frame.red_zone_size)
    9826                 :      121882 :     emit_insn (gen_memory_blockage ());
    9827                 :             : 
    9828                 :     1503944 :   using_drap = crtl->drap_reg && crtl->stack_realign_needed;
    9829                 :        6940 :   gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
    9830                 :             : 
    9831                 :             :   /* Determine the CFA offset of the end of the red-zone.  */
    9832                 :     1503944 :   m->fs.red_zone_offset = 0;
    9833                 :     1503944 :   if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
    9834                 :             :     {
    9835                 :             :       /* The red-zone begins below return address and error code in
    9836                 :             :          exception handler.  */
    9837                 :     1332901 :       m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
    9838                 :             : 
    9839                 :             :       /* When the register save area is in the aligned portion of
    9840                 :             :          the stack, determine the maximum runtime displacement that
    9841                 :             :          matches up with the aligned frame.  */
    9842                 :     1332901 :       if (stack_realign_drap)
    9843                 :        8146 :         m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
    9844                 :        4073 :                                   + UNITS_PER_WORD);
    9845                 :             :     }
    9846                 :             : 
    9847                 :     1503944 :   HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
    9848                 :             : 
    9849                 :             :   /* Special care must be taken for the normal return case of a function
    9850                 :             :      using eh_return: the eax and edx registers are marked as saved, but
    9851                 :             :      not restored along this path.  Adjust the save location to match.  */
    9852                 :     1503944 :   if (crtl->calls_eh_return && style != 2)
    9853                 :          36 :     reg_save_offset -= 2 * UNITS_PER_WORD;
    9854                 :             : 
    9855                 :             :   /* EH_RETURN requires the use of moves to function properly.  */
    9856                 :     1503944 :   if (crtl->calls_eh_return)
    9857                 :             :     restore_regs_via_mov = true;
    9858                 :             :   /* SEH requires the use of pops to identify the epilogue.  */
    9859                 :     1503888 :   else if (TARGET_SEH)
    9860                 :             :     restore_regs_via_mov = false;
    9861                 :             :   /* If we're only restoring one register and sp cannot be used then
    9862                 :             :      using a move instruction to restore the register since it's
    9863                 :             :      less work than reloading sp and popping the register.  */
    9864                 :     1503888 :   else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
    9865                 :             :     restore_regs_via_mov = true;
    9866                 :     1446152 :   else if (TARGET_EPILOGUE_USING_MOVE
    9867                 :       51418 :            && cfun->machine->use_fast_prologue_epilogue
    9868                 :       51238 :            && (frame.nregs > 1
    9869                 :       51231 :                || m->fs.sp_offset != reg_save_offset))
    9870                 :             :     restore_regs_via_mov = true;
    9871                 :     1445950 :   else if (frame_pointer_needed
    9872                 :      402635 :            && !frame.nregs
    9873                 :      310806 :            && m->fs.sp_offset != reg_save_offset)
    9874                 :             :     restore_regs_via_mov = true;
    9875                 :     1298167 :   else if (frame_pointer_needed
    9876                 :      254852 :            && TARGET_USE_LEAVE
    9877                 :      254818 :            && cfun->machine->use_fast_prologue_epilogue
    9878                 :      199940 :            && frame.nregs == 1)
    9879                 :             :     restore_regs_via_mov = true;
    9880                 :             :   else
    9881                 :     1269991 :     restore_regs_via_mov = false;
    9882                 :             : 
    9883                 :     1269991 :   if (restore_regs_via_mov || frame.nsseregs)
    9884                 :             :     {
    9885                 :             :       /* Ensure that the entire register save area is addressable via
    9886                 :             :          the stack pointer, if we will restore SSE regs via sp.  */
    9887                 :      267679 :       if (TARGET_64BIT
    9888                 :      260448 :           && m->fs.sp_offset > 0x7fffffff
    9889                 :          23 :           && sp_valid_at (frame.stack_realign_offset + 1)
    9890                 :      267701 :           && (frame.nsseregs + frame.nregs) != 0)
    9891                 :             :         {
    9892                 :           6 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9893                 :           6 :                                      GEN_INT (m->fs.sp_offset
    9894                 :             :                                               - frame.sse_reg_save_offset),
    9895                 :             :                                      style,
    9896                 :           6 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    9897                 :             :         }
    9898                 :             :     }
    9899                 :             : 
    9900                 :             :   /* If there are any SSE registers to restore, then we have to do it
    9901                 :             :      via moves, since there's obviously no pop for SSE regs.  */
    9902                 :     1503944 :   if (frame.nsseregs)
    9903                 :       33729 :     ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
    9904                 :             :                                           style == 2);
    9905                 :             : 
    9906                 :     1503944 :   if (m->call_ms2sysv)
    9907                 :             :     {
    9908                 :        7621 :       int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
    9909                 :             : 
    9910                 :             :       /* We cannot use a tail-call for the stub if:
    9911                 :             :          1. We have to pop incoming args,
    9912                 :             :          2. We have additional int regs to restore, or
    9913                 :             :          3. A sibling call will be the tail-call, or
    9914                 :             :          4. We are emitting an eh_return_internal epilogue.
    9915                 :             : 
    9916                 :             :          TODO: Item 4 has not yet tested!
    9917                 :             : 
    9918                 :             :          If any of the above are true, we will call the stub rather than
    9919                 :             :          jump to it.  */
    9920                 :        7621 :       restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
    9921                 :        7621 :       ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
    9922                 :             :     }
    9923                 :             : 
    9924                 :             :   /* If using out-of-line stub that is a tail-call, then...*/
    9925                 :     1503944 :   if (m->call_ms2sysv && restore_stub_is_tail)
    9926                 :             :     {
    9927                 :             :       /* TODO: parinoid tests. (remove eventually)  */
    9928                 :        1323 :       gcc_assert (m->fs.sp_valid);
    9929                 :        1323 :       gcc_assert (!m->fs.sp_realigned);
    9930                 :        1323 :       gcc_assert (!m->fs.fp_valid);
    9931                 :        1323 :       gcc_assert (!m->fs.realigned);
    9932                 :        1323 :       gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
    9933                 :        1323 :       gcc_assert (!crtl->drap_reg);
    9934                 :        1323 :       gcc_assert (!frame.nregs);
    9935                 :             :     }
    9936                 :     1502621 :   else if (restore_regs_via_mov)
    9937                 :             :     {
    9938                 :      232822 :       rtx t;
    9939                 :             : 
    9940                 :      232822 :       if (frame.nregs)
    9941                 :       41621 :         ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
    9942                 :             : 
    9943                 :             :       /* eh_return epilogues need %ecx added to the stack pointer.  */
    9944                 :      232822 :       if (style == 2)
    9945                 :             :         {
    9946                 :          28 :           rtx sa = EH_RETURN_STACKADJ_RTX;
    9947                 :          28 :           rtx_insn *insn;
    9948                 :             : 
    9949                 :             :           /* Stack realignment doesn't work with eh_return.  */
    9950                 :          28 :           if (crtl->stack_realign_needed)
    9951                 :           0 :             sorry ("Stack realignment not supported with "
    9952                 :             :                    "%<__builtin_eh_return%>");
    9953                 :             : 
    9954                 :             :           /* regparm nested functions don't work with eh_return.  */
    9955                 :          28 :           if (ix86_static_chain_on_stack)
    9956                 :           0 :             sorry ("regparm nested function not supported with "
    9957                 :             :                    "%<__builtin_eh_return%>");
    9958                 :             : 
    9959                 :          28 :           if (frame_pointer_needed)
    9960                 :             :             {
    9961                 :          27 :               t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
    9962                 :          35 :               t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
    9963                 :          27 :               emit_insn (gen_rtx_SET (sa, t));
    9964                 :             : 
    9965                 :             :               /* NB: eh_return epilogues must restore the frame pointer
    9966                 :             :                  in word_mode since the upper 32 bits of RBP register
    9967                 :             :                  can have any values.  */
    9968                 :          27 :               t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
    9969                 :          27 :               rtx frame_reg = gen_rtx_REG (word_mode,
    9970                 :             :                                            HARD_FRAME_POINTER_REGNUM);
    9971                 :          27 :               insn = emit_move_insn (frame_reg, t);
    9972                 :             : 
    9973                 :             :               /* Note that we use SA as a temporary CFA, as the return
    9974                 :             :                  address is at the proper place relative to it.  We
    9975                 :             :                  pretend this happens at the FP restore insn because
    9976                 :             :                  prior to this insn the FP would be stored at the wrong
    9977                 :             :                  offset relative to SA, and after this insn we have no
    9978                 :             :                  other reasonable register to use for the CFA.  We don't
    9979                 :             :                  bother resetting the CFA to the SP for the duration of
    9980                 :             :                  the return insn, unless the control flow instrumentation
    9981                 :             :                  is done.  In this case the SP is used later and we have
    9982                 :             :                  to reset CFA to SP.  */
    9983                 :          35 :               add_reg_note (insn, REG_CFA_DEF_CFA,
    9984                 :          35 :                             plus_constant (Pmode, sa, UNITS_PER_WORD));
    9985                 :          27 :               ix86_add_queued_cfa_restore_notes (insn);
    9986                 :          27 :               add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
    9987                 :          27 :               RTX_FRAME_RELATED_P (insn) = 1;
    9988                 :             : 
    9989                 :          27 :               m->fs.cfa_reg = sa;
    9990                 :          27 :               m->fs.cfa_offset = UNITS_PER_WORD;
    9991                 :          27 :               m->fs.fp_valid = false;
    9992                 :             : 
    9993                 :          27 :               pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
    9994                 :             :                                          const0_rtx, style,
    9995                 :          27 :                                          flag_cf_protection);
    9996                 :             :             }
    9997                 :             :           else
    9998                 :             :             {
    9999                 :           1 :               t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
   10000                 :           1 :               t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
   10001                 :           1 :               insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
   10002                 :           1 :               ix86_add_queued_cfa_restore_notes (insn);
   10003                 :             : 
   10004                 :           1 :               gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10005                 :           1 :               if (m->fs.cfa_offset != UNITS_PER_WORD)
   10006                 :             :                 {
   10007                 :           1 :                   m->fs.cfa_offset = UNITS_PER_WORD;
   10008                 :           1 :                   add_reg_note (insn, REG_CFA_DEF_CFA,
   10009                 :           1 :                                 plus_constant (Pmode, stack_pointer_rtx,
   10010                 :           1 :                                                UNITS_PER_WORD));
   10011                 :           1 :                   RTX_FRAME_RELATED_P (insn) = 1;
   10012                 :             :                 }
   10013                 :             :             }
   10014                 :          28 :           m->fs.sp_offset = UNITS_PER_WORD;
   10015                 :          28 :           m->fs.sp_valid = true;
   10016                 :          28 :           m->fs.sp_realigned = false;
   10017                 :             :         }
   10018                 :             :     }
   10019                 :             :   else
   10020                 :             :     {
   10021                 :             :       /* SEH requires that the function end with (1) a stack adjustment
   10022                 :             :          if necessary, (2) a sequence of pops, and (3) a return or
   10023                 :             :          jump instruction.  Prevent insns from the function body from
   10024                 :             :          being scheduled into this sequence.  */
   10025                 :     1269799 :       if (TARGET_SEH)
   10026                 :             :         {
   10027                 :             :           /* Prevent a catch region from being adjacent to the standard
   10028                 :             :              epilogue sequence.  Unfortunately neither crtl->uses_eh_lsda
   10029                 :             :              nor several other flags that would be interesting to test are
   10030                 :             :              set up yet.  */
   10031                 :             :           if (flag_non_call_exceptions)
   10032                 :             :             emit_insn (gen_nops (const1_rtx));
   10033                 :             :           else
   10034                 :             :             emit_insn (gen_blockage ());
   10035                 :             :         }
   10036                 :             : 
   10037                 :             :       /* First step is to deallocate the stack frame so that we can
   10038                 :             :          pop the registers.  If the stack pointer was realigned, it needs
   10039                 :             :          to be restored now.  Also do it on SEH target for very large
   10040                 :             :          frame as the emitted instructions aren't allowed by the ABI
   10041                 :             :          in epilogues.  */
   10042                 :     1269799 :       if (!m->fs.sp_valid || m->fs.sp_realigned
   10043                 :             :           || (TARGET_SEH
   10044                 :             :               && (m->fs.sp_offset - reg_save_offset
   10045                 :             :                   >= SEH_MAX_FRAME_SIZE)))
   10046                 :             :         {
   10047                 :       28935 :           pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
   10048                 :       28935 :                                      GEN_INT (m->fs.fp_offset
   10049                 :             :                                               - reg_save_offset),
   10050                 :             :                                      style, false);
   10051                 :             :         }
   10052                 :     1240864 :       else if (m->fs.sp_offset != reg_save_offset)
   10053                 :             :         {
   10054                 :      562836 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10055                 :             :                                      GEN_INT (m->fs.sp_offset
   10056                 :             :                                               - reg_save_offset),
   10057                 :             :                                      style,
   10058                 :      562836 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10059                 :             :         }
   10060                 :             : 
   10061                 :     1269799 :       if (TARGET_APX_PUSH2POP2
   10062                 :         400 :           && ix86_can_use_push2pop2 ()
   10063                 :     1270197 :           && m->func_type == TYPE_NORMAL)
   10064                 :         397 :         ix86_emit_restore_regs_using_pop2 ();
   10065                 :             :       else
   10066                 :     1269402 :         ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
   10067                 :             :     }
   10068                 :             : 
   10069                 :             :   /* If we used a stack pointer and haven't already got rid of it,
   10070                 :             :      then do so now.  */
   10071                 :     1503944 :   if (m->fs.fp_valid)
   10072                 :             :     {
   10073                 :             :       /* If the stack pointer is valid and pointing at the frame
   10074                 :             :          pointer store address, then we only need a pop.  */
   10075                 :      459435 :       if (sp_valid_at (frame.hfp_save_offset)
   10076                 :      459435 :           && m->fs.sp_offset == frame.hfp_save_offset)
   10077                 :      226778 :         ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10078                 :             :       /* Leave results in shorter dependency chains on CPUs that are
   10079                 :             :          able to grok it fast.  */
   10080                 :      232657 :       else if (TARGET_USE_LEAVE
   10081                 :          14 :                || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
   10082                 :      232671 :                || !cfun->machine->use_fast_prologue_epilogue)
   10083                 :      232643 :         ix86_emit_leave (NULL);
   10084                 :             :       else
   10085                 :             :         {
   10086                 :          14 :           pro_epilogue_adjust_stack (stack_pointer_rtx,
   10087                 :             :                                      hard_frame_pointer_rtx,
   10088                 :          14 :                                      const0_rtx, style, !using_drap);
   10089                 :          14 :           ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10090                 :             :         }
   10091                 :             :     }
   10092                 :             : 
   10093                 :     1503944 :   if (using_drap)
   10094                 :             :     {
   10095                 :        6940 :       int param_ptr_offset = UNITS_PER_WORD;
   10096                 :        6940 :       rtx_insn *insn;
   10097                 :             : 
   10098                 :        6940 :       gcc_assert (stack_realign_drap);
   10099                 :             : 
   10100                 :        6940 :       if (ix86_static_chain_on_stack)
   10101                 :           0 :         param_ptr_offset += UNITS_PER_WORD;
   10102                 :        6940 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10103                 :         242 :         param_ptr_offset += UNITS_PER_WORD;
   10104                 :             : 
   10105                 :        6940 :       insn = emit_insn (gen_rtx_SET
   10106                 :             :                         (stack_pointer_rtx,
   10107                 :             :                          plus_constant (Pmode, crtl->drap_reg,
   10108                 :             :                                         -param_ptr_offset)));
   10109                 :        6940 :       m->fs.cfa_reg = stack_pointer_rtx;
   10110                 :        6940 :       m->fs.cfa_offset = param_ptr_offset;
   10111                 :        6940 :       m->fs.sp_offset = param_ptr_offset;
   10112                 :        6940 :       m->fs.realigned = false;
   10113                 :             : 
   10114                 :        7247 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10115                 :        6940 :                     plus_constant (Pmode, stack_pointer_rtx,
   10116                 :             :                                    param_ptr_offset));
   10117                 :        6940 :       RTX_FRAME_RELATED_P (insn) = 1;
   10118                 :             : 
   10119                 :        6940 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10120                 :         242 :         ix86_emit_restore_reg_using_pop (crtl->drap_reg);
   10121                 :             :     }
   10122                 :             : 
   10123                 :             :   /* At this point the stack pointer must be valid, and we must have
   10124                 :             :      restored all of the registers.  We may not have deallocated the
   10125                 :             :      entire stack frame.  We've delayed this until now because it may
   10126                 :             :      be possible to merge the local stack deallocation with the
   10127                 :             :      deallocation forced by ix86_static_chain_on_stack.   */
   10128                 :     1503944 :   gcc_assert (m->fs.sp_valid);
   10129                 :     1503944 :   gcc_assert (!m->fs.sp_realigned);
   10130                 :     1503944 :   gcc_assert (!m->fs.fp_valid);
   10131                 :     1503944 :   gcc_assert (!m->fs.realigned);
   10132                 :     1633470 :   if (m->fs.sp_offset != UNITS_PER_WORD)
   10133                 :             :     {
   10134                 :          98 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10135                 :             :                                  GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
   10136                 :             :                                  style, true);
   10137                 :             :     }
   10138                 :             :   else
   10139                 :     1503846 :     ix86_add_queued_cfa_restore_notes (get_last_insn ());
   10140                 :             : 
   10141                 :             :   /* Sibcall epilogues don't want a return instruction.  */
   10142                 :     1503944 :   if (style == 0)
   10143                 :             :     {
   10144                 :      111633 :       m->fs = frame_state_save;
   10145                 :      111633 :       return;
   10146                 :             :     }
   10147                 :             : 
   10148                 :     1392311 :   if (cfun->machine->func_type != TYPE_NORMAL)
   10149                 :         118 :     emit_jump_insn (gen_interrupt_return ());
   10150                 :     1392193 :   else if (crtl->args.pops_args && crtl->args.size)
   10151                 :             :     {
   10152                 :       25612 :       rtx popc = GEN_INT (crtl->args.pops_args);
   10153                 :             : 
   10154                 :             :       /* i386 can only pop 64K bytes.  If asked to pop more, pop return
   10155                 :             :          address, do explicit add, and jump indirectly to the caller.  */
   10156                 :             : 
   10157                 :       25612 :       if (crtl->args.pops_args >= 65536)
   10158                 :             :         {
   10159                 :           0 :           rtx ecx = gen_rtx_REG (SImode, CX_REG);
   10160                 :           0 :           rtx_insn *insn;
   10161                 :             : 
   10162                 :             :           /* There is no "pascal" calling convention in any 64bit ABI.  */
   10163                 :           0 :           gcc_assert (!TARGET_64BIT);
   10164                 :             : 
   10165                 :           0 :           insn = emit_insn (gen_pop (ecx));
   10166                 :           0 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10167                 :           0 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10168                 :             : 
   10169                 :           0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10170                 :           0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10171                 :           0 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10172                 :           0 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10173                 :           0 :           RTX_FRAME_RELATED_P (insn) = 1;
   10174                 :             : 
   10175                 :           0 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10176                 :             :                                      popc, -1, true);
   10177                 :           0 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10178                 :             :         }
   10179                 :             :       else
   10180                 :       25612 :         emit_jump_insn (gen_simple_return_pop_internal (popc));
   10181                 :             :     }
   10182                 :     1366581 :   else if (!m->call_ms2sysv || !restore_stub_is_tail)
   10183                 :             :     {
   10184                 :             :       /* In case of return from EH a simple return cannot be used
   10185                 :             :          as a return address will be compared with a shadow stack
   10186                 :             :          return address.  Use indirect jump instead.  */
   10187                 :     1365258 :       if (style == 2 && flag_cf_protection)
   10188                 :             :         {
   10189                 :             :           /* Register used in indirect jump must be in word_mode.  But
   10190                 :             :              Pmode may not be the same as word_mode for x32.  */
   10191                 :          17 :           rtx ecx = gen_rtx_REG (word_mode, CX_REG);
   10192                 :          17 :           rtx_insn *insn;
   10193                 :             : 
   10194                 :          17 :           insn = emit_insn (gen_pop (ecx));
   10195                 :          17 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10196                 :          17 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10197                 :             : 
   10198                 :          25 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10199                 :          17 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10200                 :          17 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10201                 :          17 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10202                 :          17 :           RTX_FRAME_RELATED_P (insn) = 1;
   10203                 :             : 
   10204                 :          17 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10205                 :          17 :         }
   10206                 :             :       else
   10207                 :     1365241 :         emit_jump_insn (gen_simple_return_internal ());
   10208                 :             :     }
   10209                 :             : 
   10210                 :             :   /* Restore the state back to the state from the prologue,
   10211                 :             :      so that it's correct for the next epilogue.  */
   10212                 :     1392311 :   m->fs = frame_state_save;
   10213                 :             : }
   10214                 :             : 
   10215                 :             : /* Reset from the function's potential modifications.  */
   10216                 :             : 
   10217                 :             : static void
   10218                 :     1398289 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
   10219                 :             : {
   10220                 :     1398289 :   if (pic_offset_table_rtx
   10221                 :     1398289 :       && !ix86_use_pseudo_pic_reg ())
   10222                 :           0 :     SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
   10223                 :             : 
   10224                 :     1398289 :   if (TARGET_MACHO)
   10225                 :             :     {
   10226                 :             :       rtx_insn *insn = get_last_insn ();
   10227                 :             :       rtx_insn *deleted_debug_label = NULL;
   10228                 :             : 
   10229                 :             :       /* Mach-O doesn't support labels at the end of objects, so if
   10230                 :             :          it looks like we might want one, take special action.
   10231                 :             :         First, collect any sequence of deleted debug labels.  */
   10232                 :             :       while (insn
   10233                 :             :              && NOTE_P (insn)
   10234                 :             :              && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
   10235                 :             :         {
   10236                 :             :           /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
   10237                 :             :              notes only, instead set their CODE_LABEL_NUMBER to -1,
   10238                 :             :              otherwise there would be code generation differences
   10239                 :             :              in between -g and -g0.  */
   10240                 :             :           if (NOTE_P (insn) && NOTE_KIND (insn)
   10241                 :             :               == NOTE_INSN_DELETED_DEBUG_LABEL)
   10242                 :             :             deleted_debug_label = insn;
   10243                 :             :           insn = PREV_INSN (insn);
   10244                 :             :         }
   10245                 :             : 
   10246                 :             :       /* If we have:
   10247                 :             :          label:
   10248                 :             :             barrier
   10249                 :             :           then this needs to be detected, so skip past the barrier.  */
   10250                 :             : 
   10251                 :             :       if (insn && BARRIER_P (insn))
   10252                 :             :         insn = PREV_INSN (insn);
   10253                 :             : 
   10254                 :             :       /* Up to now we've only seen notes or barriers.  */
   10255                 :             :       if (insn)
   10256                 :             :         {
   10257                 :             :           if (LABEL_P (insn)
   10258                 :             :               || (NOTE_P (insn)
   10259                 :             :                   && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
   10260                 :             :             /* Trailing label.  */
   10261                 :             :             fputs ("\tnop\n", file);
   10262                 :             :           else if (cfun && ! cfun->is_thunk)
   10263                 :             :             {
   10264                 :             :               /* See if we have a completely empty function body, skipping
   10265                 :             :                  the special case of the picbase thunk emitted as asm.  */
   10266                 :             :               while (insn && ! INSN_P (insn))
   10267                 :             :                 insn = PREV_INSN (insn);
   10268                 :             :               /* If we don't find any insns, we've got an empty function body;
   10269                 :             :                  I.e. completely empty - without a return or branch.  This is
   10270                 :             :                  taken as the case where a function body has been removed
   10271                 :             :                  because it contains an inline __builtin_unreachable().  GCC
   10272                 :             :                  declares that reaching __builtin_unreachable() means UB so
   10273                 :             :                  we're not obliged to do anything special; however, we want
   10274                 :             :                  non-zero-sized function bodies.  To meet this, and help the
   10275                 :             :                  user out, let's trap the case.  */
   10276                 :             :               if (insn == NULL)
   10277                 :             :                 fputs ("\tud2\n", file);
   10278                 :             :             }
   10279                 :             :         }
   10280                 :             :       else if (deleted_debug_label)
   10281                 :             :         for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
   10282                 :             :           if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
   10283                 :             :             CODE_LABEL_NUMBER (insn) = -1;
   10284                 :             :     }
   10285                 :     1398289 : }
   10286                 :             : 
   10287                 :             : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY.  */
   10288                 :             : 
   10289                 :             : void
   10290                 :          70 : ix86_print_patchable_function_entry (FILE *file,
   10291                 :             :                                      unsigned HOST_WIDE_INT patch_area_size,
   10292                 :             :                                      bool record_p)
   10293                 :             : {
   10294                 :          70 :   if (cfun->machine->function_label_emitted)
   10295                 :             :     {
   10296                 :             :       /* NB: When ix86_print_patchable_function_entry is called after
   10297                 :             :          function table has been emitted, we have inserted or queued
   10298                 :             :          a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
   10299                 :             :          place.  There is nothing to do here.  */
   10300                 :             :       return;
   10301                 :             :     }
   10302                 :             : 
   10303                 :           9 :   default_print_patchable_function_entry (file, patch_area_size,
   10304                 :             :                                           record_p);
   10305                 :             : }
   10306                 :             : 
   10307                 :             : /* Output patchable area.  NB: default_print_patchable_function_entry
   10308                 :             :    isn't available in i386.md.  */
   10309                 :             : 
   10310                 :             : void
   10311                 :          61 : ix86_output_patchable_area (unsigned int patch_area_size,
   10312                 :             :                             bool record_p)
   10313                 :             : {
   10314                 :          61 :   default_print_patchable_function_entry (asm_out_file,
   10315                 :             :                                           patch_area_size,
   10316                 :             :                                           record_p);
   10317                 :          61 : }
   10318                 :             : 
   10319                 :             : /* Return a scratch register to use in the split stack prologue.  The
   10320                 :             :    split stack prologue is used for -fsplit-stack.  It is the first
   10321                 :             :    instructions in the function, even before the regular prologue.
   10322                 :             :    The scratch register can be any caller-saved register which is not
   10323                 :             :    used for parameters or for the static chain.  */
   10324                 :             : 
   10325                 :             : static unsigned int
   10326                 :       24254 : split_stack_prologue_scratch_regno (void)
   10327                 :             : {
   10328                 :       24254 :   if (TARGET_64BIT)
   10329                 :             :     return R11_REG;
   10330                 :             :   else
   10331                 :             :     {
   10332                 :        7209 :       bool is_fastcall, is_thiscall;
   10333                 :        7209 :       int regparm;
   10334                 :             : 
   10335                 :        7209 :       is_fastcall = (lookup_attribute ("fastcall",
   10336                 :        7209 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10337                 :             :                      != NULL);
   10338                 :        7209 :       is_thiscall = (lookup_attribute ("thiscall",
   10339                 :        7209 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10340                 :             :                      != NULL);
   10341                 :        7209 :       regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
   10342                 :             : 
   10343                 :        7209 :       if (is_fastcall)
   10344                 :             :         {
   10345                 :           0 :           if (DECL_STATIC_CHAIN (cfun->decl))
   10346                 :             :             {
   10347                 :           0 :               sorry ("%<-fsplit-stack%> does not support fastcall with "
   10348                 :             :                      "nested function");
   10349                 :           0 :               return INVALID_REGNUM;
   10350                 :             :             }
   10351                 :             :           return AX_REG;
   10352                 :             :         }
   10353                 :        7209 :       else if (is_thiscall)
   10354                 :             :         {
   10355                 :           0 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10356                 :             :             return DX_REG;
   10357                 :           0 :           return AX_REG;
   10358                 :             :         }
   10359                 :        7209 :       else if (regparm < 3)
   10360                 :             :         {
   10361                 :        7209 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10362                 :             :             return CX_REG;
   10363                 :             :           else
   10364                 :             :             {
   10365                 :         475 :               if (regparm >= 2)
   10366                 :             :                 {
   10367                 :           0 :                   sorry ("%<-fsplit-stack%> does not support 2 register "
   10368                 :             :                          "parameters for a nested function");
   10369                 :           0 :                   return INVALID_REGNUM;
   10370                 :             :                 }
   10371                 :             :               return DX_REG;
   10372                 :             :             }
   10373                 :             :         }
   10374                 :             :       else
   10375                 :             :         {
   10376                 :             :           /* FIXME: We could make this work by pushing a register
   10377                 :             :              around the addition and comparison.  */
   10378                 :           0 :           sorry ("%<-fsplit-stack%> does not support 3 register parameters");
   10379                 :           0 :           return INVALID_REGNUM;
   10380                 :             :         }
   10381                 :             :     }
   10382                 :             : }
   10383                 :             : 
   10384                 :             : /* A SYMBOL_REF for the function which allocates new stackspace for
   10385                 :             :    -fsplit-stack.  */
   10386                 :             : 
   10387                 :             : static GTY(()) rtx split_stack_fn;
   10388                 :             : 
   10389                 :             : /* A SYMBOL_REF for the more stack function when using the large
   10390                 :             :    model.  */
   10391                 :             : 
   10392                 :             : static GTY(()) rtx split_stack_fn_large;
   10393                 :             : 
   10394                 :             : /* Return location of the stack guard value in the TLS block.  */
   10395                 :             : 
   10396                 :             : rtx
   10397                 :      259785 : ix86_split_stack_guard (void)
   10398                 :             : {
   10399                 :      259785 :   int offset;
   10400                 :      259785 :   addr_space_t as = DEFAULT_TLS_SEG_REG;
   10401                 :      259785 :   rtx r;
   10402                 :             : 
   10403                 :      259785 :   gcc_assert (flag_split_stack);
   10404                 :             : 
   10405                 :             : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
   10406                 :      259785 :   offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
   10407                 :             : #else
   10408                 :             :   gcc_unreachable ();
   10409                 :             : #endif
   10410                 :             : 
   10411                 :      259785 :   r = GEN_INT (offset);
   10412                 :      259785 :   r = gen_const_mem (Pmode, r);
   10413                 :      259785 :   set_mem_addr_space (r, as);
   10414                 :             : 
   10415                 :      259785 :   return r;
   10416                 :             : }
   10417                 :             : 
   10418                 :             : /* Handle -fsplit-stack.  These are the first instructions in the
   10419                 :             :    function, even before the regular prologue.  */
   10420                 :             : 
   10421                 :             : void
   10422                 :      259776 : ix86_expand_split_stack_prologue (void)
   10423                 :             : {
   10424                 :      259776 :   HOST_WIDE_INT allocate;
   10425                 :      259776 :   unsigned HOST_WIDE_INT args_size;
   10426                 :      259776 :   rtx_code_label *label;
   10427                 :      259776 :   rtx limit, current, allocate_rtx, call_fusage;
   10428                 :      259776 :   rtx_insn *call_insn;
   10429                 :      259776 :   unsigned int scratch_regno = INVALID_REGNUM;
   10430                 :      259776 :   rtx scratch_reg = NULL_RTX;
   10431                 :      259776 :   rtx_code_label *varargs_label = NULL;
   10432                 :      259776 :   rtx fn;
   10433                 :             : 
   10434                 :      259776 :   gcc_assert (flag_split_stack && reload_completed);
   10435                 :             : 
   10436                 :      259776 :   ix86_finalize_stack_frame_flags ();
   10437                 :      259776 :   struct ix86_frame &frame = cfun->machine->frame;
   10438                 :      259776 :   allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
   10439                 :             : 
   10440                 :             :   /* This is the label we will branch to if we have enough stack
   10441                 :             :      space.  We expect the basic block reordering pass to reverse this
   10442                 :             :      branch if optimizing, so that we branch in the unlikely case.  */
   10443                 :      259776 :   label = gen_label_rtx ();
   10444                 :             : 
   10445                 :             :   /* We need to compare the stack pointer minus the frame size with
   10446                 :             :      the stack boundary in the TCB.  The stack boundary always gives
   10447                 :             :      us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
   10448                 :             :      can compare directly.  Otherwise we need to do an addition.  */
   10449                 :             : 
   10450                 :      259776 :   limit = ix86_split_stack_guard ();
   10451                 :             : 
   10452                 :      259776 :   if (allocate >= SPLIT_STACK_AVAILABLE
   10453                 :      235687 :       || flag_force_indirect_call)
   10454                 :             :     {
   10455                 :       24106 :       scratch_regno = split_stack_prologue_scratch_regno ();
   10456                 :       24106 :       if (scratch_regno == INVALID_REGNUM)
   10457                 :           0 :         return;
   10458                 :             :     }
   10459                 :             : 
   10460                 :      259776 :   if (allocate >= SPLIT_STACK_AVAILABLE)
   10461                 :             :     {
   10462                 :       24089 :       rtx offset;
   10463                 :             : 
   10464                 :             :       /* We need a scratch register to hold the stack pointer minus
   10465                 :             :          the required frame size.  Since this is the very start of the
   10466                 :             :          function, the scratch register can be any caller-saved
   10467                 :             :          register which is not used for parameters.  */
   10468                 :       24089 :       offset = GEN_INT (- allocate);
   10469                 :             : 
   10470                 :       24089 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10471                 :       24089 :       if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
   10472                 :             :         {
   10473                 :             :           /* We don't use gen_add in this case because it will
   10474                 :             :              want to split to lea, but when not optimizing the insn
   10475                 :             :              will not be split after this point.  */
   10476                 :       24089 :           emit_insn (gen_rtx_SET (scratch_reg,
   10477                 :             :                                   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   10478                 :             :                                                 offset)));
   10479                 :             :         }
   10480                 :             :       else
   10481                 :             :         {
   10482                 :           0 :           emit_move_insn (scratch_reg, offset);
   10483                 :           0 :           emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
   10484                 :             :         }
   10485                 :             :       current = scratch_reg;
   10486                 :             :     }
   10487                 :             :   else
   10488                 :      235687 :     current = stack_pointer_rtx;
   10489                 :             : 
   10490                 :      259776 :   ix86_expand_branch (GEU, current, limit, label);
   10491                 :      259776 :   rtx_insn *jump_insn = get_last_insn ();
   10492                 :      259776 :   JUMP_LABEL (jump_insn) = label;
   10493                 :             : 
   10494                 :             :   /* Mark the jump as very likely to be taken.  */
   10495                 :      259776 :   add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
   10496                 :             : 
   10497                 :      259776 :   if (split_stack_fn == NULL_RTX)
   10498                 :             :     {
   10499                 :        4343 :       split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
   10500                 :        4343 :       SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
   10501                 :             :     }
   10502                 :      259776 :   fn = split_stack_fn;
   10503                 :             : 
   10504                 :             :   /* Get more stack space.  We pass in the desired stack space and the
   10505                 :             :      size of the arguments to copy to the new stack.  In 32-bit mode
   10506                 :             :      we push the parameters; __morestack will return on a new stack
   10507                 :             :      anyhow.  In 64-bit mode we pass the parameters in r10 and
   10508                 :             :      r11.  */
   10509                 :      259776 :   allocate_rtx = GEN_INT (allocate);
   10510                 :      259776 :   args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
   10511                 :      259776 :   call_fusage = NULL_RTX;
   10512                 :      259776 :   rtx pop = NULL_RTX;
   10513                 :      259776 :   if (TARGET_64BIT)
   10514                 :             :     {
   10515                 :      161866 :       rtx reg10, reg11;
   10516                 :             : 
   10517                 :      161866 :       reg10 = gen_rtx_REG (DImode, R10_REG);
   10518                 :      161866 :       reg11 = gen_rtx_REG (DImode, R11_REG);
   10519                 :             : 
   10520                 :             :       /* If this function uses a static chain, it will be in %r10.
   10521                 :             :          Preserve it across the call to __morestack.  */
   10522                 :      161866 :       if (DECL_STATIC_CHAIN (cfun->decl))
   10523                 :             :         {
   10524                 :        7505 :           rtx rax;
   10525                 :             : 
   10526                 :        7505 :           rax = gen_rtx_REG (word_mode, AX_REG);
   10527                 :        7505 :           emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
   10528                 :        7505 :           use_reg (&call_fusage, rax);
   10529                 :             :         }
   10530                 :             : 
   10531                 :      161866 :       if (flag_force_indirect_call
   10532                 :      161849 :           || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
   10533                 :             :         {
   10534                 :          18 :           HOST_WIDE_INT argval;
   10535                 :             : 
   10536                 :          18 :           if (split_stack_fn_large == NULL_RTX)
   10537                 :             :             {
   10538                 :           8 :               split_stack_fn_large
   10539                 :           8 :                 = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
   10540                 :           8 :               SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
   10541                 :             :             }
   10542                 :             : 
   10543                 :          18 :           fn = split_stack_fn_large;
   10544                 :             : 
   10545                 :          18 :           if (ix86_cmodel == CM_LARGE_PIC)
   10546                 :             :             {
   10547                 :           3 :               rtx_code_label *label;
   10548                 :           3 :               rtx x;
   10549                 :             : 
   10550                 :           3 :               gcc_assert (Pmode == DImode);
   10551                 :             : 
   10552                 :           3 :               label = gen_label_rtx ();
   10553                 :           3 :               emit_label (label);
   10554                 :           3 :               LABEL_PRESERVE_P (label) = 1;
   10555                 :           3 :               emit_insn (gen_set_rip_rex64 (reg10, label));
   10556                 :           3 :               emit_insn (gen_set_got_offset_rex64 (reg11, label));
   10557                 :           3 :               emit_insn (gen_add2_insn (reg10, reg11));
   10558                 :           3 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
   10559                 :           3 :               x = gen_rtx_CONST (Pmode, x);
   10560                 :           3 :               emit_move_insn (reg11, x);
   10561                 :           3 :               x = gen_rtx_PLUS (Pmode, reg10, reg11);
   10562                 :           3 :               x = gen_const_mem (Pmode, x);
   10563                 :           3 :               fn = copy_to_suggested_reg (x, reg11, Pmode);
   10564                 :             :             }
   10565                 :          15 :           else if (ix86_cmodel == CM_LARGE)
   10566                 :           1 :             fn = copy_to_suggested_reg (fn, reg11, Pmode);
   10567                 :             : 
   10568                 :             :           /* When using the large model we need to load the address
   10569                 :             :              into a register, and we've run out of registers.  So we
   10570                 :             :              switch to a different calling convention, and we call a
   10571                 :             :              different function: __morestack_large.  We pass the
   10572                 :             :              argument size in the upper 32 bits of r10 and pass the
   10573                 :             :              frame size in the lower 32 bits.  */
   10574                 :          18 :           gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
   10575                 :          18 :           gcc_assert ((args_size & 0xffffffff) == args_size);
   10576                 :             : 
   10577                 :          18 :           argval = ((args_size << 16) << 16) + allocate;
   10578                 :          18 :           emit_move_insn (reg10, GEN_INT (argval));
   10579                 :          18 :         }
   10580                 :             :       else
   10581                 :             :         {
   10582                 :      161848 :           emit_move_insn (reg10, allocate_rtx);
   10583                 :      161848 :           emit_move_insn (reg11, GEN_INT (args_size));
   10584                 :      161848 :           use_reg (&call_fusage, reg11);
   10585                 :             :         }
   10586                 :             : 
   10587                 :      161866 :       use_reg (&call_fusage, reg10);
   10588                 :             :     }
   10589                 :             :   else
   10590                 :             :     {
   10591                 :       97910 :       if (flag_force_indirect_call && flag_pic)
   10592                 :             :         {
   10593                 :           0 :           rtx x;
   10594                 :             : 
   10595                 :           0 :           gcc_assert (Pmode == SImode);
   10596                 :             : 
   10597                 :           0 :           scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10598                 :             : 
   10599                 :           0 :           emit_insn (gen_set_got (scratch_reg));
   10600                 :           0 :           x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
   10601                 :             :                               UNSPEC_GOT);
   10602                 :           0 :           x = gen_rtx_CONST (Pmode, x);
   10603                 :           0 :           x = gen_rtx_PLUS (Pmode, scratch_reg, x);
   10604                 :           0 :           x = gen_const_mem (Pmode, x);
   10605                 :           0 :           fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
   10606                 :             :         }
   10607                 :             : 
   10608                 :       97910 :       rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
   10609                 :      195820 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
   10610                 :       97910 :       insn = emit_insn (gen_push (allocate_rtx));
   10611                 :      195820 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
   10612                 :      195820 :       pop = GEN_INT (2 * UNITS_PER_WORD);
   10613                 :             :     }
   10614                 :             : 
   10615                 :      259776 :   if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
   10616                 :             :     {
   10617                 :          14 :       scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
   10618                 :             : 
   10619                 :          14 :       if (GET_MODE (fn) != word_mode)
   10620                 :           0 :         fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
   10621                 :             : 
   10622                 :          14 :       fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
   10623                 :             :     }
   10624                 :             : 
   10625                 :      259776 :   call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
   10626                 :      259776 :                                 GEN_INT (UNITS_PER_WORD), constm1_rtx,
   10627                 :             :                                 pop, false);
   10628                 :      259776 :   add_function_usage_to (call_insn, call_fusage);
   10629                 :      259776 :   if (!TARGET_64BIT)
   10630                 :       97910 :     add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
   10631                 :             :   /* Indicate that this function can't jump to non-local gotos.  */
   10632                 :      259776 :   make_reg_eh_region_note_nothrow_nononlocal (call_insn);
   10633                 :             : 
   10634                 :             :   /* In order to make call/return prediction work right, we now need
   10635                 :             :      to execute a return instruction.  See
   10636                 :             :      libgcc/config/i386/morestack.S for the details on how this works.
   10637                 :             : 
   10638                 :             :      For flow purposes gcc must not see this as a return
   10639                 :             :      instruction--we need control flow to continue at the subsequent
   10640                 :             :      label.  Therefore, we use an unspec.  */
   10641                 :      259776 :   gcc_assert (crtl->args.pops_args < 65536);
   10642                 :      259776 :   rtx_insn *ret_insn
   10643                 :      259776 :     = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
   10644                 :             : 
   10645                 :      259776 :   if ((flag_cf_protection & CF_BRANCH))
   10646                 :             :     {
   10647                 :             :       /* Insert ENDBR since __morestack will jump back here via indirect
   10648                 :             :          call.  */
   10649                 :          21 :       rtx cet_eb = gen_nop_endbr ();
   10650                 :          21 :       emit_insn_after (cet_eb, ret_insn);
   10651                 :             :     }
   10652                 :             : 
   10653                 :             :   /* If we are in 64-bit mode and this function uses a static chain,
   10654                 :             :      we saved %r10 in %rax before calling _morestack.  */
   10655                 :      259776 :   if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
   10656                 :        7505 :     emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
   10657                 :             :                     gen_rtx_REG (word_mode, AX_REG));
   10658                 :             : 
   10659                 :             :   /* If this function calls va_start, we need to store a pointer to
   10660                 :             :      the arguments on the old stack, because they may not have been
   10661                 :             :      all copied to the new stack.  At this point the old stack can be
   10662                 :             :      found at the frame pointer value used by __morestack, because
   10663                 :             :      __morestack has set that up before calling back to us.  Here we
   10664                 :             :      store that pointer in a scratch register, and in
   10665                 :             :      ix86_expand_prologue we store the scratch register in a stack
   10666                 :             :      slot.  */
   10667                 :      259776 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10668                 :             :     {
   10669                 :          12 :       rtx frame_reg;
   10670                 :          12 :       int words;
   10671                 :             : 
   10672                 :          12 :       scratch_regno = split_stack_prologue_scratch_regno ();
   10673                 :          12 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   10674                 :          12 :       frame_reg = gen_rtx_REG (Pmode, BP_REG);
   10675                 :             : 
   10676                 :             :       /* 64-bit:
   10677                 :             :          fp -> old fp value
   10678                 :             :                return address within this function
   10679                 :             :                return address of caller of this function
   10680                 :             :                stack arguments
   10681                 :             :          So we add three words to get to the stack arguments.
   10682                 :             : 
   10683                 :             :          32-bit:
   10684                 :             :          fp -> old fp value
   10685                 :             :                return address within this function
   10686                 :             :                first argument to __morestack
   10687                 :             :                second argument to __morestack
   10688                 :             :                return address of caller of this function
   10689                 :             :                stack arguments
   10690                 :             :          So we add five words to get to the stack arguments.
   10691                 :             :       */
   10692                 :          12 :       words = TARGET_64BIT ? 3 : 5;
   10693                 :          16 :       emit_insn (gen_rtx_SET (scratch_reg,
   10694                 :             :                               plus_constant (Pmode, frame_reg,
   10695                 :             :                                              words * UNITS_PER_WORD)));
   10696                 :             : 
   10697                 :          12 :       varargs_label = gen_label_rtx ();
   10698                 :          12 :       emit_jump_insn (gen_jump (varargs_label));
   10699                 :          12 :       JUMP_LABEL (get_last_insn ()) = varargs_label;
   10700                 :             : 
   10701                 :          12 :       emit_barrier ();
   10702                 :             :     }
   10703                 :             : 
   10704                 :      259776 :   emit_label (label);
   10705                 :      259776 :   LABEL_NUSES (label) = 1;
   10706                 :             : 
   10707                 :             :   /* If this function calls va_start, we now have to set the scratch
   10708                 :             :      register for the case where we do not call __morestack.  In this
   10709                 :             :      case we need to set it based on the stack pointer.  */
   10710                 :      259776 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10711                 :             :     {
   10712                 :          16 :       emit_insn (gen_rtx_SET (scratch_reg,
   10713                 :             :                               plus_constant (Pmode, stack_pointer_rtx,
   10714                 :             :                                              UNITS_PER_WORD)));
   10715                 :             : 
   10716                 :          12 :       emit_label (varargs_label);
   10717                 :          12 :       LABEL_NUSES (varargs_label) = 1;
   10718                 :             :     }
   10719                 :             : }
   10720                 :             : 
   10721                 :             : /* We may have to tell the dataflow pass that the split stack prologue
   10722                 :             :    is initializing a scratch register.  */
   10723                 :             : 
   10724                 :             : static void
   10725                 :    14190176 : ix86_live_on_entry (bitmap regs)
   10726                 :             : {
   10727                 :    14190176 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   10728                 :             :     {
   10729                 :         124 :       gcc_assert (flag_split_stack);
   10730                 :         124 :       bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
   10731                 :             :     }
   10732                 :    14190176 : }
   10733                 :             : 
   10734                 :             : /* Extract the parts of an RTL expression that is a valid memory address
   10735                 :             :    for an instruction.  Return false if the structure of the address is
   10736                 :             :    grossly off.  */
   10737                 :             : 
   10738                 :             : bool
   10739                 :  3823651681 : ix86_decompose_address (rtx addr, struct ix86_address *out)
   10740                 :             : {
   10741                 :  3823651681 :   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
   10742                 :  3823651681 :   rtx base_reg, index_reg;
   10743                 :  3823651681 :   HOST_WIDE_INT scale = 1;
   10744                 :  3823651681 :   rtx scale_rtx = NULL_RTX;
   10745                 :  3823651681 :   rtx tmp;
   10746                 :  3823651681 :   addr_space_t seg = ADDR_SPACE_GENERIC;
   10747                 :             : 
   10748                 :             :   /* Allow zero-extended SImode addresses,
   10749                 :             :      they will be emitted with addr32 prefix.  */
   10750                 :  3823651681 :   if (TARGET_64BIT && GET_MODE (addr) == DImode)
   10751                 :             :     {
   10752                 :  1813505212 :       if (GET_CODE (addr) == ZERO_EXTEND
   10753                 :     1482415 :           && GET_MODE (XEXP (addr, 0)) == SImode)
   10754                 :             :         {
   10755                 :     1390098 :           addr = XEXP (addr, 0);
   10756                 :     1390098 :           if (CONST_INT_P (addr))
   10757                 :             :             return false;
   10758                 :             :         }             
   10759                 :  1812115114 :       else if (GET_CODE (addr) == AND
   10760                 :  1812115114 :                && const_32bit_mask (XEXP (addr, 1), DImode))
   10761                 :             :         {
   10762                 :       22905 :           addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
   10763                 :       22905 :           if (addr == NULL_RTX)
   10764                 :             :             return false;
   10765                 :             : 
   10766                 :       22905 :           if (CONST_INT_P (addr))
   10767                 :             :             return false;
   10768                 :             :         }
   10769                 :  1812092209 :       else if (GET_CODE (addr) == AND)
   10770                 :             :         {
   10771                 :             :           /* For ASHIFT inside AND, combine will not generate
   10772                 :             :              canonical zero-extend. Merge mask for AND and shift_count
   10773                 :             :              to check if it is canonical zero-extend.  */
   10774                 :     2410822 :           tmp = XEXP (addr, 0);
   10775                 :     2410822 :           rtx mask = XEXP (addr, 1);
   10776                 :     2410822 :           if (tmp && GET_CODE(tmp) == ASHIFT)
   10777                 :             :             {
   10778                 :      135042 :               rtx shift_val = XEXP (tmp, 1);
   10779                 :      135042 :               if (CONST_INT_P (mask) && CONST_INT_P (shift_val)
   10780                 :      119478 :                   && (((unsigned HOST_WIDE_INT) INTVAL(mask)
   10781                 :      119478 :                       | ((HOST_WIDE_INT_1U << INTVAL(shift_val)) - 1))
   10782                 :             :                       == 0xffffffff))
   10783                 :             :                 {
   10784                 :       35596 :                   addr = lowpart_subreg (SImode, XEXP (addr, 0),
   10785                 :             :                                          DImode);
   10786                 :             :                 }
   10787                 :             :             }
   10788                 :             : 
   10789                 :             :         }
   10790                 :             :     }
   10791                 :             : 
   10792                 :             :   /* Allow SImode subregs of DImode addresses,
   10793                 :             :      they will be emitted with addr32 prefix.  */
   10794                 :  3823651681 :   if (TARGET_64BIT && GET_MODE (addr) == SImode)
   10795                 :             :     {
   10796                 :    13815423 :       if (SUBREG_P (addr)
   10797                 :      188612 :           && GET_MODE (SUBREG_REG (addr)) == DImode)
   10798                 :             :         {
   10799                 :      168335 :           addr = SUBREG_REG (addr);
   10800                 :      168335 :           if (CONST_INT_P (addr))
   10801                 :             :             return false;
   10802                 :             :         }
   10803                 :             :     }
   10804                 :             : 
   10805                 :  3823651681 :   if (REG_P (addr))
   10806                 :             :     base = addr;
   10807                 :             :   else if (SUBREG_P (addr))
   10808                 :             :     {
   10809                 :      390375 :       if (REG_P (SUBREG_REG (addr)))
   10810                 :             :         base = addr;
   10811                 :             :       else
   10812                 :             :         return false;
   10813                 :             :     }
   10814                 :             :   else if (GET_CODE (addr) == PLUS)
   10815                 :             :     {
   10816                 :             :       rtx addends[4], op;
   10817                 :             :       int n = 0, i;
   10818                 :             : 
   10819                 :             :       op = addr;
   10820                 :  2818179611 :       do
   10821                 :             :         {
   10822                 :  2818179611 :           if (n >= 4)
   10823                 :   644903330 :             return false;
   10824                 :  2818175969 :           addends[n++] = XEXP (op, 1);
   10825                 :  2818175969 :           op = XEXP (op, 0);
   10826                 :             :         }
   10827                 :  2818175969 :       while (GET_CODE (op) == PLUS);
   10828                 :  2777833761 :       if (n >= 4)
   10829                 :             :         return false;
   10830                 :  2777827672 :       addends[n] = op;
   10831                 :             : 
   10832                 :  7086498936 :       for (i = n; i >= 0; --i)
   10833                 :             :         {
   10834                 :  4953564863 :           op = addends[i];
   10835                 :  4953564863 :           switch (GET_CODE (op))
   10836                 :             :             {
   10837                 :    46564244 :             case MULT:
   10838                 :    46564244 :               if (index)
   10839                 :             :                 return false;
   10840                 :    46527648 :               index = XEXP (op, 0);
   10841                 :    46527648 :               scale_rtx = XEXP (op, 1);
   10842                 :    46527648 :               break;
   10843                 :             : 
   10844                 :     9886204 :             case ASHIFT:
   10845                 :     9886204 :               if (index)
   10846                 :             :                 return false;
   10847                 :     9825890 :               index = XEXP (op, 0);
   10848                 :     9825890 :               tmp = XEXP (op, 1);
   10849                 :     9825890 :               if (!CONST_INT_P (tmp))
   10850                 :             :                 return false;
   10851                 :     9812819 :               scale = INTVAL (tmp);
   10852                 :     9812819 :               if ((unsigned HOST_WIDE_INT) scale > 3)
   10853                 :             :                 return false;
   10854                 :     9511850 :               scale = 1 << scale;
   10855                 :     9511850 :               break;
   10856                 :             : 
   10857                 :      554989 :             case ZERO_EXTEND:
   10858                 :      554989 :               op = XEXP (op, 0);
   10859                 :      554989 :               if (GET_CODE (op) != UNSPEC)
   10860                 :             :                 return false;
   10861                 :             :               /* FALLTHRU */
   10862                 :             : 
   10863                 :      462192 :             case UNSPEC:
   10864                 :      462192 :               if (XINT (op, 1) == UNSPEC_TP
   10865                 :      460260 :                   && TARGET_TLS_DIRECT_SEG_REFS
   10866                 :      460260 :                   && seg == ADDR_SPACE_GENERIC)
   10867                 :      460260 :                 seg = DEFAULT_TLS_SEG_REG;
   10868                 :             :               else
   10869                 :             :                 return false;
   10870                 :             :               break;
   10871                 :             : 
   10872                 :      440271 :             case SUBREG:
   10873                 :      440271 :               if (!REG_P (SUBREG_REG (op)))
   10874                 :             :                 return false;
   10875                 :             :               /* FALLTHRU */
   10876                 :             : 
   10877                 :  2180075840 :             case REG:
   10878                 :  2180075840 :               if (!base)
   10879                 :             :                 base = op;
   10880                 :    57314489 :               else if (!index)
   10881                 :             :                 index = op;
   10882                 :             :               else
   10883                 :             :                 return false;
   10884                 :             :               break;
   10885                 :             : 
   10886                 :  2072741336 :             case CONST:
   10887                 :  2072741336 :             case CONST_INT:
   10888                 :  2072741336 :             case SYMBOL_REF:
   10889                 :  2072741336 :             case LABEL_REF:
   10890                 :  2072741336 :               if (disp)
   10891                 :             :                 return false;
   10892                 :             :               disp = op;
   10893                 :             :               break;
   10894                 :             : 
   10895                 :             :             default:
   10896                 :             :               return false;
   10897                 :             :             }
   10898                 :             :         }
   10899                 :             :     }
   10900                 :             :   else if (GET_CODE (addr) == MULT)
   10901                 :             :     {
   10902                 :     2795359 :       index = XEXP (addr, 0);           /* index*scale */
   10903                 :     2795359 :       scale_rtx = XEXP (addr, 1);
   10904                 :             :     }
   10905                 :             :   else if (GET_CODE (addr) == ASHIFT)
   10906                 :             :     {
   10907                 :             :       /* We're called for lea too, which implements ashift on occasion.  */
   10908                 :     2536552 :       index = XEXP (addr, 0);
   10909                 :     2536552 :       tmp = XEXP (addr, 1);
   10910                 :     2536552 :       if (!CONST_INT_P (tmp))
   10911                 :             :         return false;
   10912                 :     2248681 :       scale = INTVAL (tmp);
   10913                 :     2248681 :       if ((unsigned HOST_WIDE_INT) scale > 3)
   10914                 :             :         return false;
   10915                 :     1662464 :       scale = 1 << scale;
   10916                 :             :     }
   10917                 :             :   else
   10918                 :             :     disp = addr;                        /* displacement */
   10919                 :             : 
   10920                 :  3177837757 :   if (index)
   10921                 :             :     {
   10922                 :   110061729 :       if (REG_P (index))
   10923                 :             :         ;
   10924                 :     2689606 :       else if (SUBREG_P (index)
   10925                 :      262600 :                && REG_P (SUBREG_REG (index)))
   10926                 :             :         ;
   10927                 :             :       else
   10928                 :             :         return false;
   10929                 :             :     }
   10930                 :             : 
   10931                 :             :   /* Extract the integral value of scale.  */
   10932                 :  3175375668 :   if (scale_rtx)
   10933                 :             :     {
   10934                 :    42972772 :       if (!CONST_INT_P (scale_rtx))
   10935                 :             :         return false;
   10936                 :    42536343 :       scale = INTVAL (scale_rtx);
   10937                 :             :     }
   10938                 :             : 
   10939                 :  3174939239 :   base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
   10940                 :  3174939239 :   index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
   10941                 :             : 
   10942                 :             :   /* Avoid useless 0 displacement.  */
   10943                 :  3174939239 :   if (disp == const0_rtx && (base || index))
   10944                 :  3174939239 :     disp = NULL_RTX;
   10945                 :             : 
   10946                 :             :   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   10947                 :  2314218617 :   if (base_reg && index_reg && scale == 1
   10948                 :  3231065509 :       && (REGNO (index_reg) == ARG_POINTER_REGNUM
   10949                 :             :           || REGNO (index_reg) == FRAME_POINTER_REGNUM
   10950                 :             :           || REGNO (index_reg) == SP_REG))
   10951                 :             :     {
   10952                 :             :       std::swap (base, index);
   10953                 :             :       std::swap (base_reg, index_reg);
   10954                 :             :     }
   10955                 :             : 
   10956                 :             :   /* Special case: %ebp cannot be encoded as a base without a displacement.
   10957                 :             :      Similarly %r13.  */
   10958                 :   256653854 :   if (!disp && base_reg
   10959                 :  3428258473 :       && (REGNO (base_reg) == ARG_POINTER_REGNUM
   10960                 :             :           || REGNO (base_reg) == FRAME_POINTER_REGNUM
   10961                 :             :           || REGNO (base_reg) == BP_REG
   10962                 :             :           || REGNO (base_reg) == R13_REG))
   10963                 :             :     disp = const0_rtx;
   10964                 :             : 
   10965                 :             :   /* Special case: on K6, [%esi] makes the instruction vector decoded.
   10966                 :             :      Avoid this by transforming to [%esi+0].
   10967                 :             :      Reload calls address legitimization without cfun defined, so we need
   10968                 :             :      to test cfun for being non-NULL. */
   10969                 :           0 :   if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
   10970                 :           0 :       && base_reg && !index_reg && !disp
   10971                 :  3174939239 :       && REGNO (base_reg) == SI_REG)
   10972                 :           0 :     disp = const0_rtx;
   10973                 :             : 
   10974                 :             :   /* Special case: encode reg+reg instead of reg*2.  */
   10975                 :  3174939239 :   if (!base && index && scale == 2)
   10976                 :   860720622 :     base = index, base_reg = index_reg, scale = 1;
   10977                 :             : 
   10978                 :             :   /* Special case: scaling cannot be encoded without base or displacement.  */
   10979                 :   860720622 :   if (!base && !disp && index && scale != 1)
   10980                 :     2679776 :     disp = const0_rtx;
   10981                 :             : 
   10982                 :  3174939239 :   out->base = base;
   10983                 :  3174939239 :   out->index = index;
   10984                 :  3174939239 :   out->disp = disp;
   10985                 :  3174939239 :   out->scale = scale;
   10986                 :  3174939239 :   out->seg = seg;
   10987                 :             : 
   10988                 :  3174939239 :   return true;
   10989                 :             : }
   10990                 :             : 
   10991                 :             : /* Return cost of the memory address x.
   10992                 :             :    For i386, it is better to use a complex address than let gcc copy
   10993                 :             :    the address into a reg and make a new pseudo.  But not if the address
   10994                 :             :    requires to two regs - that would mean more pseudos with longer
   10995                 :             :    lifetimes.  */
   10996                 :             : static int
   10997                 :     9183348 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
   10998                 :             : {
   10999                 :     9183348 :   struct ix86_address parts;
   11000                 :     9183348 :   int cost = 1;
   11001                 :     9183348 :   int ok = ix86_decompose_address (x, &parts);
   11002                 :             : 
   11003                 :     9183348 :   gcc_assert (ok);
   11004                 :             : 
   11005                 :     9183348 :   if (parts.base && SUBREG_P (parts.base))
   11006                 :         287 :     parts.base = SUBREG_REG (parts.base);
   11007                 :     9183348 :   if (parts.index && SUBREG_P (parts.index))
   11008                 :          14 :     parts.index = SUBREG_REG (parts.index);
   11009                 :             : 
   11010                 :             :   /* Attempt to minimize number of registers in the address by increasing
   11011                 :             :      address cost for each used register.  We don't increase address cost
   11012                 :             :      for "pic_offset_table_rtx".  When a memopt with "pic_offset_table_rtx"
   11013                 :             :      is not invariant itself it most likely means that base or index is not
   11014                 :             :      invariant.  Therefore only "pic_offset_table_rtx" could be hoisted out,
   11015                 :             :      which is not profitable for x86.  */
   11016                 :     9183348 :   if (parts.base
   11017                 :     7955050 :       && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
   11018                 :    16845240 :       && (current_pass->type == GIMPLE_PASS
   11019                 :     2135970 :           || !pic_offset_table_rtx
   11020                 :      110174 :           || !REG_P (parts.base)
   11021                 :      110174 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
   11022                 :             :     cost++;
   11023                 :             : 
   11024                 :     9183348 :   if (parts.index
   11025                 :     4534183 :       && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
   11026                 :    13700055 :       && (current_pass->type == GIMPLE_PASS
   11027                 :      494797 :           || !pic_offset_table_rtx
   11028                 :       42564 :           || !REG_P (parts.index)
   11029                 :       42564 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
   11030                 :     4515912 :     cost++;
   11031                 :             : 
   11032                 :             :   /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
   11033                 :             :      since it's predecode logic can't detect the length of instructions
   11034                 :             :      and it degenerates to vector decoded.  Increase cost of such
   11035                 :             :      addresses here.  The penalty is minimally 2 cycles.  It may be worthwhile
   11036                 :             :      to split such addresses or even refuse such addresses at all.
   11037                 :             : 
   11038                 :             :      Following addressing modes are affected:
   11039                 :             :       [base+scale*index]
   11040                 :             :       [scale*index+disp]
   11041                 :             :       [base+index]
   11042                 :             : 
   11043                 :             :      The first and last case  may be avoidable by explicitly coding the zero in
   11044                 :             :      memory address, but I don't have AMD-K6 machine handy to check this
   11045                 :             :      theory.  */
   11046                 :             : 
   11047                 :     9183348 :   if (TARGET_CPU_P (K6)
   11048                 :           0 :       && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
   11049                 :           0 :           || (parts.disp && !parts.base && parts.index && parts.scale != 1)
   11050                 :           0 :           || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
   11051                 :           0 :     cost += 10;
   11052                 :             : 
   11053                 :     9183348 :   return cost;
   11054                 :             : }
   11055                 :             : 
   11056                 :             : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
   11057                 :             :    this is used for to form addresses to local data when -fPIC is in
   11058                 :             :    use.  */
   11059                 :             : 
   11060                 :             : static bool
   11061                 :           0 : darwin_local_data_pic (rtx disp)
   11062                 :             : {
   11063                 :           0 :   return (GET_CODE (disp) == UNSPEC
   11064                 :           0 :           && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
   11065                 :             : }
   11066                 :             : 
   11067                 :             : /* True if the function symbol operand X should be loaded from GOT.
   11068                 :             :    If CALL_P is true, X is a call operand.
   11069                 :             : 
   11070                 :             :    NB: -mno-direct-extern-access doesn't force load from GOT for
   11071                 :             :    call.
   11072                 :             : 
   11073                 :             :    NB: In 32-bit mode, only non-PIC is allowed in inline assembly
   11074                 :             :    statements, since a PIC register could not be available at the
   11075                 :             :    call site.  */
   11076                 :             : 
   11077                 :             : bool
   11078                 :  1566121497 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
   11079                 :             : {
   11080                 :    83956004 :   return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
   11081                 :             :           && !TARGET_PECOFF && !TARGET_MACHO
   11082                 :  1563835302 :           && (!flag_pic || this_is_asm_operands)
   11083                 :  1547246175 :           && ix86_cmodel != CM_LARGE
   11084                 :  1547240892 :           && ix86_cmodel != CM_LARGE_PIC
   11085                 :  1547240891 :           && GET_CODE (x) == SYMBOL_REF
   11086                 :  1547240889 :           && ((!call_p
   11087                 :  1542160231 :                && (!ix86_direct_extern_access
   11088                 :  1542158994 :                    || (SYMBOL_REF_DECL (x)
   11089                 :  1381505417 :                        && lookup_attribute ("nodirect_extern_access",
   11090                 :  1381505417 :                                             DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
   11091                 :  1547239245 :               || (SYMBOL_REF_FUNCTION_P (x)
   11092                 :   587194193 :                   && (!flag_plt
   11093                 :   587192421 :                       || (SYMBOL_REF_DECL (x)
   11094                 :   587192421 :                           && lookup_attribute ("noplt",
   11095                 :   587192421 :                                                DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
   11096                 :  1566125270 :           && !SYMBOL_REF_LOCAL_P (x));
   11097                 :             : }
   11098                 :             : 
   11099                 :             : /* Determine if a given RTX is a valid constant.  We already know this
   11100                 :             :    satisfies CONSTANT_P.  */
   11101                 :             : 
   11102                 :             : static bool
   11103                 :  1212967513 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
   11104                 :             : {
   11105                 :  1212967513 :   switch (GET_CODE (x))
   11106                 :             :     {
   11107                 :   116181347 :     case CONST:
   11108                 :   116181347 :       x = XEXP (x, 0);
   11109                 :             : 
   11110                 :   116181347 :       if (GET_CODE (x) == PLUS)
   11111                 :             :         {
   11112                 :   116105107 :           if (!CONST_INT_P (XEXP (x, 1)))
   11113                 :             :             return false;
   11114                 :   116105107 :           x = XEXP (x, 0);
   11115                 :             :         }
   11116                 :             : 
   11117                 :   116181347 :       if (TARGET_MACHO && darwin_local_data_pic (x))
   11118                 :             :         return true;
   11119                 :             : 
   11120                 :             :       /* Only some unspecs are valid as "constants".  */
   11121                 :   116181347 :       if (GET_CODE (x) == UNSPEC)
   11122                 :      390645 :         switch (XINT (x, 1))
   11123                 :             :           {
   11124                 :       20561 :           case UNSPEC_GOT:
   11125                 :       20561 :           case UNSPEC_GOTOFF:
   11126                 :       20561 :           case UNSPEC_PLTOFF:
   11127                 :       20561 :             return TARGET_64BIT;
   11128                 :      369494 :           case UNSPEC_TPOFF:
   11129                 :      369494 :           case UNSPEC_NTPOFF:
   11130                 :      369494 :             x = XVECEXP (x, 0, 0);
   11131                 :      369494 :             return (GET_CODE (x) == SYMBOL_REF
   11132                 :      369494 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11133                 :         502 :           case UNSPEC_DTPOFF:
   11134                 :         502 :             x = XVECEXP (x, 0, 0);
   11135                 :         502 :             return (GET_CODE (x) == SYMBOL_REF
   11136                 :         502 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
   11137                 :             :           default:
   11138                 :             :             return false;
   11139                 :             :           }
   11140                 :             : 
   11141                 :             :       /* We must have drilled down to a symbol.  */
   11142                 :   115790702 :       if (GET_CODE (x) == LABEL_REF)
   11143                 :             :         return true;
   11144                 :   115787294 :       if (GET_CODE (x) != SYMBOL_REF)
   11145                 :             :         return false;
   11146                 :             :       /* FALLTHRU */
   11147                 :             : 
   11148                 :   779660910 :     case SYMBOL_REF:
   11149                 :             :       /* TLS symbols are never valid.  */
   11150                 :   779660910 :       if (SYMBOL_REF_TLS_MODEL (x))
   11151                 :             :         return false;
   11152                 :             : 
   11153                 :             :       /* DLLIMPORT symbols are never valid.  */
   11154                 :   779566960 :       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
   11155                 :             :           && SYMBOL_REF_DLLIMPORT_P (x))
   11156                 :             :         return false;
   11157                 :             : 
   11158                 :             : #if TARGET_MACHO
   11159                 :             :       /* mdynamic-no-pic */
   11160                 :             :       if (MACHO_DYNAMIC_NO_PIC_P)
   11161                 :             :         return machopic_symbol_defined_p (x);
   11162                 :             : #endif
   11163                 :             : 
   11164                 :             :       /* External function address should be loaded
   11165                 :             :          via the GOT slot to avoid PLT.  */
   11166                 :   779566960 :       if (ix86_force_load_from_GOT_p (x))
   11167                 :             :         return false;
   11168                 :             : 
   11169                 :             :       break;
   11170                 :             : 
   11171                 :   416237673 :     CASE_CONST_SCALAR_INT:
   11172                 :   416237673 :       if (ix86_endbr_immediate_operand (x, VOIDmode))
   11173                 :             :         return false;
   11174                 :             : 
   11175                 :   416237500 :       switch (mode)
   11176                 :             :         {
   11177                 :      921468 :         case E_TImode:
   11178                 :      921468 :           if (TARGET_64BIT)
   11179                 :             :             return true;
   11180                 :             :           /* FALLTHRU */
   11181                 :       20550 :         case E_OImode:
   11182                 :       20550 :         case E_XImode:
   11183                 :       20550 :           if (!standard_sse_constant_p (x, mode)
   11184                 :       34814 :               && GET_MODE_SIZE (TARGET_AVX512F && TARGET_EVEX512
   11185                 :             :                                 ? XImode
   11186                 :             :                                 : (TARGET_AVX
   11187                 :             :                                    ? OImode
   11188                 :             :                                    : (TARGET_SSE2
   11189                 :       14264 :                                       ? TImode : DImode))) < GET_MODE_SIZE (mode))
   11190                 :             :             return false;
   11191                 :             :         default:
   11192                 :             :           break;
   11193                 :             :         }
   11194                 :             :       break;
   11195                 :             : 
   11196                 :     5978465 :     case CONST_VECTOR:
   11197                 :     5978465 :       if (!standard_sse_constant_p (x, mode))
   11198                 :             :         return false;
   11199                 :             :       break;
   11200                 :             : 
   11201                 :     6599427 :     case CONST_DOUBLE:
   11202                 :     6599427 :       if (mode == E_BFmode)
   11203                 :             :         return false;
   11204                 :             : 
   11205                 :             :     default:
   11206                 :             :       break;
   11207                 :             :     }
   11208                 :             : 
   11209                 :             :   /* Otherwise we handle everything else in the move patterns.  */
   11210                 :             :   return true;
   11211                 :             : }
   11212                 :             : 
   11213                 :             : /* Determine if it's legal to put X into the constant pool.  This
   11214                 :             :    is not possible for the address of thread-local symbols, which
   11215                 :             :    is checked above.  */
   11216                 :             : 
   11217                 :             : static bool
   11218                 :    45361217 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   11219                 :             : {
   11220                 :             :   /* We can put any immediate constant in memory.  */
   11221                 :    45361217 :   switch (GET_CODE (x))
   11222                 :             :     {
   11223                 :             :     CASE_CONST_ANY:
   11224                 :             :       return false;
   11225                 :             : 
   11226                 :     1644594 :     default:
   11227                 :     1644594 :       break;
   11228                 :             :     }
   11229                 :             : 
   11230                 :     1644594 :   return !ix86_legitimate_constant_p (mode, x);
   11231                 :             : }
   11232                 :             : 
   11233                 :             : /*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
   11234                 :             :     otherwise zero.  */
   11235                 :             : 
   11236                 :             : static bool
   11237                 :           0 : is_imported_p (rtx x)
   11238                 :             : {
   11239                 :           0 :   if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
   11240                 :             :       || GET_CODE (x) != SYMBOL_REF)
   11241                 :           0 :     return false;
   11242                 :             : 
   11243                 :             :   return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
   11244                 :             : }
   11245                 :             : 
   11246                 :             : 
   11247                 :             : /* Nonzero if the constant value X is a legitimate general operand
   11248                 :             :    when generating PIC code.  It is given that flag_pic is on and
   11249                 :             :    that X satisfies CONSTANT_P.  */
   11250                 :             : 
   11251                 :             : bool
   11252                 :    97249551 : legitimate_pic_operand_p (rtx x)
   11253                 :             : {
   11254                 :    97249551 :   rtx inner;
   11255                 :             : 
   11256                 :    97249551 :   switch (GET_CODE (x))
   11257                 :             :     {
   11258                 :     1611791 :     case CONST:
   11259                 :     1611791 :       inner = XEXP (x, 0);
   11260                 :     1611791 :       if (GET_CODE (inner) == PLUS
   11261                 :      296656 :           && CONST_INT_P (XEXP (inner, 1)))
   11262                 :      296656 :         inner = XEXP (inner, 0);
   11263                 :             : 
   11264                 :             :       /* Only some unspecs are valid as "constants".  */
   11265                 :     1611791 :       if (GET_CODE (inner) == UNSPEC)
   11266                 :     1381018 :         switch (XINT (inner, 1))
   11267                 :             :           {
   11268                 :     1342208 :           case UNSPEC_GOT:
   11269                 :     1342208 :           case UNSPEC_GOTOFF:
   11270                 :     1342208 :           case UNSPEC_PLTOFF:
   11271                 :     1342208 :             return TARGET_64BIT;
   11272                 :           0 :           case UNSPEC_TPOFF:
   11273                 :           0 :             x = XVECEXP (inner, 0, 0);
   11274                 :           0 :             return (GET_CODE (x) == SYMBOL_REF
   11275                 :           0 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11276                 :           0 :           case UNSPEC_MACHOPIC_OFFSET:
   11277                 :           0 :             return legitimate_pic_address_disp_p (x);
   11278                 :             :           default:
   11279                 :             :             return false;
   11280                 :             :           }
   11281                 :             :       /* FALLTHRU */
   11282                 :             : 
   11283                 :     6151713 :     case SYMBOL_REF:
   11284                 :     6151713 :     case LABEL_REF:
   11285                 :     6151713 :       return legitimate_pic_address_disp_p (x);
   11286                 :             : 
   11287                 :             :     default:
   11288                 :             :       return true;
   11289                 :             :     }
   11290                 :             : }
   11291                 :             : 
   11292                 :             : /* Determine if a given CONST RTX is a valid memory displacement
   11293                 :             :    in PIC mode.  */
   11294                 :             : 
   11295                 :             : bool
   11296                 :    56548757 : legitimate_pic_address_disp_p (rtx disp)
   11297                 :             : {
   11298                 :    56548757 :   bool saw_plus;
   11299                 :             : 
   11300                 :             :   /* In 64bit mode we can allow direct addresses of symbols and labels
   11301                 :             :      when they are not dynamic symbols.  */
   11302                 :    56548757 :   if (TARGET_64BIT)
   11303                 :             :     {
   11304                 :    34475684 :       rtx op0 = disp, op1;
   11305                 :             : 
   11306                 :    34475684 :       switch (GET_CODE (disp))
   11307                 :             :         {
   11308                 :             :         case LABEL_REF:
   11309                 :             :           return true;
   11310                 :             : 
   11311                 :     9269408 :         case CONST:
   11312                 :     9269408 :           if (GET_CODE (XEXP (disp, 0)) != PLUS)
   11313                 :             :             break;
   11314                 :      998881 :           op0 = XEXP (XEXP (disp, 0), 0);
   11315                 :      998881 :           op1 = XEXP (XEXP (disp, 0), 1);
   11316                 :      998881 :           if (!CONST_INT_P (op1))
   11317                 :             :             break;
   11318                 :      998881 :           if (GET_CODE (op0) == UNSPEC
   11319                 :         291 :               && (XINT (op0, 1) == UNSPEC_DTPOFF
   11320                 :         291 :                   || XINT (op0, 1) == UNSPEC_NTPOFF)
   11321                 :      999172 :               && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
   11322                 :             :             return true;
   11323                 :      998590 :           if (INTVAL (op1) >= 16*1024*1024
   11324                 :      998590 :               || INTVAL (op1) < -16*1024*1024)
   11325                 :             :             break;
   11326                 :      998418 :           if (GET_CODE (op0) == LABEL_REF)
   11327                 :             :             return true;
   11328                 :      998418 :           if (GET_CODE (op0) == CONST
   11329                 :           0 :               && GET_CODE (XEXP (op0, 0)) == UNSPEC
   11330                 :           0 :               && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
   11331                 :             :             return true;
   11332                 :      998418 :           if (GET_CODE (op0) == UNSPEC
   11333                 :           0 :               && XINT (op0, 1) == UNSPEC_PCREL)
   11334                 :             :             return true;
   11335                 :      998418 :           if (GET_CODE (op0) != SYMBOL_REF)
   11336                 :             :             break;
   11337                 :             :           /* FALLTHRU */
   11338                 :             : 
   11339                 :    25998556 :         case SYMBOL_REF:
   11340                 :             :           /* TLS references should always be enclosed in UNSPEC.
   11341                 :             :              The dllimported symbol needs always to be resolved.  */
   11342                 :    25998556 :           if (SYMBOL_REF_TLS_MODEL (op0)
   11343                 :             :               || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
   11344                 :             :             return false;
   11345                 :             : 
   11346                 :    25845606 :           if (TARGET_PECOFF)
   11347                 :             :             {
   11348                 :             :               if (is_imported_p (op0))
   11349                 :             :                 return true;
   11350                 :             : 
   11351                 :             :               if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
   11352                 :             :                 break;
   11353                 :             : 
   11354                 :             :               /* Non-external-weak function symbols need to be resolved only
   11355                 :             :                  for the large model.  Non-external symbols don't need to be
   11356                 :             :                  resolved for large and medium models.  For the small model,
   11357                 :             :                  we don't need to resolve anything here.  */
   11358                 :             :               if ((ix86_cmodel != CM_LARGE_PIC
   11359                 :             :                    && SYMBOL_REF_FUNCTION_P (op0)
   11360                 :             :                    && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
   11361                 :             :                   || !SYMBOL_REF_EXTERNAL_P (op0)
   11362                 :             :                   || ix86_cmodel == CM_SMALL_PIC)
   11363                 :             :                 return true;
   11364                 :             :             }
   11365                 :    25845606 :           else if (!SYMBOL_REF_FAR_ADDR_P (op0)
   11366                 :    25845602 :                    && (SYMBOL_REF_LOCAL_P (op0)
   11367                 :    15963086 :                        || ((ix86_direct_extern_access
   11368                 :    31720558 :                             && !(SYMBOL_REF_DECL (op0)
   11369                 :    15757621 :                                  && lookup_attribute ("nodirect_extern_access",
   11370                 :    15757621 :                                                       DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
   11371                 :             :                            && HAVE_LD_PIE_COPYRELOC
   11372                 :    15962788 :                            && flag_pie
   11373                 :       38866 :                            && !SYMBOL_REF_WEAK (op0)
   11374                 :       38380 :                            && !SYMBOL_REF_FUNCTION_P (op0)))
   11375                 :    35735617 :                    && ix86_cmodel != CM_LARGE_PIC)
   11376                 :             :             return true;
   11377                 :             :           break;
   11378                 :             : 
   11379                 :             :         default:
   11380                 :             :           break;
   11381                 :             :         }
   11382                 :             :     }
   11383                 :    46303144 :   if (GET_CODE (disp) != CONST)
   11384                 :             :     return false;
   11385                 :    12229301 :   disp = XEXP (disp, 0);
   11386                 :             : 
   11387                 :    12229301 :   if (TARGET_64BIT)
   11388                 :             :     {
   11389                 :             :       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
   11390                 :             :          of GOT tables.  We should not need these anyway.  */
   11391                 :     8334191 :       if (GET_CODE (disp) != UNSPEC
   11392                 :     8270527 :           || (XINT (disp, 1) != UNSPEC_GOTPCREL
   11393                 :     8270527 :               && XINT (disp, 1) != UNSPEC_GOTOFF
   11394                 :             :               && XINT (disp, 1) != UNSPEC_PCREL
   11395                 :             :               && XINT (disp, 1) != UNSPEC_PLTOFF))
   11396                 :             :         return false;
   11397                 :             : 
   11398                 :     8270527 :       if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
   11399                 :     8270527 :           && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
   11400                 :             :         return false;
   11401                 :             :       return true;
   11402                 :             :     }
   11403                 :             : 
   11404                 :     3895110 :   saw_plus = false;
   11405                 :     3895110 :   if (GET_CODE (disp) == PLUS)
   11406                 :             :     {
   11407                 :      521090 :       if (!CONST_INT_P (XEXP (disp, 1)))
   11408                 :             :         return false;
   11409                 :      521090 :       disp = XEXP (disp, 0);
   11410                 :      521090 :       saw_plus = true;
   11411                 :             :     }
   11412                 :             : 
   11413                 :     3895110 :   if (TARGET_MACHO && darwin_local_data_pic (disp))
   11414                 :             :     return true;
   11415                 :             : 
   11416                 :     3895110 :   if (GET_CODE (disp) != UNSPEC)
   11417                 :             :     return false;
   11418                 :             : 
   11419                 :     3714077 :   switch (XINT (disp, 1))
   11420                 :             :     {
   11421                 :     1695978 :     case UNSPEC_GOT:
   11422                 :     1695978 :       if (saw_plus)
   11423                 :             :         return false;
   11424                 :             :       /* We need to check for both symbols and labels because VxWorks loads
   11425                 :             :          text labels with @GOT rather than @GOTOFF.  See gotoff_operand for
   11426                 :             :          details.  */
   11427                 :     1695978 :       return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
   11428                 :     1695978 :               || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF);
   11429                 :     2018099 :     case UNSPEC_GOTOFF:
   11430                 :             :       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
   11431                 :             :          While ABI specify also 32bit relocation but we don't produce it in
   11432                 :             :          small PIC model at all.  */
   11433                 :     2018099 :       if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
   11434                 :     2018099 :            || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
   11435                 :             :           && !TARGET_64BIT)
   11436                 :     2018099 :         return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
   11437                 :             :       return false;
   11438                 :           0 :     case UNSPEC_GOTTPOFF:
   11439                 :           0 :     case UNSPEC_GOTNTPOFF:
   11440                 :           0 :     case UNSPEC_INDNTPOFF:
   11441                 :           0 :       if (saw_plus)
   11442                 :             :         return false;
   11443                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11444                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11445                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
   11446                 :           0 :     case UNSPEC_NTPOFF:
   11447                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11448                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11449                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
   11450                 :           0 :     case UNSPEC_DTPOFF:
   11451                 :           0 :       disp = XVECEXP (disp, 0, 0);
   11452                 :           0 :       return (GET_CODE (disp) == SYMBOL_REF
   11453                 :           0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
   11454                 :             :     }
   11455                 :             : 
   11456                 :             :   return false;
   11457                 :             : }
   11458                 :             : 
   11459                 :             : /* Determine if op is suitable RTX for an address register.
   11460                 :             :    Return naked register if a register or a register subreg is
   11461                 :             :    found, otherwise return NULL_RTX.  */
   11462                 :             : 
   11463                 :             : static rtx
   11464                 :  1057520461 : ix86_validate_address_register (rtx op)
   11465                 :             : {
   11466                 :  1057520461 :   machine_mode mode = GET_MODE (op);
   11467                 :             : 
   11468                 :             :   /* Only SImode or DImode registers can form the address.  */
   11469                 :  1057520461 :   if (mode != SImode && mode != DImode)
   11470                 :             :     return NULL_RTX;
   11471                 :             : 
   11472                 :  1057511346 :   if (REG_P (op))
   11473                 :             :     return op;
   11474                 :      578773 :   else if (SUBREG_P (op))
   11475                 :             :     {
   11476                 :      578773 :       rtx reg = SUBREG_REG (op);
   11477                 :             : 
   11478                 :      578773 :       if (!REG_P (reg))
   11479                 :             :         return NULL_RTX;
   11480                 :             : 
   11481                 :      578773 :       mode = GET_MODE (reg);
   11482                 :             : 
   11483                 :             :       /* Don't allow SUBREGs that span more than a word.  It can
   11484                 :             :          lead to spill failures when the register is one word out
   11485                 :             :          of a two word structure.  */
   11486                 :     1197443 :       if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   11487                 :             :         return NULL_RTX;
   11488                 :             : 
   11489                 :             :       /* Allow only SUBREGs of non-eliminable hard registers.  */
   11490                 :      176508 :       if (register_no_elim_operand (reg, mode))
   11491                 :             :         return reg;
   11492                 :             :     }
   11493                 :             : 
   11494                 :             :   /* Op is not a register.  */
   11495                 :             :   return NULL_RTX;
   11496                 :             : }
   11497                 :             : 
   11498                 :             : /* Determine which memory address register set insn can use.  */
   11499                 :             : 
   11500                 :             : static enum attr_addr
   11501                 :   228324483 : ix86_memory_address_reg_class (rtx_insn* insn)
   11502                 :             : {
   11503                 :             :   /* LRA can do some initialization with NULL insn,
   11504                 :             :      return maximum register class in this case.  */
   11505                 :   228324483 :   enum attr_addr addr_rclass = ADDR_GPR32;
   11506                 :             : 
   11507                 :   228324483 :   if (!insn)
   11508                 :             :     return addr_rclass;
   11509                 :             : 
   11510                 :    63741466 :   if (asm_noperands (PATTERN (insn)) >= 0
   11511                 :    63741466 :       || GET_CODE (PATTERN (insn)) == ASM_INPUT)
   11512                 :       69726 :     return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
   11513                 :             : 
   11514                 :             :   /* Return maximum register class for unrecognized instructions.  */
   11515                 :    63706603 :   if (INSN_CODE (insn) < 0)
   11516                 :             :     return addr_rclass;
   11517                 :             : 
   11518                 :             :   /* Try to recognize the insn before calling get_attr_addr.
   11519                 :             :      Save current recog_data and current alternative.  */
   11520                 :    63706603 :   struct recog_data_d saved_recog_data = recog_data;
   11521                 :    63706603 :   int saved_alternative = which_alternative;
   11522                 :             : 
   11523                 :             :   /* Update recog_data for processing of alternatives.  */
   11524                 :    63706603 :   extract_insn_cached (insn);
   11525                 :             : 
   11526                 :             :   /* If current alternative is not set, loop throught enabled
   11527                 :             :      alternatives and get the most limited register class.  */
   11528                 :    63706603 :   if (saved_alternative == -1)
   11529                 :             :     {
   11530                 :    63706603 :       alternative_mask enabled = get_enabled_alternatives (insn);
   11531                 :             : 
   11532                 :  1105319756 :       for (int i = 0; i < recog_data.n_alternatives; i++)
   11533                 :             :         {
   11534                 :  1041613153 :           if (!TEST_BIT (enabled, i))
   11535                 :   153273241 :             continue;
   11536                 :             : 
   11537                 :   888339912 :           which_alternative = i;
   11538                 :   888339912 :           addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
   11539                 :             :         }
   11540                 :             :     }
   11541                 :             :   else
   11542                 :             :     {
   11543                 :           0 :       which_alternative = saved_alternative;
   11544                 :           0 :       addr_rclass = get_attr_addr (insn);
   11545                 :             :     }
   11546                 :             : 
   11547                 :    63706603 :   recog_data = saved_recog_data;
   11548                 :    63706603 :   which_alternative = saved_alternative;
   11549                 :             : 
   11550                 :    63706603 :   return addr_rclass;
   11551                 :             : }
   11552                 :             : 
   11553                 :             : /* Return memory address register class insn can use.  */
   11554                 :             : 
   11555                 :             : enum reg_class
   11556                 :   192593161 : ix86_insn_base_reg_class (rtx_insn* insn)
   11557                 :             : {
   11558                 :   192593161 :   switch (ix86_memory_address_reg_class (insn))
   11559                 :             :     {
   11560                 :             :     case ADDR_GPR8:
   11561                 :             :       return LEGACY_GENERAL_REGS;
   11562                 :             :     case ADDR_GPR16:
   11563                 :             :       return GENERAL_GPR16;
   11564                 :             :     case ADDR_GPR32:
   11565                 :             :       break;
   11566                 :           0 :     default:
   11567                 :           0 :       gcc_unreachable ();
   11568                 :             :     }
   11569                 :             : 
   11570                 :             :   return BASE_REG_CLASS;
   11571                 :             : }
   11572                 :             : 
   11573                 :             : bool
   11574                 :      916894 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
   11575                 :             : {
   11576                 :      916894 :   switch (ix86_memory_address_reg_class (insn))
   11577                 :             :     {
   11578                 :           0 :     case ADDR_GPR8:
   11579                 :           0 :       return LEGACY_INT_REGNO_P (regno);
   11580                 :           0 :     case ADDR_GPR16:
   11581                 :           0 :       return GENERAL_GPR16_REGNO_P (regno);
   11582                 :      916894 :     case ADDR_GPR32:
   11583                 :      916894 :       break;
   11584                 :           0 :     default:
   11585                 :           0 :       gcc_unreachable ();
   11586                 :             :     }
   11587                 :             : 
   11588                 :      916894 :   return GENERAL_REGNO_P (regno);
   11589                 :             : }
   11590                 :             : 
   11591                 :             : enum reg_class
   11592                 :    34814428 : ix86_insn_index_reg_class (rtx_insn* insn)
   11593                 :             : {
   11594                 :    34814428 :   switch (ix86_memory_address_reg_class (insn))
   11595                 :             :     {
   11596                 :             :     case ADDR_GPR8:
   11597                 :             :       return LEGACY_INDEX_REGS;
   11598                 :             :     case ADDR_GPR16:
   11599                 :             :       return INDEX_GPR16;
   11600                 :             :     case ADDR_GPR32:
   11601                 :             :       break;
   11602                 :           0 :     default:
   11603                 :           0 :       gcc_unreachable ();
   11604                 :             :     }
   11605                 :             : 
   11606                 :             :   return INDEX_REG_CLASS;
   11607                 :             : }
   11608                 :             : 
   11609                 :             : /* Recognizes RTL expressions that are valid memory addresses for an
   11610                 :             :    instruction.  The MODE argument is the machine mode for the MEM
   11611                 :             :    expression that wants to use this address.
   11612                 :             : 
   11613                 :             :    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
   11614                 :             :    convert common non-canonical forms to canonical form so that they will
   11615                 :             :    be recognized.  */
   11616                 :             : 
   11617                 :             : static bool
   11618                 :  1820203794 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
   11619                 :             :                            code_helper = ERROR_MARK)
   11620                 :             : {
   11621                 :  1820203794 :   struct ix86_address parts;
   11622                 :  1820203794 :   rtx base, index, disp;
   11623                 :  1820203794 :   HOST_WIDE_INT scale;
   11624                 :  1820203794 :   addr_space_t seg;
   11625                 :             : 
   11626                 :  1820203794 :   if (ix86_decompose_address (addr, &parts) == 0)
   11627                 :             :     /* Decomposition failed.  */
   11628                 :             :     return false;
   11629                 :             : 
   11630                 :  1812123471 :   base = parts.base;
   11631                 :  1812123471 :   index = parts.index;
   11632                 :  1812123471 :   disp = parts.disp;
   11633                 :  1812123471 :   scale = parts.scale;
   11634                 :  1812123471 :   seg = parts.seg;
   11635                 :             : 
   11636                 :             :   /* Validate base register.  */
   11637                 :  1812123471 :   if (base)
   11638                 :             :     {
   11639                 :   994924468 :       rtx reg = ix86_validate_address_register (base);
   11640                 :             : 
   11641                 :   994924468 :       if (reg == NULL_RTX)
   11642                 :             :         return false;
   11643                 :             : 
   11644                 :   994559369 :       unsigned int regno = REGNO (reg);
   11645                 :   994559369 :       if ((strict && !REGNO_OK_FOR_BASE_P (regno))
   11646                 :   990287358 :           || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
   11647                 :             :         /* Base is not valid.  */
   11648                 :             :         return false;
   11649                 :             :     }
   11650                 :             : 
   11651                 :             :   /* Validate index register.  */
   11652                 :  1810428989 :   if (index)
   11653                 :             :     {
   11654                 :    62595993 :       rtx reg = ix86_validate_address_register (index);
   11655                 :             : 
   11656                 :    62595993 :       if (reg == NULL_RTX)
   11657                 :             :         return false;
   11658                 :             : 
   11659                 :    62549570 :       unsigned int regno = REGNO (reg);
   11660                 :    62549570 :       if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
   11661                 :    62543230 :           || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
   11662                 :             :         /* Index is not valid.  */
   11663                 :             :         return false;
   11664                 :             :     }
   11665                 :             : 
   11666                 :             :   /* Index and base should have the same mode.  */
   11667                 :  1810382327 :   if (base && index
   11668                 :    54399466 :       && GET_MODE (base) != GET_MODE (index))
   11669                 :             :     return false;
   11670                 :             : 
   11671                 :             :   /* Address override works only on the (%reg) part of %fs:(%reg).  */
   11672                 :  1810287971 :   if (seg != ADDR_SPACE_GENERIC
   11673                 :  1810287971 :       && ((base && GET_MODE (base) != word_mode)
   11674                 :      174115 :           || (index && GET_MODE (index) != word_mode)))
   11675                 :             :     return false;
   11676                 :             : 
   11677                 :             :   /* Validate scale factor.  */
   11678                 :  1810287966 :   if (scale != 1)
   11679                 :             :     {
   11680                 :    29656315 :       if (!index)
   11681                 :             :         /* Scale without index.  */
   11682                 :             :         return false;
   11683                 :             : 
   11684                 :    29656315 :       if (scale != 2 && scale != 4 && scale != 8)
   11685                 :             :         /* Scale is not a valid multiplier.  */
   11686                 :             :         return false;
   11687                 :             :     }
   11688                 :             : 
   11689                 :             :   /* Validate displacement.  */
   11690                 :  1807647492 :   if (disp)
   11691                 :             :     {
   11692                 :  1633200268 :       if (ix86_endbr_immediate_operand (disp, VOIDmode))
   11693                 :             :         return false;
   11694                 :             : 
   11695                 :  1633200203 :       if (GET_CODE (disp) == CONST
   11696                 :   125303377 :           && GET_CODE (XEXP (disp, 0)) == UNSPEC
   11697                 :    12439005 :           && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
   11698                 :    12439005 :         switch (XINT (XEXP (disp, 0), 1))
   11699                 :             :           {
   11700                 :             :           /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
   11701                 :             :              when used.  While ABI specify also 32bit relocations, we
   11702                 :             :              don't produce them at all and use IP relative instead.
   11703                 :             :              Allow GOT in 32bit mode for both PIC and non-PIC if symbol
   11704                 :             :              should be loaded via GOT.  */
   11705                 :     1696013 :           case UNSPEC_GOT:
   11706                 :     1696013 :             if (!TARGET_64BIT
   11707                 :     1696013 :                 && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   11708                 :           0 :               goto is_legitimate_pic;
   11709                 :             :             /* FALLTHRU */
   11710                 :     3374095 :           case UNSPEC_GOTOFF:
   11711                 :     3374095 :             gcc_assert (flag_pic);
   11712                 :     3374095 :             if (!TARGET_64BIT)
   11713                 :     3374020 :               goto is_legitimate_pic;
   11714                 :             : 
   11715                 :             :             /* 64bit address unspec.  */
   11716                 :             :             return false;
   11717                 :             : 
   11718                 :     8270493 :           case UNSPEC_GOTPCREL:
   11719                 :     8270493 :             if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   11720                 :        1351 :               goto is_legitimate_pic;
   11721                 :             :             /* FALLTHRU */
   11722                 :     8269142 :           case UNSPEC_PCREL:
   11723                 :     8269142 :             gcc_assert (flag_pic);
   11724                 :     8269142 :             goto is_legitimate_pic;
   11725                 :             : 
   11726                 :             :           case UNSPEC_GOTTPOFF:
   11727                 :             :           case UNSPEC_GOTNTPOFF:
   11728                 :             :           case UNSPEC_INDNTPOFF:
   11729                 :             :           case UNSPEC_NTPOFF:
   11730                 :             :           case UNSPEC_DTPOFF:
   11731                 :             :             break;
   11732                 :             : 
   11733                 :             :           default:
   11734                 :             :             /* Invalid address unspec.  */
   11735                 :             :             return false;
   11736                 :             :           }
   11737                 :             : 
   11738                 :   993231421 :       else if (SYMBOLIC_CONST (disp)
   11739                 :  1733625570 :                && (flag_pic
   11740                 :             : #if TARGET_MACHO
   11741                 :             :                    || (MACHOPIC_INDIRECT
   11742                 :             :                        && !machopic_operand_p (disp))
   11743                 :             : #endif
   11744                 :             :                   ))
   11745                 :             :         {
   11746                 :             : 
   11747                 :    50233842 :         is_legitimate_pic:
   11748                 :    50233842 :           if (TARGET_64BIT && (index || base))
   11749                 :             :             {
   11750                 :             :               /* foo@dtpoff(%rX) is ok.  */
   11751                 :       30309 :               if (GET_CODE (disp) != CONST
   11752                 :        6619 :                   || GET_CODE (XEXP (disp, 0)) != PLUS
   11753                 :        6619 :                   || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
   11754                 :        4366 :                   || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
   11755                 :        4366 :                   || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
   11756                 :        4366 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
   11757                 :             :                 /* Non-constant pic memory reference.  */
   11758                 :             :                 return false;
   11759                 :             :             }
   11760                 :    50203533 :           else if ((!TARGET_MACHO || flag_pic)
   11761                 :    50203533 :                     && ! legitimate_pic_address_disp_p (disp))
   11762                 :             :             /* Displacement is an invalid pic construct.  */
   11763                 :             :             return false;
   11764                 :             : #if TARGET_MACHO
   11765                 :             :           else if (MACHO_DYNAMIC_NO_PIC_P
   11766                 :             :                    && !ix86_legitimate_constant_p (Pmode, disp))
   11767                 :             :             /* displacment must be referenced via non_lazy_pointer */
   11768                 :             :             return false;
   11769                 :             : #endif
   11770                 :             : 
   11771                 :             :           /* This code used to verify that a symbolic pic displacement
   11772                 :             :              includes the pic_offset_table_rtx register.
   11773                 :             : 
   11774                 :             :              While this is good idea, unfortunately these constructs may
   11775                 :             :              be created by "adds using lea" optimization for incorrect
   11776                 :             :              code like:
   11777                 :             : 
   11778                 :             :              int a;
   11779                 :             :              int foo(int i)
   11780                 :             :                {
   11781                 :             :                  return *(&a+i);
   11782                 :             :                }
   11783                 :             : 
   11784                 :             :              This code is nonsensical, but results in addressing
   11785                 :             :              GOT table with pic_offset_table_rtx base.  We can't
   11786                 :             :              just refuse it easily, since it gets matched by
   11787                 :             :              "addsi3" pattern, that later gets split to lea in the
   11788                 :             :              case output register differs from input.  While this
   11789                 :             :              can be handled by separate addsi pattern for this case
   11790                 :             :              that never results in lea, this seems to be easier and
   11791                 :             :              correct fix for crash to disable this test.  */
   11792                 :             :         }
   11793                 :  1582171869 :       else if (GET_CODE (disp) != LABEL_REF
   11794                 :  1581935596 :                && !CONST_INT_P (disp)
   11795                 :   747156073 :                && (GET_CODE (disp) != CONST
   11796                 :   111576239 :                    || !ix86_legitimate_constant_p (Pmode, disp))
   11797                 :  2217761726 :                && (GET_CODE (disp) != SYMBOL_REF
   11798                 :   589992308 :                    || !ix86_legitimate_constant_p (Pmode, disp)))
   11799                 :             :         /* Displacement is not constant.  */
   11800                 :    45654466 :         return false;
   11801                 :  1536517403 :       else if (TARGET_64BIT
   11802                 :  1536517403 :                && !x86_64_immediate_operand (disp, VOIDmode))
   11803                 :             :         /* Displacement is out of range.  */
   11804                 :             :         return false;
   11805                 :             :       /* In x32 mode, constant addresses are sign extended to 64bit, so
   11806                 :             :          we have to prevent addresses from 0x80000000 to 0xffffffff.  */
   11807                 :       23034 :       else if (TARGET_X32 && !(index || base)
   11808                 :       12420 :                && CONST_INT_P (disp)
   11809                 :  1536077996 :                && val_signbit_known_set_p (SImode, INTVAL (disp)))
   11810                 :             :         return false;
   11811                 :             :     }
   11812                 :             : 
   11813                 :             :   /* Everything looks valid.  */
   11814                 :             :   return true;
   11815                 :             : }
   11816                 :             : 
   11817                 :             : /* Determine if a given RTX is a valid constant address.  */
   11818                 :             : 
   11819                 :             : bool
   11820                 :  2329722283 : constant_address_p (rtx x)
   11821                 :             : {
   11822                 :  2329722283 :   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
   11823                 :             : }
   11824                 :             : 
   11825                 :             : /* Return a unique alias set for the GOT.  */
   11826                 :             : 
   11827                 :             : alias_set_type
   11828                 :      183674 : ix86_GOT_alias_set (void)
   11829                 :             : {
   11830                 :      183674 :   static alias_set_type set = -1;
   11831                 :      183674 :   if (set == -1)
   11832                 :        2892 :     set = new_alias_set ();
   11833                 :      183674 :   return set;
   11834                 :             : }
   11835                 :             : 
   11836                 :             : /* Return a legitimate reference for ORIG (an address) using the
   11837                 :             :    register REG.  If REG is 0, a new pseudo is generated.
   11838                 :             : 
   11839                 :             :    There are two types of references that must be handled:
   11840                 :             : 
   11841                 :             :    1. Global data references must load the address from the GOT, via
   11842                 :             :       the PIC reg.  An insn is emitted to do this load, and the reg is
   11843                 :             :       returned.
   11844                 :             : 
   11845                 :             :    2. Static data references, constant pool addresses, and code labels
   11846                 :             :       compute the address as an offset from the GOT, whose base is in
   11847                 :             :       the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
   11848                 :             :       differentiate them from global data objects.  The returned
   11849                 :             :       address is the PIC reg + an unspec constant.
   11850                 :             : 
   11851                 :             :    TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
   11852                 :             :    reg also appears in the address.  */
   11853                 :             : 
   11854                 :             : rtx
   11855                 :      392511 : legitimize_pic_address (rtx orig, rtx reg)
   11856                 :             : {
   11857                 :      392511 :   rtx addr = orig;
   11858                 :      392511 :   rtx new_rtx = orig;
   11859                 :             : 
   11860                 :             : #if TARGET_MACHO
   11861                 :             :   if (TARGET_MACHO && !TARGET_64BIT)
   11862                 :             :     {
   11863                 :             :       if (reg == 0)
   11864                 :             :         reg = gen_reg_rtx (Pmode);
   11865                 :             :       /* Use the generic Mach-O PIC machinery.  */
   11866                 :             :       return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
   11867                 :             :     }
   11868                 :             : #endif
   11869                 :             : 
   11870                 :      392511 :   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   11871                 :             :     {
   11872                 :             :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   11873                 :             :       if (tmp)
   11874                 :             :         return tmp;
   11875                 :             :     }
   11876                 :             : 
   11877                 :      392511 :   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
   11878                 :             :     new_rtx = addr;
   11879                 :      298565 :   else if ((!TARGET_64BIT
   11880                 :       99565 :             || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
   11881                 :             :            && !TARGET_PECOFF
   11882                 :      298662 :            && gotoff_operand (addr, Pmode))
   11883                 :             :     {
   11884                 :             :       /* This symbol may be referenced via a displacement
   11885                 :             :          from the PIC base address (@GOTOFF).  */
   11886                 :       97257 :       if (GET_CODE (addr) == CONST)
   11887                 :        2874 :         addr = XEXP (addr, 0);
   11888                 :             : 
   11889                 :       97257 :       if (GET_CODE (addr) == PLUS)
   11890                 :             :           {
   11891                 :        2874 :             new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
   11892                 :             :                                       UNSPEC_GOTOFF);
   11893                 :        2874 :             new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
   11894                 :             :           }
   11895                 :             :         else
   11896                 :       94383 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
   11897                 :             : 
   11898                 :       97257 :       new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11899                 :             : 
   11900                 :       97257 :       if (TARGET_64BIT)
   11901                 :          13 :         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11902                 :             : 
   11903                 :       97257 :       if (reg != 0)
   11904                 :             :         {
   11905                 :           4 :           gcc_assert (REG_P (reg));
   11906                 :           4 :           new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   11907                 :             :                                          new_rtx, reg, 1, OPTAB_DIRECT);
   11908                 :             :         }
   11909                 :             :       else
   11910                 :       97253 :         new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   11911                 :             :     }
   11912                 :      375457 :   else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
   11913                 :             :            /* We can't always use @GOTOFF for text labels
   11914                 :             :               on VxWorks, see gotoff_operand.  */
   11915                 :      201308 :            || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
   11916                 :             :     {
   11917                 :      174146 :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   11918                 :      174146 :       if (tmp)
   11919                 :             :         return tmp;
   11920                 :             : 
   11921                 :             :       /* For x64 PE-COFF there is no GOT table,
   11922                 :             :          so we use address directly.  */
   11923                 :      174146 :       if (TARGET_64BIT && TARGET_PECOFF)
   11924                 :             :         {
   11925                 :             :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
   11926                 :             :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11927                 :             :         }
   11928                 :      174146 :       else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
   11929                 :             :         {
   11930                 :       92280 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
   11931                 :             :                                     UNSPEC_GOTPCREL);
   11932                 :       92280 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11933                 :       92280 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   11934                 :       92280 :           set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
   11935                 :             :         }
   11936                 :             :       else
   11937                 :             :         {
   11938                 :             :           /* This symbol must be referenced via a load
   11939                 :             :              from the Global Offset Table (@GOT).  */
   11940                 :       81866 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
   11941                 :       81866 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11942                 :             : 
   11943                 :       81866 :           if (TARGET_64BIT)
   11944                 :          26 :             new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11945                 :             : 
   11946                 :       81866 :           if (reg != 0)
   11947                 :             :             {
   11948                 :           0 :               gcc_assert (REG_P (reg));
   11949                 :           0 :               new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   11950                 :             :                                              new_rtx, reg, 1, OPTAB_DIRECT);
   11951                 :             :             }
   11952                 :             :           else
   11953                 :       81866 :             new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   11954                 :             : 
   11955                 :       81866 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   11956                 :       81866 :           set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
   11957                 :             :         }
   11958                 :             : 
   11959                 :      174146 :       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   11960                 :             :     }
   11961                 :             :   else
   11962                 :             :     {
   11963                 :       27162 :       if (CONST_INT_P (addr)
   11964                 :       27162 :           && !x86_64_immediate_operand (addr, VOIDmode))
   11965                 :           8 :         new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
   11966                 :       27154 :       else if (GET_CODE (addr) == CONST)
   11967                 :             :         {
   11968                 :       16731 :           addr = XEXP (addr, 0);
   11969                 :             : 
   11970                 :             :           /* We must match stuff we generate before.  Assume the only
   11971                 :             :              unspecs that can get here are ours.  Not that we could do
   11972                 :             :              anything with them anyway....  */
   11973                 :       16731 :           if (GET_CODE (addr) == UNSPEC
   11974                 :        8926 :               || (GET_CODE (addr) == PLUS
   11975                 :        8926 :                   && GET_CODE (XEXP (addr, 0)) == UNSPEC))
   11976                 :             :             return orig;
   11977                 :        6847 :           gcc_assert (GET_CODE (addr) == PLUS);
   11978                 :             :         }
   11979                 :             : 
   11980                 :       17278 :       if (GET_CODE (addr) == PLUS)
   11981                 :             :         {
   11982                 :        8640 :           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
   11983                 :             : 
   11984                 :             :           /* Check first to see if this is a constant
   11985                 :             :              offset from a @GOTOFF symbol reference.  */
   11986                 :        8640 :           if (!TARGET_PECOFF
   11987                 :        8640 :               && gotoff_operand (op0, Pmode)
   11988                 :        8640 :               && CONST_INT_P (op1))
   11989                 :             :             {
   11990                 :           5 :               if (!TARGET_64BIT)
   11991                 :             :                 {
   11992                 :           0 :                   new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
   11993                 :             :                                             UNSPEC_GOTOFF);
   11994                 :           0 :                   new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
   11995                 :           0 :                   new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   11996                 :             : 
   11997                 :           0 :                   if (reg != 0)
   11998                 :             :                     {
   11999                 :           0 :                       gcc_assert (REG_P (reg));
   12000                 :           0 :                       new_rtx = expand_simple_binop (Pmode, PLUS,
   12001                 :             :                                                      pic_offset_table_rtx,
   12002                 :             :                                                      new_rtx, reg, 1,
   12003                 :             :                                                      OPTAB_DIRECT);
   12004                 :             :                     }
   12005                 :             :                   else
   12006                 :           0 :                     new_rtx
   12007                 :           0 :                       = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12008                 :             :                 }
   12009                 :             :               else
   12010                 :             :                 {
   12011                 :           5 :                   if (INTVAL (op1) < -16*1024*1024
   12012                 :           5 :                       || INTVAL (op1) >= 16*1024*1024)
   12013                 :             :                     {
   12014                 :           5 :                       if (!x86_64_immediate_operand (op1, Pmode))
   12015                 :           5 :                         op1 = force_reg (Pmode, op1);
   12016                 :             : 
   12017                 :           5 :                       new_rtx
   12018                 :           5 :                         = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
   12019                 :             :                     }
   12020                 :             :                 }
   12021                 :             :             }
   12022                 :             :           else
   12023                 :             :             {
   12024                 :        8635 :               rtx base = legitimize_pic_address (op0, reg);
   12025                 :        8635 :               machine_mode mode = GET_MODE (base);
   12026                 :        8635 :               new_rtx
   12027                 :        8635 :                 = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
   12028                 :             : 
   12029                 :        8635 :               if (CONST_INT_P (new_rtx))
   12030                 :             :                 {
   12031                 :        6834 :                   if (INTVAL (new_rtx) < -16*1024*1024
   12032                 :        6834 :                       || INTVAL (new_rtx) >= 16*1024*1024)
   12033                 :             :                     {
   12034                 :           0 :                       if (!x86_64_immediate_operand (new_rtx, mode))
   12035                 :           0 :                         new_rtx = force_reg (mode, new_rtx);
   12036                 :             : 
   12037                 :           0 :                       new_rtx
   12038                 :           0 :                         = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
   12039                 :             :                     }
   12040                 :             :                   else
   12041                 :        6834 :                     new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
   12042                 :             :                 }
   12043                 :             :               else
   12044                 :             :                 {
   12045                 :             :                   /* For %rip addressing, we have to use
   12046                 :             :                      just disp32, not base nor index.  */
   12047                 :        1801 :                   if (TARGET_64BIT
   12048                 :          99 :                       && (GET_CODE (base) == SYMBOL_REF
   12049                 :          99 :                           || GET_CODE (base) == LABEL_REF))
   12050                 :           7 :                     base = force_reg (mode, base);
   12051                 :        1801 :                   if (GET_CODE (new_rtx) == PLUS
   12052                 :        1678 :                       && CONSTANT_P (XEXP (new_rtx, 1)))
   12053                 :             :                     {
   12054                 :        1674 :                       base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
   12055                 :        1674 :                       new_rtx = XEXP (new_rtx, 1);
   12056                 :             :                     }
   12057                 :        1801 :                   new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
   12058                 :             :                 }
   12059                 :             :             }
   12060                 :             :         }
   12061                 :             :     }
   12062                 :             :   return new_rtx;
   12063                 :             : }
   12064                 :             : 
   12065                 :             : /* Load the thread pointer.  If TO_REG is true, force it into a register.  */
   12066                 :             : 
   12067                 :             : static rtx
   12068                 :       21624 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
   12069                 :             : {
   12070                 :       21624 :   rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
   12071                 :             : 
   12072                 :       21624 :   if (GET_MODE (tp) != tp_mode)
   12073                 :             :     {
   12074                 :           7 :       gcc_assert (GET_MODE (tp) == SImode);
   12075                 :           7 :       gcc_assert (tp_mode == DImode);
   12076                 :             : 
   12077                 :           7 :       tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
   12078                 :             :     }
   12079                 :             : 
   12080                 :       21624 :   if (to_reg)
   12081                 :        7542 :     tp = copy_to_mode_reg (tp_mode, tp);
   12082                 :             : 
   12083                 :       21624 :   return tp;
   12084                 :             : }
   12085                 :             : 
   12086                 :             : /* Construct the SYMBOL_REF for the tls_get_addr function.  */
   12087                 :             : 
   12088                 :             : static GTY(()) rtx ix86_tls_symbol;
   12089                 :             : 
   12090                 :             : static rtx
   12091                 :        6955 : ix86_tls_get_addr (void)
   12092                 :             : {
   12093                 :        6955 :   if (!ix86_tls_symbol)
   12094                 :             :     {
   12095                 :         830 :       const char *sym
   12096                 :         415 :         = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
   12097                 :         415 :            ? "___tls_get_addr" : "__tls_get_addr");
   12098                 :             : 
   12099                 :         415 :       ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
   12100                 :             :     }
   12101                 :             : 
   12102                 :        6955 :   if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
   12103                 :             :     {
   12104                 :           0 :       rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
   12105                 :             :                                    UNSPEC_PLTOFF);
   12106                 :           0 :       return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
   12107                 :             :                            gen_rtx_CONST (Pmode, unspec));
   12108                 :             :     }
   12109                 :             : 
   12110                 :        6955 :   return ix86_tls_symbol;
   12111                 :             : }
   12112                 :             : 
   12113                 :             : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
   12114                 :             : 
   12115                 :             : static GTY(()) rtx ix86_tls_module_base_symbol;
   12116                 :             : 
   12117                 :             : rtx
   12118                 :           8 : ix86_tls_module_base (void)
   12119                 :             : {
   12120                 :           8 :   if (!ix86_tls_module_base_symbol)
   12121                 :             :     {
   12122                 :           2 :       ix86_tls_module_base_symbol
   12123                 :           2 :         = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
   12124                 :             : 
   12125                 :           2 :       SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
   12126                 :           2 :         |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
   12127                 :             :     }
   12128                 :             : 
   12129                 :           8 :   return ix86_tls_module_base_symbol;
   12130                 :             : }
   12131                 :             : 
   12132                 :             : /* A subroutine of ix86_legitimize_address and ix86_expand_move.  FOR_MOV is
   12133                 :             :    false if we expect this to be used for a memory address and true if
   12134                 :             :    we expect to load the address into a register.  */
   12135                 :             : 
   12136                 :             : rtx
   12137                 :       28579 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
   12138                 :             : {
   12139                 :       28579 :   rtx dest, base, off;
   12140                 :       28579 :   rtx pic = NULL_RTX, tp = NULL_RTX;
   12141                 :       28579 :   machine_mode tp_mode = Pmode;
   12142                 :       28579 :   int type;
   12143                 :             : 
   12144                 :             :   /* Fall back to global dynamic model if tool chain cannot support local
   12145                 :             :      dynamic.  */
   12146                 :       28579 :   if (TARGET_SUN_TLS && !TARGET_64BIT
   12147                 :             :       && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
   12148                 :             :       && model == TLS_MODEL_LOCAL_DYNAMIC)
   12149                 :             :     model = TLS_MODEL_GLOBAL_DYNAMIC;
   12150                 :             : 
   12151                 :       28579 :   switch (model)
   12152                 :             :     {
   12153                 :        6537 :     case TLS_MODEL_GLOBAL_DYNAMIC:
   12154                 :        6537 :       if (!TARGET_64BIT)
   12155                 :             :         {
   12156                 :        2076 :           if (flag_pic && !TARGET_PECOFF)
   12157                 :        2076 :             pic = pic_offset_table_rtx;
   12158                 :             :           else
   12159                 :             :             {
   12160                 :           0 :               pic = gen_reg_rtx (Pmode);
   12161                 :           0 :               emit_insn (gen_set_got (pic));
   12162                 :             :             }
   12163                 :             :         }
   12164                 :             : 
   12165                 :        6537 :       if (TARGET_GNU2_TLS)
   12166                 :             :         {
   12167                 :          12 :           dest = gen_reg_rtx (ptr_mode);
   12168                 :          12 :           if (TARGET_64BIT)
   12169                 :          12 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
   12170                 :             :           else
   12171                 :           0 :             emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
   12172                 :             : 
   12173                 :          12 :           tp = get_thread_pointer (ptr_mode, true);
   12174                 :          12 :           dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12175                 :          12 :           if (GET_MODE (dest) != Pmode)
   12176                 :           6 :              dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12177                 :          12 :           dest = force_reg (Pmode, dest);
   12178                 :             : 
   12179                 :          12 :           if (GET_MODE (x) != Pmode)
   12180                 :           3 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12181                 :             : 
   12182                 :          12 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12183                 :             :         }
   12184                 :             :       else
   12185                 :             :         {
   12186                 :        6525 :           rtx caddr = ix86_tls_get_addr ();
   12187                 :             : 
   12188                 :        6525 :           dest = gen_reg_rtx (Pmode);
   12189                 :        6525 :           if (TARGET_64BIT)
   12190                 :             :             {
   12191                 :        4449 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12192                 :        4449 :               rtx_insn *insns;
   12193                 :             : 
   12194                 :        4449 :               start_sequence ();
   12195                 :        4449 :               emit_call_insn
   12196                 :        4449 :                 (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr));
   12197                 :        4449 :               insns = get_insns ();
   12198                 :        4449 :               end_sequence ();
   12199                 :             : 
   12200                 :        4449 :               if (GET_MODE (x) != Pmode)
   12201                 :           1 :                 x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12202                 :             : 
   12203                 :        4449 :               RTL_CONST_CALL_P (insns) = 1;
   12204                 :        4449 :               emit_libcall_block (insns, dest, rax, x);
   12205                 :             :             }
   12206                 :             :           else
   12207                 :        2076 :             emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
   12208                 :             :         }
   12209                 :             :       break;
   12210                 :             : 
   12211                 :         434 :     case TLS_MODEL_LOCAL_DYNAMIC:
   12212                 :         434 :       if (!TARGET_64BIT)
   12213                 :             :         {
   12214                 :         110 :           if (flag_pic)
   12215                 :         110 :             pic = pic_offset_table_rtx;
   12216                 :             :           else
   12217                 :             :             {
   12218                 :           0 :               pic = gen_reg_rtx (Pmode);
   12219                 :           0 :               emit_insn (gen_set_got (pic));
   12220                 :             :             }
   12221                 :             :         }
   12222                 :             : 
   12223                 :         434 :       if (TARGET_GNU2_TLS)
   12224                 :             :         {
   12225                 :           4 :           rtx tmp = ix86_tls_module_base ();
   12226                 :             : 
   12227                 :           4 :           base = gen_reg_rtx (ptr_mode);
   12228                 :           4 :           if (TARGET_64BIT)
   12229                 :           4 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
   12230                 :             :           else
   12231                 :           0 :             emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
   12232                 :             : 
   12233                 :           4 :           tp = get_thread_pointer (ptr_mode, true);
   12234                 :           4 :           if (GET_MODE (base) != Pmode)
   12235                 :           2 :             base = gen_rtx_ZERO_EXTEND (Pmode, base);
   12236                 :           4 :           base = force_reg (Pmode, base);
   12237                 :             :         }
   12238                 :             :       else
   12239                 :             :         {
   12240                 :         430 :           rtx caddr = ix86_tls_get_addr ();
   12241                 :             : 
   12242                 :         430 :           base = gen_reg_rtx (Pmode);
   12243                 :         430 :           if (TARGET_64BIT)
   12244                 :             :             {
   12245                 :         320 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12246                 :         320 :               rtx_insn *insns;
   12247                 :         320 :               rtx eqv;
   12248                 :             : 
   12249                 :         320 :               start_sequence ();
   12250                 :         320 :               emit_call_insn
   12251                 :         320 :                 (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr));
   12252                 :         320 :               insns = get_insns ();
   12253                 :         320 :               end_sequence ();
   12254                 :             : 
   12255                 :             :               /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
   12256                 :             :                  share the LD_BASE result with other LD model accesses.  */
   12257                 :         320 :               eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   12258                 :             :                                     UNSPEC_TLS_LD_BASE);
   12259                 :             : 
   12260                 :         320 :               RTL_CONST_CALL_P (insns) = 1;
   12261                 :         320 :               emit_libcall_block (insns, base, rax, eqv);
   12262                 :             :             }
   12263                 :             :           else
   12264                 :         110 :             emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
   12265                 :             :         }
   12266                 :             : 
   12267                 :         434 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
   12268                 :         434 :       off = gen_rtx_CONST (Pmode, off);
   12269                 :             : 
   12270                 :         434 :       dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
   12271                 :             : 
   12272                 :         434 :       if (TARGET_GNU2_TLS)
   12273                 :             :         {
   12274                 :           4 :           if (GET_MODE (tp) != Pmode)
   12275                 :             :             {
   12276                 :           2 :               dest = lowpart_subreg (ptr_mode, dest, Pmode);
   12277                 :           2 :               dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12278                 :           2 :               dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12279                 :             :             }
   12280                 :             :           else
   12281                 :           2 :             dest = gen_rtx_PLUS (Pmode, tp, dest);
   12282                 :           4 :           dest = force_reg (Pmode, dest);
   12283                 :             : 
   12284                 :           4 :           if (GET_MODE (x) != Pmode)
   12285                 :           1 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12286                 :             : 
   12287                 :           4 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12288                 :             :         }
   12289                 :             :       break;
   12290                 :             : 
   12291                 :        9516 :     case TLS_MODEL_INITIAL_EXEC:
   12292                 :        9516 :       if (TARGET_64BIT)
   12293                 :             :         {
   12294                 :             :           if (TARGET_SUN_TLS && !TARGET_X32)
   12295                 :             :             {
   12296                 :             :               /* The Sun linker took the AMD64 TLS spec literally
   12297                 :             :                  and can only handle %rax as destination of the
   12298                 :             :                  initial executable code sequence.  */
   12299                 :             : 
   12300                 :             :               dest = gen_reg_rtx (DImode);
   12301                 :             :               emit_insn (gen_tls_initial_exec_64_sun (dest, x));
   12302                 :             :               return dest;
   12303                 :             :             }
   12304                 :             : 
   12305                 :             :           /* Generate DImode references to avoid %fs:(%reg32)
   12306                 :             :              problems and linker IE->LE relaxation bug.  */
   12307                 :             :           tp_mode = DImode;
   12308                 :             :           pic = NULL;
   12309                 :             :           type = UNSPEC_GOTNTPOFF;
   12310                 :             :         }
   12311                 :         741 :       else if (flag_pic)
   12312                 :             :         {
   12313                 :         740 :           pic = pic_offset_table_rtx;
   12314                 :         740 :           type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
   12315                 :             :         }
   12316                 :           1 :       else if (!TARGET_ANY_GNU_TLS)
   12317                 :             :         {
   12318                 :           0 :           pic = gen_reg_rtx (Pmode);
   12319                 :           0 :           emit_insn (gen_set_got (pic));
   12320                 :           0 :           type = UNSPEC_GOTTPOFF;
   12321                 :             :         }
   12322                 :             :       else
   12323                 :             :         {
   12324                 :             :           pic = NULL;
   12325                 :             :           type = UNSPEC_INDNTPOFF;
   12326                 :             :         }
   12327                 :             : 
   12328                 :        9516 :       off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
   12329                 :        9516 :       off = gen_rtx_CONST (tp_mode, off);
   12330                 :        9516 :       if (pic)
   12331                 :         740 :         off = gen_rtx_PLUS (tp_mode, pic, off);
   12332                 :        9516 :       off = gen_const_mem (tp_mode, off);
   12333                 :        9516 :       set_mem_alias_set (off, ix86_GOT_alias_set ());
   12334                 :             : 
   12335                 :        9516 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12336                 :             :         {
   12337                 :        9516 :           base = get_thread_pointer (tp_mode,
   12338                 :        9516 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12339                 :        9516 :           off = force_reg (tp_mode, off);
   12340                 :        9516 :           dest = gen_rtx_PLUS (tp_mode, base, off);
   12341                 :        9516 :           if (tp_mode != Pmode)
   12342                 :           4 :             dest = convert_to_mode (Pmode, dest, 1);
   12343                 :             :         }
   12344                 :             :       else
   12345                 :             :         {
   12346                 :           0 :           base = get_thread_pointer (Pmode, true);
   12347                 :           0 :           dest = gen_reg_rtx (Pmode);
   12348                 :           0 :           emit_insn (gen_sub3_insn (dest, base, off));
   12349                 :             :         }
   12350                 :             :       break;
   12351                 :             : 
   12352                 :       12092 :     case TLS_MODEL_LOCAL_EXEC:
   12353                 :       24184 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   12354                 :             :                             (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12355                 :             :                             ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
   12356                 :       12092 :       off = gen_rtx_CONST (Pmode, off);
   12357                 :             : 
   12358                 :       12092 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12359                 :             :         {
   12360                 :       12092 :           base = get_thread_pointer (Pmode,
   12361                 :       12092 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12362                 :       12092 :           return gen_rtx_PLUS (Pmode, base, off);
   12363                 :             :         }
   12364                 :             :       else
   12365                 :             :         {
   12366                 :           0 :           base = get_thread_pointer (Pmode, true);
   12367                 :           0 :           dest = gen_reg_rtx (Pmode);
   12368                 :           0 :           emit_insn (gen_sub3_insn (dest, base, off));
   12369                 :             :         }
   12370                 :           0 :       break;
   12371                 :             : 
   12372                 :           0 :     default:
   12373                 :           0 :       gcc_unreachable ();
   12374                 :             :     }
   12375                 :             : 
   12376                 :             :   return dest;
   12377                 :             : }
   12378                 :             : 
   12379                 :             : /* Return true if the TLS address requires insn using integer registers.
   12380                 :             :    It's used to prevent KMOV/VMOV in TLS code sequences which require integer
   12381                 :             :    MOV instructions, refer to PR103275.  */
   12382                 :             : bool
   12383                 :     4217396 : ix86_gpr_tls_address_pattern_p (rtx mem)
   12384                 :             : {
   12385                 :     4217396 :   gcc_assert (MEM_P (mem));
   12386                 :             : 
   12387                 :     4217396 :   rtx addr = XEXP (mem, 0);
   12388                 :     4217396 :   subrtx_var_iterator::array_type array;
   12389                 :    13738085 :   FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
   12390                 :             :     {
   12391                 :     9520689 :       rtx op = *iter;
   12392                 :     9520689 :       if (GET_CODE (op) == UNSPEC)
   12393                 :       28848 :         switch (XINT (op, 1))
   12394                 :             :           {
   12395                 :             :           case UNSPEC_GOTNTPOFF:
   12396                 :           0 :             return true;
   12397                 :           0 :           case UNSPEC_TPOFF:
   12398                 :           0 :             if (!TARGET_64BIT)
   12399                 :             :               return true;
   12400                 :             :             break;
   12401                 :             :           default:
   12402                 :             :             break;
   12403                 :             :           }
   12404                 :             :     }
   12405                 :             : 
   12406                 :     4217396 :   return false;
   12407                 :     4217396 : }
   12408                 :             : 
   12409                 :             : /* Return true if OP refers to a TLS address.  */
   12410                 :             : bool
   12411                 :   214763177 : ix86_tls_address_pattern_p (rtx op)
   12412                 :             : {
   12413                 :   214763177 :   subrtx_var_iterator::array_type array;
   12414                 :  1264785375 :   FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
   12415                 :             :     {
   12416                 :  1050037623 :       rtx op = *iter;
   12417                 :  1050037623 :       if (MEM_P (op))
   12418                 :             :         {
   12419                 :    96086568 :           rtx *x = &XEXP (op, 0);
   12420                 :   150125242 :           while (GET_CODE (*x) == PLUS)
   12421                 :             :             {
   12422                 :             :               int i;
   12423                 :   162131470 :               for (i = 0; i < 2; i++)
   12424                 :             :                 {
   12425                 :   108092796 :                   rtx u = XEXP (*x, i);
   12426                 :   108092796 :                   if (GET_CODE (u) == ZERO_EXTEND)
   12427                 :       98837 :                     u = XEXP (u, 0);
   12428                 :   108092796 :                   if (GET_CODE (u) == UNSPEC
   12429                 :       15447 :                       && XINT (u, 1) == UNSPEC_TP)
   12430                 :       15425 :                     return true;
   12431                 :             :                 }
   12432                 :    54038674 :               x = &XEXP (*x, 0);
   12433                 :             :             }
   12434                 :             : 
   12435                 :    96071143 :           iter.skip_subrtxes ();
   12436                 :             :         }
   12437                 :             :     }
   12438                 :             : 
   12439                 :   214747752 :   return false;
   12440                 :   214763177 : }
   12441                 :             : 
   12442                 :             : /* Rewrite *LOC so that it refers to a default TLS address space.  */
   12443                 :             : void
   12444                 :       15425 : ix86_rewrite_tls_address_1 (rtx *loc)
   12445                 :             : {
   12446                 :       15425 :   subrtx_ptr_iterator::array_type array;
   12447                 :       44976 :   FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
   12448                 :             :     {
   12449                 :       44976 :       rtx *loc = *iter;
   12450                 :       44976 :       if (MEM_P (*loc))
   12451                 :             :         {
   12452                 :       15582 :           rtx addr = XEXP (*loc, 0);
   12453                 :       15582 :           rtx *x = &addr;
   12454                 :       20368 :           while (GET_CODE (*x) == PLUS)
   12455                 :             :             {
   12456                 :             :               int i;
   12457                 :       29806 :               for (i = 0; i < 2; i++)
   12458                 :             :                 {
   12459                 :       25020 :                   rtx u = XEXP (*x, i);
   12460                 :       25020 :                   if (GET_CODE (u) == ZERO_EXTEND)
   12461                 :           3 :                     u = XEXP (u, 0);
   12462                 :       25020 :                   if (GET_CODE (u) == UNSPEC
   12463                 :       15425 :                       && XINT (u, 1) == UNSPEC_TP)
   12464                 :             :                     {
   12465                 :       15425 :                       addr_space_t as = DEFAULT_TLS_SEG_REG;
   12466                 :             : 
   12467                 :       15425 :                       *x = XEXP (*x, 1 - i);
   12468                 :             : 
   12469                 :       15425 :                       *loc = replace_equiv_address_nv (*loc, addr, true);
   12470                 :       15425 :                       set_mem_addr_space (*loc, as);
   12471                 :       15425 :                       return;
   12472                 :             :                     }
   12473                 :             :                 }
   12474                 :        4786 :               x = &XEXP (*x, 0);
   12475                 :             :             }
   12476                 :             : 
   12477                 :         157 :           iter.skip_subrtxes ();
   12478                 :             :         }
   12479                 :             :     }
   12480                 :       15425 : }
   12481                 :             : 
   12482                 :             : /* Rewrite instruction pattern involvning TLS address
   12483                 :             :    so that it refers to a default TLS address space.  */
   12484                 :             : rtx
   12485                 :       15425 : ix86_rewrite_tls_address (rtx pattern)
   12486                 :             : {
   12487                 :       15425 :   pattern = copy_insn (pattern);
   12488                 :       15425 :   ix86_rewrite_tls_address_1 (&pattern);
   12489                 :       15425 :   return pattern;
   12490                 :             : }
   12491                 :             : 
   12492                 :             : /* Create or return the unique __imp_DECL dllimport symbol corresponding
   12493                 :             :    to symbol DECL if BEIMPORT is true.  Otherwise create or return the
   12494                 :             :    unique refptr-DECL symbol corresponding to symbol DECL.  */
   12495                 :             : 
   12496                 :             : struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
   12497                 :             : {
   12498                 :           0 :   static inline hashval_t hash (tree_map *m) { return m->hash; }
   12499                 :             :   static inline bool
   12500                 :           0 :   equal (tree_map *a, tree_map *b)
   12501                 :             :   {
   12502                 :           0 :     return a->base.from == b->base.from;
   12503                 :             :   }
   12504                 :             : 
   12505                 :             :   static int
   12506                 :           0 :   keep_cache_entry (tree_map *&m)
   12507                 :             :   {
   12508                 :           0 :     return ggc_marked_p (m->base.from);
   12509                 :             :   }
   12510                 :             : };
   12511                 :             : 
   12512                 :             : static GTY((cache)) hash_table<dllimport_hasher> *dllimport_map;
   12513                 :             : 
   12514                 :             : static tree
   12515                 :           0 : get_dllimport_decl (tree decl, bool beimport)
   12516                 :             : {
   12517                 :           0 :   struct tree_map *h, in;
   12518                 :           0 :   const char *name;
   12519                 :           0 :   const char *prefix;
   12520                 :           0 :   size_t namelen, prefixlen;
   12521                 :           0 :   char *imp_name;
   12522                 :           0 :   tree to;
   12523                 :           0 :   rtx rtl;
   12524                 :             : 
   12525                 :           0 :   if (!dllimport_map)
   12526                 :           0 :     dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
   12527                 :             : 
   12528                 :           0 :   in.hash = htab_hash_pointer (decl);
   12529                 :           0 :   in.base.from = decl;
   12530                 :           0 :   tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
   12531                 :           0 :   h = *loc;
   12532                 :           0 :   if (h)
   12533                 :           0 :     return h->to;
   12534                 :             : 
   12535                 :           0 :   *loc = h = ggc_alloc<tree_map> ();
   12536                 :           0 :   h->hash = in.hash;
   12537                 :           0 :   h->base.from = decl;
   12538                 :           0 :   h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
   12539                 :             :                            VAR_DECL, NULL, ptr_type_node);
   12540                 :           0 :   DECL_ARTIFICIAL (to) = 1;
   12541                 :           0 :   DECL_IGNORED_P (to) = 1;
   12542                 :           0 :   DECL_EXTERNAL (to) = 1;
   12543                 :           0 :   TREE_READONLY (to) = 1;
   12544                 :             : 
   12545                 :           0 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   12546                 :           0 :   name = targetm.strip_name_encoding (name);
   12547                 :           0 :   if (beimport)
   12548                 :           0 :     prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
   12549                 :           0 :       ? "*__imp_" : "*__imp__";
   12550                 :             :   else
   12551                 :           0 :     prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
   12552                 :           0 :   namelen = strlen (name);
   12553                 :           0 :   prefixlen = strlen (prefix);
   12554                 :           0 :   imp_name = (char *) alloca (namelen + prefixlen + 1);
   12555                 :           0 :   memcpy (imp_name, prefix, prefixlen);
   12556                 :           0 :   memcpy (imp_name + prefixlen, name, namelen + 1);
   12557                 :             : 
   12558                 :           0 :   name = ggc_alloc_string (imp_name, namelen + prefixlen);
   12559                 :           0 :   rtl = gen_rtx_SYMBOL_REF (Pmode, name);
   12560                 :           0 :   SET_SYMBOL_REF_DECL (rtl, to);
   12561                 :           0 :   SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
   12562                 :           0 :   if (!beimport)
   12563                 :             :     {
   12564                 :           0 :       SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
   12565                 :             : #ifdef SUB_TARGET_RECORD_STUB
   12566                 :             :       SUB_TARGET_RECORD_STUB (name);
   12567                 :             : #endif
   12568                 :             :     }      
   12569                 :             : 
   12570                 :           0 :   rtl = gen_const_mem (Pmode, rtl);
   12571                 :           0 :   set_mem_alias_set (rtl, ix86_GOT_alias_set ());
   12572                 :             : 
   12573                 :           0 :   SET_DECL_RTL (to, rtl);
   12574                 :           0 :   SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
   12575                 :             : 
   12576                 :           0 :   return to;
   12577                 :             : }
   12578                 :             : 
   12579                 :             : /* Expand SYMBOL into its corresponding far-address symbol.
   12580                 :             :    WANT_REG is true if we require the result be a register.  */
   12581                 :             : 
   12582                 :             : static rtx
   12583                 :           0 : legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
   12584                 :             : {
   12585                 :           0 :   tree imp_decl;
   12586                 :           0 :   rtx x;
   12587                 :             : 
   12588                 :           0 :   gcc_assert (SYMBOL_REF_DECL (symbol));
   12589                 :           0 :   imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
   12590                 :             : 
   12591                 :           0 :   x = DECL_RTL (imp_decl);
   12592                 :           0 :   if (want_reg)
   12593                 :           0 :     x = force_reg (Pmode, x);
   12594                 :           0 :   return x;
   12595                 :             : }
   12596                 :             : 
   12597                 :             : /* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
   12598                 :             :    true if we require the result be a register.  */
   12599                 :             : 
   12600                 :             : static rtx
   12601                 :           0 : legitimize_dllimport_symbol (rtx symbol, bool want_reg)
   12602                 :             : {
   12603                 :           0 :   tree imp_decl;
   12604                 :           0 :   rtx x;
   12605                 :             : 
   12606                 :           0 :   gcc_assert (SYMBOL_REF_DECL (symbol));
   12607                 :           0 :   imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
   12608                 :             : 
   12609                 :           0 :   x = DECL_RTL (imp_decl);
   12610                 :           0 :   if (want_reg)
   12611                 :           0 :     x = force_reg (Pmode, x);
   12612                 :           0 :   return x;
   12613                 :             : }
   12614                 :             : 
   12615                 :             : /* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG 
   12616                 :             :    is true if we require the result be a register.  */
   12617                 :             : 
   12618                 :             : rtx
   12619                 :     4828360 : legitimize_pe_coff_symbol (rtx addr, bool inreg)
   12620                 :             : {
   12621                 :     4828360 :   if (!TARGET_PECOFF)
   12622                 :     4828360 :     return NULL_RTX;
   12623                 :             : 
   12624                 :             :   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   12625                 :             :     {
   12626                 :             :       if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
   12627                 :             :         return legitimize_dllimport_symbol (addr, inreg);
   12628                 :             :       if (GET_CODE (addr) == CONST
   12629                 :             :           && GET_CODE (XEXP (addr, 0)) == PLUS
   12630                 :             :           && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
   12631                 :             :           && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
   12632                 :             :         {
   12633                 :             :           rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
   12634                 :             :           return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
   12635                 :             :         }
   12636                 :             :     }
   12637                 :             : 
   12638                 :             :   if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
   12639                 :             :     return NULL_RTX;
   12640                 :             :   if (GET_CODE (addr) == SYMBOL_REF
   12641                 :             :       && !is_imported_p (addr)
   12642                 :             :       && SYMBOL_REF_EXTERNAL_P (addr)
   12643                 :             :       && SYMBOL_REF_DECL (addr))
   12644                 :             :     return legitimize_pe_coff_extern_decl (addr, inreg);
   12645                 :             : 
   12646                 :             :   if (GET_CODE (addr) == CONST
   12647                 :             :       && GET_CODE (XEXP (addr, 0)) == PLUS
   12648                 :             :       && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
   12649                 :             :       && !is_imported_p (XEXP (XEXP (addr, 0), 0))
   12650                 :             :       && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
   12651                 :             :       && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
   12652                 :             :     {
   12653                 :             :       rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
   12654                 :             :       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
   12655                 :             :     }
   12656                 :             :   return NULL_RTX;
   12657                 :             : }
   12658                 :             : 
   12659                 :             : /* Try machine-dependent ways of modifying an illegitimate address
   12660                 :             :    to be legitimate.  If we find one, return the new, valid address.
   12661                 :             :    This macro is used in only one place: `memory_address' in explow.cc.
   12662                 :             : 
   12663                 :             :    OLDX is the address as it was before break_out_memory_refs was called.
   12664                 :             :    In some cases it is useful to look at this to decide what needs to be done.
   12665                 :             : 
   12666                 :             :    It is always safe for this macro to do nothing.  It exists to recognize
   12667                 :             :    opportunities to optimize the output.
   12668                 :             : 
   12669                 :             :    For the 80386, we handle X+REG by loading X into a register R and
   12670                 :             :    using R+REG.  R will go in a general reg and indexing will be used.
   12671                 :             :    However, if REG is a broken-out memory address or multiplication,
   12672                 :             :    nothing needs to be done because REG can certainly go in a general reg.
   12673                 :             : 
   12674                 :             :    When -fpic is used, special handling is needed for symbolic references.
   12675                 :             :    See comments by legitimize_pic_address in i386.cc for details.  */
   12676                 :             : 
   12677                 :             : static rtx
   12678                 :      587358 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
   12679                 :             : {
   12680                 :      587358 :   bool changed = false;
   12681                 :      587358 :   unsigned log;
   12682                 :             : 
   12683                 :      587358 :   log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0;
   12684                 :      149592 :   if (log)
   12685                 :       18975 :     return legitimize_tls_address (x, (enum tls_model) log, false);
   12686                 :      568383 :   if (GET_CODE (x) == CONST
   12687                 :         431 :       && GET_CODE (XEXP (x, 0)) == PLUS
   12688                 :         431 :       && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
   12689                 :      568814 :       && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
   12690                 :             :     {
   12691                 :           4 :       rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
   12692                 :             :                                       (enum tls_model) log, false);
   12693                 :           4 :       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
   12694                 :             :     }
   12695                 :             : 
   12696                 :      568379 :   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   12697                 :             :     {
   12698                 :             :       rtx tmp = legitimize_pe_coff_symbol (x, true);
   12699                 :             :       if (tmp)
   12700                 :             :         return tmp;
   12701                 :             :     }
   12702                 :             : 
   12703                 :      568379 :   if (flag_pic && SYMBOLIC_CONST (x))
   12704                 :      130925 :     return legitimize_pic_address (x, 0);
   12705                 :             : 
   12706                 :             : #if TARGET_MACHO
   12707                 :             :   if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
   12708                 :             :     return machopic_indirect_data_reference (x, 0);
   12709                 :             : #endif
   12710                 :             : 
   12711                 :             :   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   12712                 :      437454 :   if (GET_CODE (x) == ASHIFT
   12713                 :           0 :       && CONST_INT_P (XEXP (x, 1))
   12714                 :           0 :       && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
   12715                 :             :     {
   12716                 :           0 :       changed = true;
   12717                 :           0 :       log = INTVAL (XEXP (x, 1));
   12718                 :           0 :       x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
   12719                 :             :                         GEN_INT (1 << log));
   12720                 :             :     }
   12721                 :             : 
   12722                 :      437454 :   if (GET_CODE (x) == PLUS)
   12723                 :             :     {
   12724                 :             :       /* Canonicalize shifts by 0, 1, 2, 3 into multiply.  */
   12725                 :             : 
   12726                 :      117877 :       if (GET_CODE (XEXP (x, 0)) == ASHIFT
   12727                 :         567 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   12728                 :         567 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
   12729                 :             :         {
   12730                 :         567 :           changed = true;
   12731                 :         567 :           log = INTVAL (XEXP (XEXP (x, 0), 1));
   12732                 :         567 :           XEXP (x, 0) = gen_rtx_MULT (Pmode,
   12733                 :             :                                       force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
   12734                 :             :                                       GEN_INT (1 << log));
   12735                 :             :         }
   12736                 :             : 
   12737                 :      117877 :       if (GET_CODE (XEXP (x, 1)) == ASHIFT
   12738                 :           0 :           && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   12739                 :           0 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
   12740                 :             :         {
   12741                 :           0 :           changed = true;
   12742                 :           0 :           log = INTVAL (XEXP (XEXP (x, 1), 1));
   12743                 :           0 :           XEXP (x, 1) = gen_rtx_MULT (Pmode,
   12744                 :             :                                       force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
   12745                 :             :                                       GEN_INT (1 << log));
   12746                 :             :         }
   12747                 :             : 
   12748                 :             :       /* Put multiply first if it isn't already.  */
   12749                 :      117877 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   12750                 :             :         {
   12751                 :           0 :           std::swap (XEXP (x, 0), XEXP (x, 1));
   12752                 :           0 :           changed = true;
   12753                 :             :         }
   12754                 :             : 
   12755                 :             :       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
   12756                 :             :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
   12757                 :             :          created by virtual register instantiation, register elimination, and
   12758                 :             :          similar optimizations.  */
   12759                 :      117877 :       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
   12760                 :             :         {
   12761                 :        9306 :           changed = true;
   12762                 :        9306 :           x = gen_rtx_PLUS (Pmode,
   12763                 :             :                             gen_rtx_PLUS (Pmode, XEXP (x, 0),
   12764                 :             :                                           XEXP (XEXP (x, 1), 0)),
   12765                 :             :                             XEXP (XEXP (x, 1), 1));
   12766                 :             :         }
   12767                 :             : 
   12768                 :             :       /* Canonicalize
   12769                 :             :          (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
   12770                 :             :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
   12771                 :      108571 :       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
   12772                 :       71752 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   12773                 :       45893 :                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
   12774                 :           0 :                && CONSTANT_P (XEXP (x, 1)))
   12775                 :             :         {
   12776                 :           0 :           rtx constant;
   12777                 :           0 :           rtx other = NULL_RTX;
   12778                 :             : 
   12779                 :           0 :           if (CONST_INT_P (XEXP (x, 1)))
   12780                 :             :             {
   12781                 :           0 :               constant = XEXP (x, 1);
   12782                 :           0 :               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
   12783                 :             :             }
   12784                 :           0 :           else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
   12785                 :             :             {
   12786                 :             :               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
   12787                 :             :               other = XEXP (x, 1);
   12788                 :             :             }
   12789                 :             :           else
   12790                 :             :             constant = 0;
   12791                 :             : 
   12792                 :           0 :           if (constant)
   12793                 :             :             {
   12794                 :           0 :               changed = true;
   12795                 :           0 :               x = gen_rtx_PLUS (Pmode,
   12796                 :             :                                 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
   12797                 :             :                                               XEXP (XEXP (XEXP (x, 0), 1), 0)),
   12798                 :             :                                 plus_constant (Pmode, other,
   12799                 :             :                                                INTVAL (constant)));
   12800                 :             :             }
   12801                 :             :         }
   12802                 :             : 
   12803                 :      117877 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   12804                 :        9350 :         return x;
   12805                 :             : 
   12806                 :      108527 :       if (GET_CODE (XEXP (x, 0)) == MULT)
   12807                 :             :         {
   12808                 :       18382 :           changed = true;
   12809                 :       18382 :           XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
   12810                 :             :         }
   12811                 :             : 
   12812                 :      108527 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   12813                 :             :         {
   12814                 :           0 :           changed = true;
   12815                 :           0 :           XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
   12816                 :             :         }
   12817                 :             : 
   12818                 :      108527 :       if (changed
   12819                 :       18391 :           && REG_P (XEXP (x, 1))
   12820                 :       14929 :           && REG_P (XEXP (x, 0)))
   12821                 :             :         return x;
   12822                 :             : 
   12823                 :       93598 :       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
   12824                 :             :         {
   12825                 :        1793 :           changed = true;
   12826                 :        1793 :           x = legitimize_pic_address (x, 0);
   12827                 :             :         }
   12828                 :             : 
   12829                 :       93598 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   12830                 :        3719 :         return x;
   12831                 :             : 
   12832                 :       89879 :       if (REG_P (XEXP (x, 0)))
   12833                 :             :         {
   12834                 :       17654 :           rtx temp = gen_reg_rtx (Pmode);
   12835                 :       17654 :           rtx val  = force_operand (XEXP (x, 1), temp);
   12836                 :       17654 :           if (val != temp)
   12837                 :             :             {
   12838                 :        9432 :               val = convert_to_mode (Pmode, val, 1);
   12839                 :        9432 :               emit_move_insn (temp, val);
   12840                 :             :             }
   12841                 :             : 
   12842                 :       17654 :           XEXP (x, 1) = temp;
   12843                 :       17654 :           return x;
   12844                 :             :         }
   12845                 :             : 
   12846                 :       72225 :       else if (REG_P (XEXP (x, 1)))
   12847                 :             :         {
   12848                 :        2554 :           rtx temp = gen_reg_rtx (Pmode);
   12849                 :        2554 :           rtx val  = force_operand (XEXP (x, 0), temp);
   12850                 :        2554 :           if (val != temp)
   12851                 :             :             {
   12852                 :           0 :               val = convert_to_mode (Pmode, val, 1);
   12853                 :           0 :               emit_move_insn (temp, val);
   12854                 :             :             }
   12855                 :             : 
   12856                 :        2554 :           XEXP (x, 0) = temp;
   12857                 :        2554 :           return x;
   12858                 :             :         }
   12859                 :             :     }
   12860                 :             : 
   12861                 :             :   return x;
   12862                 :             : }
   12863                 :             : 
   12864                 :             : /* Print an integer constant expression in assembler syntax.  Addition
   12865                 :             :    and subtraction are the only arithmetic that may appear in these
   12866                 :             :    expressions.  FILE is the stdio stream to write to, X is the rtx, and
   12867                 :             :    CODE is the operand print code from the output string.  */
   12868                 :             : 
   12869                 :             : static void
   12870                 :     3340280 : output_pic_addr_const (FILE *file, rtx x, int code)
   12871                 :             : {
   12872                 :     3562487 :   char buf[256];
   12873                 :             : 
   12874                 :     3562487 :   switch (GET_CODE (x))
   12875                 :             :     {
   12876                 :           0 :     case PC:
   12877                 :           0 :       gcc_assert (flag_pic);
   12878                 :           0 :       putc ('.', file);
   12879                 :           0 :       break;
   12880                 :             : 
   12881                 :      836441 :     case SYMBOL_REF:
   12882                 :      836441 :       if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
   12883                 :      836441 :         output_addr_const (file, x);
   12884                 :             :       else
   12885                 :             :         {
   12886                 :             :           const char *name = XSTR (x, 0);
   12887                 :             : 
   12888                 :             :           /* Mark the decl as referenced so that cgraph will
   12889                 :             :              output the function.  */
   12890                 :             :           if (SYMBOL_REF_DECL (x))
   12891                 :             :             mark_decl_referenced (SYMBOL_REF_DECL (x));
   12892                 :             : 
   12893                 :             : #if TARGET_MACHO
   12894                 :             :           if (MACHOPIC_INDIRECT
   12895                 :             :               && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
   12896                 :             :             name = machopic_indirection_name (x, /*stub_p=*/true);
   12897                 :             : #endif
   12898                 :             :           assemble_name (file, name);
   12899                 :             :         }
   12900                 :      836441 :       if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
   12901                 :      836441 :           && code == 'P' && ix86_call_use_plt_p (x))
   12902                 :      385825 :         fputs ("@PLT", file);
   12903                 :             :       break;
   12904                 :             : 
   12905                 :        2588 :     case LABEL_REF:
   12906                 :        2588 :       x = XEXP (x, 0);
   12907                 :             :       /* FALLTHRU */
   12908                 :        2588 :     case CODE_LABEL:
   12909                 :        2588 :       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   12910                 :        2588 :       assemble_name (asm_out_file, buf);
   12911                 :        2588 :       break;
   12912                 :             : 
   12913                 :     2305184 :     CASE_CONST_SCALAR_INT:
   12914                 :     2305184 :       output_addr_const (file, x);
   12915                 :     2305184 :       break;
   12916                 :             : 
   12917                 :      204641 :     case CONST:
   12918                 :             :       /* This used to output parentheses around the expression,
   12919                 :             :          but that does not work on the 386 (either ATT or BSD assembler).  */
   12920                 :      204641 :       output_pic_addr_const (file, XEXP (x, 0), code);
   12921                 :      204641 :       break;
   12922                 :             : 
   12923                 :           0 :     case CONST_DOUBLE:
   12924                 :             :       /* We can't handle floating point constants;
   12925                 :             :          TARGET_PRINT_OPERAND must handle them.  */
   12926                 :           0 :       output_operand_lossage ("floating constant misused");
   12927                 :           0 :       break;
   12928                 :             : 
   12929                 :       17566 :     case PLUS:
   12930                 :             :       /* Some assemblers need integer constants to appear first.  */
   12931                 :       17566 :       if (CONST_INT_P (XEXP (x, 0)))
   12932                 :             :         {
   12933                 :           0 :           output_pic_addr_const (file, XEXP (x, 0), code);
   12934                 :           0 :           putc ('+', file);
   12935                 :           0 :           output_pic_addr_const (file, XEXP (x, 1), code);
   12936                 :             :         }
   12937                 :             :       else
   12938                 :             :         {
   12939                 :       17566 :           gcc_assert (CONST_INT_P (XEXP (x, 1)));
   12940                 :       17566 :           output_pic_addr_const (file, XEXP (x, 1), code);
   12941                 :       17566 :           putc ('+', file);
   12942                 :       17566 :           output_pic_addr_const (file, XEXP (x, 0), code);
   12943                 :             :         }
   12944                 :             :       break;
   12945                 :             : 
   12946                 :           0 :     case MINUS:
   12947                 :           0 :       if (!TARGET_MACHO)
   12948                 :           0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
   12949                 :           0 :       output_pic_addr_const (file, XEXP (x, 0), code);
   12950                 :           0 :       putc ('-', file);
   12951                 :           0 :       output_pic_addr_const (file, XEXP (x, 1), code);
   12952                 :           0 :       if (!TARGET_MACHO)
   12953                 :           0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
   12954                 :           0 :       break;
   12955                 :             : 
   12956                 :      196067 :     case UNSPEC:
   12957                 :      196067 :       gcc_assert (XVECLEN (x, 0) == 1);
   12958                 :      196067 :       output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
   12959                 :      196067 :       switch (XINT (x, 1))
   12960                 :             :         {
   12961                 :       42461 :         case UNSPEC_GOT:
   12962                 :       42461 :           fputs ("@GOT", file);
   12963                 :       42461 :           break;
   12964                 :       78356 :         case UNSPEC_GOTOFF:
   12965                 :       78356 :           fputs ("@GOTOFF", file);
   12966                 :       78356 :           break;
   12967                 :          34 :         case UNSPEC_PLTOFF:
   12968                 :          34 :           fputs ("@PLTOFF", file);
   12969                 :          34 :           break;
   12970                 :           0 :         case UNSPEC_PCREL:
   12971                 :           0 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12972                 :             :                  "(%rip)" : "[rip]", file);
   12973                 :           0 :           break;
   12974                 :       71253 :         case UNSPEC_GOTPCREL:
   12975                 :       71253 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12976                 :             :                  "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
   12977                 :       71253 :           break;
   12978                 :           0 :         case UNSPEC_GOTTPOFF:
   12979                 :             :           /* FIXME: This might be @TPOFF in Sun ld too.  */
   12980                 :           0 :           fputs ("@gottpoff", file);
   12981                 :           0 :           break;
   12982                 :           0 :         case UNSPEC_TPOFF:
   12983                 :           0 :           fputs ("@tpoff", file);
   12984                 :           0 :           break;
   12985                 :        1353 :         case UNSPEC_NTPOFF:
   12986                 :        1353 :           if (TARGET_64BIT)
   12987                 :        1353 :             fputs ("@tpoff", file);
   12988                 :             :           else
   12989                 :           0 :             fputs ("@ntpoff", file);
   12990                 :             :           break;
   12991                 :         304 :         case UNSPEC_DTPOFF:
   12992                 :         304 :           fputs ("@dtpoff", file);
   12993                 :         304 :           break;
   12994                 :        2306 :         case UNSPEC_GOTNTPOFF:
   12995                 :        2306 :           if (TARGET_64BIT)
   12996                 :        2055 :             fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   12997                 :             :                    "@gottpoff(%rip)": "@gottpoff[rip]", file);
   12998                 :             :           else
   12999                 :         251 :             fputs ("@gotntpoff", file);
   13000                 :             :           break;
   13001                 :           0 :         case UNSPEC_INDNTPOFF:
   13002                 :           0 :           fputs ("@indntpoff", file);
   13003                 :           0 :           break;
   13004                 :             : #if TARGET_MACHO
   13005                 :             :         case UNSPEC_MACHOPIC_OFFSET:
   13006                 :             :           putc ('-', file);
   13007                 :             :           machopic_output_function_base_name (file);
   13008                 :             :           break;
   13009                 :             : #endif
   13010                 :           0 :         default:
   13011                 :           0 :           output_operand_lossage ("invalid UNSPEC as operand");
   13012                 :           0 :           break;
   13013                 :             :         }
   13014                 :             :        break;
   13015                 :             : 
   13016                 :           0 :     default:
   13017                 :           0 :       output_operand_lossage ("invalid expression as operand");
   13018                 :             :     }
   13019                 :     3340280 : }
   13020                 :             : 
   13021                 :             : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
   13022                 :             :    We need to emit DTP-relative relocations.  */
   13023                 :             : 
   13024                 :             : static void ATTRIBUTE_UNUSED
   13025                 :         708 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
   13026                 :             : {
   13027                 :         708 :   fputs (ASM_LONG, file);
   13028                 :         708 :   output_addr_const (file, x);
   13029                 :         708 :   fputs ("@dtpoff", file);
   13030                 :         708 :   switch (size)
   13031                 :             :     {
   13032                 :             :     case 4:
   13033                 :             :       break;
   13034                 :         536 :     case 8:
   13035                 :         536 :       fputs (", 0", file);
   13036                 :         536 :       break;
   13037                 :           0 :     default:
   13038                 :           0 :       gcc_unreachable ();
   13039                 :             :    }
   13040                 :         708 : }
   13041                 :             : 
   13042                 :             : /* Return true if X is a representation of the PIC register.  This copes
   13043                 :             :    with calls from ix86_find_base_term, where the register might have
   13044                 :             :    been replaced by a cselib value.  */
   13045                 :             : 
   13046                 :             : static bool
   13047                 :    25477545 : ix86_pic_register_p (rtx x)
   13048                 :             : {
   13049                 :    25477545 :   if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
   13050                 :      799703 :     return (pic_offset_table_rtx
   13051                 :      799703 :             && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
   13052                 :    24677842 :   else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
   13053                 :             :     return true;
   13054                 :    24677456 :   else if (!REG_P (x))
   13055                 :             :     return false;
   13056                 :    24110055 :   else if (pic_offset_table_rtx)
   13057                 :             :     {
   13058                 :    24102542 :       if (REGNO (x) == REGNO (pic_offset_table_rtx))
   13059                 :             :         return true;
   13060                 :      287709 :       if (HARD_REGISTER_P (x)
   13061                 :      266397 :           && !HARD_REGISTER_P (pic_offset_table_rtx)
   13062                 :      554106 :           && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
   13063                 :             :         return true;
   13064                 :             :       return false;
   13065                 :             :     }
   13066                 :             :   else
   13067                 :        7513 :     return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
   13068                 :             : }
   13069                 :             : 
   13070                 :             : /* Helper function for ix86_delegitimize_address.
   13071                 :             :    Attempt to delegitimize TLS local-exec accesses.  */
   13072                 :             : 
   13073                 :             : static rtx
   13074                 :  3511091911 : ix86_delegitimize_tls_address (rtx orig_x)
   13075                 :             : {
   13076                 :  3511091911 :   rtx x = orig_x, unspec;
   13077                 :  3511091911 :   struct ix86_address addr;
   13078                 :             : 
   13079                 :  3511091911 :   if (!TARGET_TLS_DIRECT_SEG_REFS)
   13080                 :             :     return orig_x;
   13081                 :  3511091911 :   if (MEM_P (x))
   13082                 :    40091367 :     x = XEXP (x, 0);
   13083                 :  3511091911 :   if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
   13084                 :             :     return orig_x;
   13085                 :  1681043284 :   if (ix86_decompose_address (x, &addr) == 0
   13086                 :  1965486642 :       || addr.seg != DEFAULT_TLS_SEG_REG
   13087                 :      227302 :       || addr.disp == NULL_RTX
   13088                 :  1681224519 :       || GET_CODE (addr.disp) != CONST)
   13089                 :             :     return orig_x;
   13090                 :       89026 :   unspec = XEXP (addr.disp, 0);
   13091                 :       89026 :   if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
   13092                 :       58880 :     unspec = XEXP (unspec, 0);
   13093                 :       89026 :   if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
   13094                 :             :     return orig_x;
   13095                 :       89026 :   x = XVECEXP (unspec, 0, 0);
   13096                 :       89026 :   gcc_assert (GET_CODE (x) == SYMBOL_REF);
   13097                 :       89026 :   if (unspec != XEXP (addr.disp, 0))
   13098                 :       58880 :     x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
   13099                 :       89026 :   if (addr.index)
   13100                 :             :     {
   13101                 :         182 :       rtx idx = addr.index;
   13102                 :         182 :       if (addr.scale != 1)
   13103                 :         182 :         idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
   13104                 :         182 :       x = gen_rtx_PLUS (Pmode, idx, x);
   13105                 :             :     }
   13106                 :       89026 :   if (addr.base)
   13107                 :           2 :     x = gen_rtx_PLUS (Pmode, addr.base, x);
   13108                 :       89026 :   if (MEM_P (orig_x))
   13109                 :         132 :     x = replace_equiv_address_nv (orig_x, x);
   13110                 :             :   return x;
   13111                 :             : }
   13112                 :             : 
   13113                 :             : /* In the name of slightly smaller debug output, and to cater to
   13114                 :             :    general assembler lossage, recognize PIC+GOTOFF and turn it back
   13115                 :             :    into a direct symbol reference.
   13116                 :             : 
   13117                 :             :    On Darwin, this is necessary to avoid a crash, because Darwin
   13118                 :             :    has a different PIC label for each routine but the DWARF debugging
   13119                 :             :    information is not associated with any particular routine, so it's
   13120                 :             :    necessary to remove references to the PIC label from RTL stored by
   13121                 :             :    the DWARF output code.
   13122                 :             : 
   13123                 :             :    This helper is used in the normal ix86_delegitimize_address
   13124                 :             :    entrypoint (e.g. used in the target delegitimization hook) and
   13125                 :             :    in ix86_find_base_term.  As compile time memory optimization, we
   13126                 :             :    avoid allocating rtxes that will not change anything on the outcome
   13127                 :             :    of the callers (find_base_value and find_base_term).  */
   13128                 :             : 
   13129                 :             : static inline rtx
   13130                 :  3534570980 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
   13131                 :             : {
   13132                 :  3534570980 :   rtx orig_x = delegitimize_mem_from_attrs (x);
   13133                 :             :   /* addend is NULL or some rtx if x is something+GOTOFF where
   13134                 :             :      something doesn't include the PIC register.  */
   13135                 :  3534570980 :   rtx addend = NULL_RTX;
   13136                 :             :   /* reg_addend is NULL or a multiple of some register.  */
   13137                 :  3534570980 :   rtx reg_addend = NULL_RTX;
   13138                 :             :   /* const_addend is NULL or a const_int.  */
   13139                 :  3534570980 :   rtx const_addend = NULL_RTX;
   13140                 :             :   /* This is the result, or NULL.  */
   13141                 :  3534570980 :   rtx result = NULL_RTX;
   13142                 :             : 
   13143                 :  3534570980 :   x = orig_x;
   13144                 :             : 
   13145                 :  3534570980 :   if (MEM_P (x))
   13146                 :    57996580 :     x = XEXP (x, 0);
   13147                 :             : 
   13148                 :  3534570980 :   if (TARGET_64BIT)
   13149                 :             :     {
   13150                 :   194673177 :       if (GET_CODE (x) == CONST
   13151                 :     6361162 :           && GET_CODE (XEXP (x, 0)) == PLUS
   13152                 :     4753258 :           && GET_MODE (XEXP (x, 0)) == Pmode
   13153                 :     4753258 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13154                 :     4753258 :           && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
   13155                 :   194673870 :           && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
   13156                 :             :         {
   13157                 :             :           /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
   13158                 :             :              base.  A CONST can't be arg_pointer_rtx based.  */
   13159                 :           0 :           if (base_term_p && MEM_P (orig_x))
   13160                 :             :             return orig_x;
   13161                 :           0 :           rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
   13162                 :           0 :           x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
   13163                 :           0 :           if (MEM_P (orig_x))
   13164                 :           0 :             x = replace_equiv_address_nv (orig_x, x);
   13165                 :           0 :           return x;
   13166                 :             :         }
   13167                 :             : 
   13168                 :   194673177 :       if (GET_CODE (x) == CONST
   13169                 :     6361162 :           && GET_CODE (XEXP (x, 0)) == UNSPEC
   13170                 :     1607904 :           && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
   13171                 :      535531 :               || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
   13172                 :     1072373 :           && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
   13173                 :             :         {
   13174                 :      235844 :           x = XVECEXP (XEXP (x, 0), 0, 0);
   13175                 :      235844 :           if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
   13176                 :             :             {
   13177                 :           9 :               x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
   13178                 :           9 :               if (x == NULL_RTX)
   13179                 :             :                 return orig_x;
   13180                 :             :             }
   13181                 :      235844 :           return x;
   13182                 :             :         }
   13183                 :             : 
   13184                 :   194437333 :       if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
   13185                 :   194436296 :         return ix86_delegitimize_tls_address (orig_x);
   13186                 :             : 
   13187                 :             :       /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
   13188                 :             :          and -mcmodel=medium -fpic.  */
   13189                 :             :     }
   13190                 :             : 
   13191                 :  3339898840 :   if (GET_CODE (x) != PLUS
   13192                 :  1585935416 :       || GET_CODE (XEXP (x, 1)) != CONST)
   13193                 :  3314975753 :     return ix86_delegitimize_tls_address (orig_x);
   13194                 :             : 
   13195                 :    24923087 :   if (ix86_pic_register_p (XEXP (x, 0)))
   13196                 :             :     /* %ebx + GOT/GOTOFF */
   13197                 :             :     ;
   13198                 :     1286372 :   else if (GET_CODE (XEXP (x, 0)) == PLUS)
   13199                 :             :     {
   13200                 :             :       /* %ebx + %reg * scale + GOT/GOTOFF */
   13201                 :      486389 :       reg_addend = XEXP (x, 0);
   13202                 :      486389 :       if (ix86_pic_register_p (XEXP (reg_addend, 0)))
   13203                 :      418320 :         reg_addend = XEXP (reg_addend, 1);
   13204                 :       68069 :       else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
   13205                 :       37757 :         reg_addend = XEXP (reg_addend, 0);
   13206                 :             :       else
   13207                 :             :         {
   13208                 :       30312 :           reg_addend = NULL_RTX;
   13209                 :       30312 :           addend = XEXP (x, 0);
   13210                 :             :         }
   13211                 :             :     }
   13212                 :             :   else
   13213                 :             :     addend = XEXP (x, 0);
   13214                 :             : 
   13215                 :    24923087 :   x = XEXP (XEXP (x, 1), 0);
   13216                 :    24923087 :   if (GET_CODE (x) == PLUS
   13217                 :     1429964 :       && CONST_INT_P (XEXP (x, 1)))
   13218                 :             :     {
   13219                 :     1429964 :       const_addend = XEXP (x, 1);
   13220                 :     1429964 :       x = XEXP (x, 0);
   13221                 :             :     }
   13222                 :             : 
   13223                 :    24923087 :   if (GET_CODE (x) == UNSPEC
   13224                 :    24248990 :       && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
   13225                 :     6579621 :           || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
   13226                 :     1005765 :           || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
   13227                 :           0 :               && !MEM_P (orig_x) && !addend)))
   13228                 :    23243225 :     result = XVECEXP (x, 0, 0);
   13229                 :             : 
   13230                 :    23243225 :   if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
   13231                 :             :       && !MEM_P (orig_x))
   13232                 :             :     result = XVECEXP (x, 0, 0);
   13233                 :             : 
   13234                 :    23243225 :   if (! result)
   13235                 :     1679862 :     return ix86_delegitimize_tls_address (orig_x);
   13236                 :             : 
   13237                 :             :   /* For (PLUS something CONST_INT) both find_base_{value,term} just
   13238                 :             :      recurse on the first operand.  */
   13239                 :    23243225 :   if (const_addend && !base_term_p)
   13240                 :       87506 :     result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
   13241                 :    23243225 :   if (reg_addend)
   13242                 :      444565 :     result = gen_rtx_PLUS (Pmode, reg_addend, result);
   13243                 :    23243225 :   if (addend)
   13244                 :             :     {
   13245                 :             :       /* If the rest of original X doesn't involve the PIC register, add
   13246                 :             :          addend and subtract pic_offset_table_rtx.  This can happen e.g.
   13247                 :             :          for code like:
   13248                 :             :          leal (%ebx, %ecx, 4), %ecx
   13249                 :             :          ...
   13250                 :             :          movl foo@GOTOFF(%ecx), %edx
   13251                 :             :          in which case we return (%ecx - %ebx) + foo
   13252                 :             :          or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
   13253                 :             :          and reload has completed.  Don't do the latter for debug,
   13254                 :             :          as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly.  */
   13255                 :      131772 :       if (pic_offset_table_rtx
   13256                 :      131772 :           && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
   13257                 :         729 :         result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
   13258                 :             :                                                      pic_offset_table_rtx),
   13259                 :             :                                result);
   13260                 :      131043 :       else if (base_term_p
   13261                 :      126982 :                && pic_offset_table_rtx
   13262                 :             :                && !TARGET_MACHO
   13263                 :             :                && !TARGET_VXWORKS_RTP)
   13264                 :             :         {
   13265                 :      126982 :           rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
   13266                 :      126982 :           tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
   13267                 :      126982 :           result = gen_rtx_PLUS (Pmode, tmp, result);
   13268                 :      126982 :         }
   13269                 :             :       else
   13270                 :             :         return orig_x;
   13271                 :             :     }
   13272                 :    23239164 :   if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
   13273                 :             :     {
   13274                 :           0 :       result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
   13275                 :           0 :       if (result == NULL_RTX)
   13276                 :             :         return orig_x;
   13277                 :             :     }
   13278                 :             :   return result;
   13279                 :             : }
   13280                 :             : 
   13281                 :             : /* The normal instantiation of the above template.  */
   13282                 :             : 
   13283                 :             : static rtx
   13284                 :   257447420 : ix86_delegitimize_address (rtx x)
   13285                 :             : {
   13286                 :   257447420 :   return ix86_delegitimize_address_1 (x, false);
   13287                 :             : }
   13288                 :             : 
   13289                 :             : /* If X is a machine specific address (i.e. a symbol or label being
   13290                 :             :    referenced as a displacement from the GOT implemented using an
   13291                 :             :    UNSPEC), then return the base term.  Otherwise return X.  */
   13292                 :             : 
   13293                 :             : rtx
   13294                 :  6364370519 : ix86_find_base_term (rtx x)
   13295                 :             : {
   13296                 :  6364370519 :   rtx term;
   13297                 :             : 
   13298                 :  6364370519 :   if (TARGET_64BIT)
   13299                 :             :     {
   13300                 :  3087246959 :       if (GET_CODE (x) != CONST)
   13301                 :             :         return x;
   13302                 :    28984186 :       term = XEXP (x, 0);
   13303                 :    28984186 :       if (GET_CODE (term) == PLUS
   13304                 :    28970357 :           && CONST_INT_P (XEXP (term, 1)))
   13305                 :    28970357 :         term = XEXP (term, 0);
   13306                 :    28984186 :       if (GET_CODE (term) != UNSPEC
   13307                 :       37021 :           || (XINT (term, 1) != UNSPEC_GOTPCREL
   13308                 :       37021 :               && XINT (term, 1) != UNSPEC_PCREL))
   13309                 :             :         return x;
   13310                 :             : 
   13311                 :           0 :       return XVECEXP (term, 0, 0);
   13312                 :             :     }
   13313                 :             : 
   13314                 :  3277123560 :   return ix86_delegitimize_address_1 (x, true);
   13315                 :             : }
   13316                 :             : 
   13317                 :             : /* Return true if X shouldn't be emitted into the debug info.
   13318                 :             :    Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
   13319                 :             :    symbol easily into the .debug_info section, so we need not to
   13320                 :             :    delegitimize, but instead assemble as @gotoff.
   13321                 :             :    Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
   13322                 :             :    assembles that as _GLOBAL_OFFSET_TABLE_-. expression.  */
   13323                 :             : 
   13324                 :             : static bool
   13325                 :     1502877 : ix86_const_not_ok_for_debug_p (rtx x)
   13326                 :             : {
   13327                 :     1502877 :   if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
   13328                 :             :     return true;
   13329                 :             : 
   13330                 :     1502857 :   if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
   13331                 :           0 :     return true;
   13332                 :             : 
   13333                 :             :   return false;
   13334                 :             : }
   13335                 :             : 
   13336                 :             : static void
   13337                 :     6240837 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
   13338                 :             :                     bool fp, FILE *file)
   13339                 :             : {
   13340                 :     6240837 :   const char *suffix;
   13341                 :             : 
   13342                 :     6240837 :   if (mode == CCFPmode)
   13343                 :             :     {
   13344                 :      541543 :       code = ix86_fp_compare_code_to_integer (code);
   13345                 :      541543 :       mode = CCmode;
   13346                 :             :     }
   13347                 :     6240837 :   if (reverse)
   13348                 :      154246 :     code = reverse_condition (code);
   13349                 :             : 
   13350                 :     6240837 :   switch (code)
   13351                 :             :     {
   13352                 :     2447774 :     case EQ:
   13353                 :     2447774 :       gcc_assert (mode != CCGZmode);
   13354                 :     2447774 :       switch (mode)
   13355                 :             :         {
   13356                 :             :         case E_CCAmode:
   13357                 :             :           suffix = "a";
   13358                 :             :           break;
   13359                 :             :         case E_CCCmode:
   13360                 :       27793 :           suffix = "c";
   13361                 :             :           break;
   13362                 :             :         case E_CCOmode:
   13363                 :     6240837 :           suffix = "o";
   13364                 :             :           break;
   13365                 :             :         case E_CCPmode:
   13366                 :      229839 :           suffix = "p";
   13367                 :             :           break;
   13368                 :             :         case E_CCSmode:
   13369                 :      109213 :           suffix = "s";
   13370                 :             :           break;
   13371                 :     2424931 :         default:
   13372                 :     2424931 :           suffix = "e";
   13373                 :     2424931 :           break;
   13374                 :             :         }
   13375                 :             :       break;
   13376                 :     2051994 :     case NE:
   13377                 :     2051994 :       gcc_assert (mode != CCGZmode);
   13378                 :     2051994 :       switch (mode)
   13379                 :             :         {
   13380                 :             :         case E_CCAmode:
   13381                 :             :           suffix = "na";
   13382                 :             :           break;
   13383                 :             :         case E_CCCmode:
   13384                 :       10993 :           suffix = "nc";
   13385                 :             :           break;
   13386                 :       11661 :         case E_CCOmode:
   13387                 :       11661 :           suffix = "no";
   13388                 :       11661 :           break;
   13389                 :             :         case E_CCPmode:
   13390                 :        4210 :           suffix = "np";
   13391                 :             :           break;
   13392                 :             :         case E_CCSmode:
   13393                 :       51576 :           suffix = "ns";
   13394                 :             :           break;
   13395                 :     2036389 :         default:
   13396                 :     2036389 :           suffix = "ne";
   13397                 :     2036389 :           break;
   13398                 :             :         }
   13399                 :             :       break;
   13400                 :      168060 :     case GT:
   13401                 :      168060 :       gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
   13402                 :             :       suffix = "g";
   13403                 :             :       break;
   13404                 :      164480 :     case GTU:
   13405                 :             :       /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
   13406                 :             :          Those same assemblers have the same but opposite lossage on cmov.  */
   13407                 :      164480 :       if (mode == CCmode)
   13408                 :      164480 :         suffix = fp ? "nbe" : "a";
   13409                 :             :       else
   13410                 :           0 :         gcc_unreachable ();
   13411                 :             :       break;
   13412                 :      204531 :     case LT:
   13413                 :      204531 :       switch (mode)
   13414                 :             :         {
   13415                 :             :         case E_CCNOmode:
   13416                 :             :         case E_CCGOCmode:
   13417                 :             :           suffix = "s";
   13418                 :             :           break;
   13419                 :             : 
   13420                 :             :         case E_CCmode:
   13421                 :             :         case E_CCGCmode:
   13422                 :             :         case E_CCGZmode:
   13423                 :     6240837 :           suffix = "l";
   13424                 :             :           break;
   13425                 :             : 
   13426                 :           0 :         default:
   13427                 :           0 :           gcc_unreachable ();
   13428                 :             :         }
   13429                 :             :       break;
   13430                 :      381041 :     case LTU:
   13431                 :      381041 :       if (mode == CCmode || mode == CCGZmode)
   13432                 :             :         suffix = "b";
   13433                 :       23458 :       else if (mode == CCCmode)
   13434                 :       23458 :         suffix = fp ? "b" : "c";
   13435                 :             :       else
   13436                 :           0 :         gcc_unreachable ();
   13437                 :             :       break;
   13438                 :      116742 :     case GE:
   13439                 :      116742 :       switch (mode)
   13440                 :             :         {
   13441                 :             :         case E_CCNOmode:
   13442                 :             :         case E_CCGOCmode:
   13443                 :             :           suffix = "ns";
   13444                 :             :           break;
   13445                 :             : 
   13446                 :             :         case E_CCmode:
   13447                 :             :         case E_CCGCmode:
   13448                 :             :         case E_CCGZmode:
   13449                 :     6240837 :           suffix = "ge";
   13450                 :             :           break;
   13451                 :             : 
   13452                 :           0 :         default:
   13453                 :           0 :           gcc_unreachable ();
   13454                 :             :         }
   13455                 :             :       break;
   13456                 :      154943 :     case GEU:
   13457                 :      154943 :       if (mode == CCmode || mode == CCGZmode)
   13458                 :             :         suffix = "nb";
   13459                 :        7069 :       else if (mode == CCCmode)
   13460                 :        7069 :         suffix = fp ? "nb" : "nc";
   13461                 :             :       else
   13462                 :           0 :         gcc_unreachable ();
   13463                 :             :       break;
   13464                 :      216789 :     case LE:
   13465                 :      216789 :       gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
   13466                 :             :       suffix = "le";
   13467                 :             :       break;
   13468                 :      100434 :     case LEU:
   13469                 :      100434 :       if (mode == CCmode)
   13470                 :             :         suffix = "be";
   13471                 :             :       else
   13472                 :           0 :         gcc_unreachable ();
   13473                 :             :       break;
   13474                 :      229832 :     case UNORDERED:
   13475                 :      229832 :       suffix = fp ? "u" : "p";
   13476                 :             :       break;
   13477                 :        4217 :     case ORDERED:
   13478                 :        4217 :       suffix = fp ? "nu" : "np";
   13479                 :             :       break;
   13480                 :           0 :     default:
   13481                 :           0 :       gcc_unreachable ();
   13482                 :             :     }
   13483                 :     6240837 :   fputs (suffix, file);
   13484                 :     6240837 : }
   13485                 :             : 
   13486                 :             : /* Print the name of register X to FILE based on its machine mode and number.
   13487                 :             :    If CODE is 'w', pretend the mode is HImode.
   13488                 :             :    If CODE is 'b', pretend the mode is QImode.
   13489                 :             :    If CODE is 'k', pretend the mode is SImode.
   13490                 :             :    If CODE is 'q', pretend the mode is DImode.
   13491                 :             :    If CODE is 'x', pretend the mode is V4SFmode.
   13492                 :             :    If CODE is 't', pretend the mode is V8SFmode.
   13493                 :             :    If CODE is 'g', pretend the mode is V16SFmode.
   13494                 :             :    If CODE is 'h', pretend the reg is the 'high' byte register.
   13495                 :             :    If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   13496                 :             :    If CODE is 'd', duplicate the operand for AVX instruction.
   13497                 :             :    If CODE is 'V', print naked full integer register name without %.
   13498                 :             :  */
   13499                 :             : 
   13500                 :             : void
   13501                 :   113265859 : print_reg (rtx x, int code, FILE *file)
   13502                 :             : {
   13503                 :   113265859 :   const char *reg;
   13504                 :   113265859 :   int msize;
   13505                 :   113265859 :   unsigned int regno;
   13506                 :   113265859 :   bool duplicated;
   13507                 :             : 
   13508                 :   113265859 :   if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
   13509                 :   113264054 :     putc ('%', file);
   13510                 :             : 
   13511                 :   113265859 :   if (x == pc_rtx)
   13512                 :             :     {
   13513                 :     5467394 :       gcc_assert (TARGET_64BIT);
   13514                 :     5467394 :       fputs ("rip", file);
   13515                 :     5467394 :       return;
   13516                 :             :     }
   13517                 :             : 
   13518                 :   107798465 :   if (code == 'y' && STACK_TOP_P (x))
   13519                 :             :     {
   13520                 :      298066 :       fputs ("st(0)", file);
   13521                 :      298066 :       return;
   13522                 :             :     }
   13523                 :             : 
   13524                 :   107500399 :   if (code == 'w')
   13525                 :             :     msize = 2;
   13526                 :             :   else if (code == 'b')
   13527                 :             :     msize = 1;
   13528                 :             :   else if (code == 'k')
   13529                 :             :     msize = 4;
   13530                 :             :   else if (code == 'q')
   13531                 :             :     msize = 8;
   13532                 :             :   else if (code == 'h')
   13533                 :             :     msize = 0;
   13534                 :             :   else if (code == 'x')
   13535                 :             :     msize = 16;
   13536                 :             :   else if (code == 't')
   13537                 :             :     msize = 32;
   13538                 :             :   else if (code == 'g')
   13539                 :             :     msize = 64;
   13540                 :             :   else
   13541                 :   184456832 :     msize = GET_MODE_SIZE (GET_MODE (x));
   13542                 :             : 
   13543                 :   107500399 :   regno = REGNO (x);
   13544                 :             : 
   13545                 :   107500399 :   if (regno == ARG_POINTER_REGNUM
   13546                 :   107500399 :       || regno == FRAME_POINTER_REGNUM
   13547                 :   107500399 :       || regno == FPSR_REG)
   13548                 :             :     {
   13549                 :           0 :       output_operand_lossage
   13550                 :           0 :         ("invalid use of register '%s'", reg_names[regno]);
   13551                 :           0 :       return;
   13552                 :             :     }
   13553                 :   107500399 :   else if (regno == FLAGS_REG)
   13554                 :             :     {
   13555                 :           1 :       output_operand_lossage ("invalid use of asm flag output");
   13556                 :           1 :       return;
   13557                 :             :     }
   13558                 :             : 
   13559                 :   107500398 :   if (code == 'V')
   13560                 :             :     {
   13561                 :           1 :       if (GENERAL_REGNO_P (regno))
   13562                 :           2 :         msize = GET_MODE_SIZE (word_mode);
   13563                 :             :       else
   13564                 :           0 :         error ("%<V%> modifier on non-integer register");
   13565                 :             :     }
   13566                 :             : 
   13567                 :   107500398 :   duplicated = code == 'd' && TARGET_AVX;
   13568                 :             : 
   13569                 :   107500398 :   switch (msize)
   13570                 :             :     {
   13571                 :    69917162 :     case 16:
   13572                 :    69917162 :     case 12:
   13573                 :    69917162 :     case 8:
   13574                 :   130566595 :       if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
   13575                 :           5 :         warning (0, "unsupported size for integer register");
   13576                 :             :       /* FALLTHRU */
   13577                 :   104324855 :     case 4:
   13578                 :   104324855 :       if (LEGACY_INT_REGNO_P (regno))
   13579                 :   114038328 :         putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
   13580                 :             :       /* FALLTHRU */
   13581                 :   105122397 :     case 2:
   13582                 :    20401474 :     normal:
   13583                 :   105122397 :       reg = hi_reg_name[regno];
   13584                 :   105122397 :       break;
   13585                 :     2110270 :     case 1:
   13586                 :     2110270 :       if (regno >= ARRAY_SIZE (qi_reg_name))
   13587                 :      226046 :         goto normal;
   13588                 :     1884224 :       if (!ANY_QI_REGNO_P (regno))
   13589                 :           0 :         error ("unsupported size for integer register");
   13590                 :     1884224 :       reg = qi_reg_name[regno];
   13591                 :     1884224 :       break;
   13592                 :       26472 :     case 0:
   13593                 :       26472 :       if (regno >= ARRAY_SIZE (qi_high_reg_name))
   13594                 :           0 :         goto normal;
   13595                 :       26472 :       reg = qi_high_reg_name[regno];
   13596                 :       26472 :       break;
   13597                 :      467305 :     case 32:
   13598                 :      467305 :     case 64:
   13599                 :      467305 :       if (SSE_REGNO_P (regno))
   13600                 :             :         {
   13601                 :      467305 :           gcc_assert (!duplicated);
   13602                 :      641428 :           putc (msize == 32 ? 'y' : 'z', file);
   13603                 :      467305 :           reg = hi_reg_name[regno] + 1;
   13604                 :      467305 :           break;
   13605                 :             :         }
   13606                 :           0 :       goto normal;
   13607                 :           0 :     default:
   13608                 :           0 :       gcc_unreachable ();
   13609                 :             :     }
   13610                 :             : 
   13611                 :   107500398 :   fputs (reg, file);
   13612                 :             : 
   13613                 :             :   /* Irritatingly, AMD extended registers use
   13614                 :             :      different naming convention: "r%d[bwd]"  */
   13615                 :   107500398 :   if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   13616                 :             :     {
   13617                 :     9347703 :       gcc_assert (TARGET_64BIT);
   13618                 :     9347703 :       switch (msize)
   13619                 :             :         {
   13620                 :           0 :           case 0:
   13621                 :           0 :             error ("extended registers have no high halves");
   13622                 :           0 :             break;
   13623                 :      155085 :           case 1:
   13624                 :      155085 :             putc ('b', file);
   13625                 :      155085 :             break;
   13626                 :       26337 :           case 2:
   13627                 :       26337 :             putc ('w', file);
   13628                 :       26337 :             break;
   13629                 :     2325282 :           case 4:
   13630                 :     2325282 :             putc ('d', file);
   13631                 :     2325282 :             break;
   13632                 :             :           case 8:
   13633                 :             :             /* no suffix */
   13634                 :             :             break;
   13635                 :           0 :           default:
   13636                 :           0 :             error ("unsupported operand size for extended register");
   13637                 :           0 :             break;
   13638                 :             :         }
   13639                 :     9347703 :       return;
   13640                 :             :     }
   13641                 :             : 
   13642                 :    98152695 :   if (duplicated)
   13643                 :             :     {
   13644                 :       16398 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   13645                 :       16379 :         fprintf (file, ", %%%s", reg);
   13646                 :             :       else
   13647                 :          19 :         fprintf (file, ", %s", reg);
   13648                 :             :     }
   13649                 :             : }
   13650                 :             : 
   13651                 :             : /* Meaning of CODE:
   13652                 :             :    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
   13653                 :             :    C -- print opcode suffix for set/cmov insn.
   13654                 :             :    c -- like C, but print reversed condition
   13655                 :             :    F,f -- likewise, but for floating-point.
   13656                 :             :    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
   13657                 :             :         otherwise nothing
   13658                 :             :    R -- print embedded rounding and sae.
   13659                 :             :    r -- print only sae.
   13660                 :             :    z -- print the opcode suffix for the size of the current operand.
   13661                 :             :    Z -- likewise, with special suffixes for x87 instructions.
   13662                 :             :    * -- print a star (in certain assembler syntax)
   13663                 :             :    A -- print an absolute memory reference.
   13664                 :             :    E -- print address with DImode register names if TARGET_64BIT.
   13665                 :             :    w -- print the operand as if it's a "word" (HImode) even if it isn't.
   13666                 :             :    s -- print a shift double count, followed by the assemblers argument
   13667                 :             :         delimiter.
   13668                 :             :    b -- print the QImode name of the register for the indicated operand.
   13669                 :             :         %b0 would print %al if operands[0] is reg 0.
   13670                 :             :    w --  likewise, print the HImode name of the register.
   13671                 :             :    k --  likewise, print the SImode name of the register.
   13672                 :             :    q --  likewise, print the DImode name of the register.
   13673                 :             :    x --  likewise, print the V4SFmode name of the register.
   13674                 :             :    t --  likewise, print the V8SFmode name of the register.
   13675                 :             :    g --  likewise, print the V16SFmode name of the register.
   13676                 :             :    h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
   13677                 :             :    y -- print "st(0)" instead of "st" as a register.
   13678                 :             :    d -- print duplicated register operand for AVX instruction.
   13679                 :             :    D -- print condition for SSE cmp instruction.
   13680                 :             :    P -- if PIC, print an @PLT suffix.  For -fno-plt, load function
   13681                 :             :         address from GOT.
   13682                 :             :    p -- print raw symbol name.
   13683                 :             :    X -- don't print any sort of PIC '@' suffix for a symbol.
   13684                 :             :    & -- print some in-use local-dynamic symbol name.
   13685                 :             :    H -- print a memory address offset by 8; used for sse high-parts
   13686                 :             :    Y -- print condition for XOP pcom* instruction.
   13687                 :             :    V -- print naked full integer register name without %.
   13688                 :             :    + -- print a branch hint as 'cs' or 'ds' prefix
   13689                 :             :    ; -- print a semicolon (after prefixes due to bug in older gas).
   13690                 :             :    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
   13691                 :             :    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
   13692                 :             :    M -- print addr32 prefix for TARGET_X32 with VSIB address.
   13693                 :             :    ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
   13694                 :             :    N -- print maskz if it's constant 0 operand.
   13695                 :             :  */
   13696                 :             : 
   13697                 :             : void
   13698                 :   161745189 : ix86_print_operand (FILE *file, rtx x, int code)
   13699                 :             : {
   13700                 :   161939760 :   if (code)
   13701                 :             :     {
   13702                 :    56102081 :       switch (code)
   13703                 :             :         {
   13704                 :      194567 :         case 'A':
   13705                 :      194567 :           switch (ASSEMBLER_DIALECT)
   13706                 :             :             {
   13707                 :      194567 :             case ASM_ATT:
   13708                 :      194567 :               putc ('*', file);
   13709                 :      194567 :               break;
   13710                 :             : 
   13711                 :           0 :             case ASM_INTEL:
   13712                 :             :               /* Intel syntax. For absolute addresses, registers should not
   13713                 :             :                  be surrounded by braces.  */
   13714                 :           0 :               if (!REG_P (x))
   13715                 :             :                 {
   13716                 :           0 :                   putc ('[', file);
   13717                 :           0 :                   ix86_print_operand (file, x, 0);
   13718                 :           0 :                   putc (']', file);
   13719                 :           0 :                   return;
   13720                 :             :                 }
   13721                 :             :               break;
   13722                 :             : 
   13723                 :           0 :             default:
   13724                 :           0 :               gcc_unreachable ();
   13725                 :             :             }
   13726                 :             : 
   13727                 :      194567 :           ix86_print_operand (file, x, 0);
   13728                 :      194567 :           return;
   13729                 :             : 
   13730                 :     2866559 :         case 'E':
   13731                 :             :           /* Wrap address in an UNSPEC to declare special handling.  */
   13732                 :     2866559 :           if (TARGET_64BIT)
   13733                 :     2403550 :             x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
   13734                 :             : 
   13735                 :     2866559 :           output_address (VOIDmode, x);
   13736                 :     2866559 :           return;
   13737                 :             : 
   13738                 :           0 :         case 'L':
   13739                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13740                 :           0 :             putc ('l', file);
   13741                 :           0 :           return;
   13742                 :             : 
   13743                 :           0 :         case 'W':
   13744                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13745                 :           0 :             putc ('w', file);
   13746                 :           0 :           return;
   13747                 :             : 
   13748                 :           0 :         case 'B':
   13749                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13750                 :           0 :             putc ('b', file);
   13751                 :           0 :           return;
   13752                 :             : 
   13753                 :           0 :         case 'Q':
   13754                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13755                 :           0 :             putc ('l', file);
   13756                 :           0 :           return;
   13757                 :             : 
   13758                 :           0 :         case 'S':
   13759                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13760                 :           0 :             putc ('s', file);
   13761                 :           0 :           return;
   13762                 :             : 
   13763                 :           0 :         case 'T':
   13764                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   13765                 :           0 :             putc ('t', file);
   13766                 :           0 :           return;
   13767                 :             : 
   13768                 :             :         case 'O':
   13769                 :             : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   13770                 :             :           if (ASSEMBLER_DIALECT != ASM_ATT)
   13771                 :             :             return;
   13772                 :             : 
   13773                 :             :           switch (GET_MODE_SIZE (GET_MODE (x)))
   13774                 :             :             {
   13775                 :             :             case 2:
   13776                 :             :               putc ('w', file);
   13777                 :             :               break;
   13778                 :             :   
   13779                 :             :             case 4:
   13780                 :             :               putc ('l', file);
   13781                 :             :               break;
   13782                 :             : 
   13783                 :             :             case 8:
   13784                 :             :               putc ('q', file);
   13785                 :             :               break;
   13786                 :             : 
   13787                 :             :             default:
   13788                 :             :               output_operand_lossage ("invalid operand size for operand "
   13789                 :             :                                       "code 'O'");
   13790                 :             :               return;
   13791                 :             :             }
   13792                 :             : 
   13793                 :             :           putc ('.', file);
   13794                 :             : #endif
   13795                 :             :           return;
   13796                 :             : 
   13797                 :       36203 :         case 'z':
   13798                 :       36203 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   13799                 :             :             {
   13800                 :             :               /* Opcodes don't get size suffixes if using Intel opcodes.  */
   13801                 :       36201 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   13802                 :             :                 return;
   13803                 :             : 
   13804                 :       72402 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13805                 :             :                 {
   13806                 :           6 :                 case 1:
   13807                 :           6 :                   putc ('b', file);
   13808                 :           6 :                   return;
   13809                 :             : 
   13810                 :           6 :                 case 2:
   13811                 :           6 :                   putc ('w', file);
   13812                 :           6 :                   return;
   13813                 :             : 
   13814                 :       35709 :                 case 4:
   13815                 :       35709 :                   putc ('l', file);
   13816                 :       35709 :                   return;
   13817                 :             : 
   13818                 :         480 :                 case 8:
   13819                 :         480 :                   putc ('q', file);
   13820                 :         480 :                   return;
   13821                 :             : 
   13822                 :           0 :                 default:
   13823                 :           0 :                   output_operand_lossage ("invalid operand size for operand "
   13824                 :             :                                           "code 'z'");
   13825                 :           0 :                   return;
   13826                 :             :                 }
   13827                 :             :             }
   13828                 :             : 
   13829                 :           2 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   13830                 :             :             {
   13831                 :           1 :               if (this_is_asm_operands)
   13832                 :           1 :                 warning_for_asm (this_is_asm_operands,
   13833                 :             :                                  "non-integer operand used with operand code %<z%>");
   13834                 :             :               else
   13835                 :           0 :                 warning (0, "non-integer operand used with operand code %<z%>");
   13836                 :             :             }
   13837                 :             :           /* FALLTHRU */
   13838                 :             : 
   13839                 :      385642 :         case 'Z':
   13840                 :             :           /* 387 opcodes don't get size suffixes if using Intel opcodes.  */
   13841                 :      385642 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   13842                 :             :             return;
   13843                 :             : 
   13844                 :      385642 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   13845                 :             :             {
   13846                 :       29972 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13847                 :             :                 {
   13848                 :        3576 :                 case 2:
   13849                 :             : #ifdef HAVE_AS_IX86_FILDS
   13850                 :        3576 :                   putc ('s', file);
   13851                 :             : #endif
   13852                 :        3576 :                   return;
   13853                 :             : 
   13854                 :        3939 :                 case 4:
   13855                 :        3939 :                   putc ('l', file);
   13856                 :        3939 :                   return;
   13857                 :             : 
   13858                 :        7471 :                 case 8:
   13859                 :             : #ifdef HAVE_AS_IX86_FILDQ
   13860                 :        7471 :                   putc ('q', file);
   13861                 :             : #else
   13862                 :             :                   fputs ("ll", file);
   13863                 :             : #endif
   13864                 :        7471 :                   return;
   13865                 :             : 
   13866                 :             :                 default:
   13867                 :             :                   break;
   13868                 :             :                 }
   13869                 :             :             }
   13870                 :      370656 :           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   13871                 :             :             {
   13872                 :             :               /* 387 opcodes don't get size suffixes
   13873                 :             :                  if the operands are registers.  */
   13874                 :      370654 :               if (STACK_REG_P (x))
   13875                 :             :                 return;
   13876                 :             : 
   13877                 :      694046 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   13878                 :             :                 {
   13879                 :       23163 :                 case 4:
   13880                 :       23163 :                   putc ('s', file);
   13881                 :       23163 :                   return;
   13882                 :             : 
   13883                 :       32679 :                 case 8:
   13884                 :       32679 :                   putc ('l', file);
   13885                 :       32679 :                   return;
   13886                 :             : 
   13887                 :      291179 :                 case 12:
   13888                 :      291179 :                 case 16:
   13889                 :      291179 :                   putc ('t', file);
   13890                 :      291179 :                   return;
   13891                 :             : 
   13892                 :             :                 default:
   13893                 :             :                   break;
   13894                 :             :                 }
   13895                 :             :             }
   13896                 :             :           else
   13897                 :             :             {
   13898                 :           2 :               output_operand_lossage ("invalid operand type used with "
   13899                 :             :                                       "operand code '%c'", code);
   13900                 :           2 :               return;
   13901                 :             :             }
   13902                 :             : 
   13903                 :           2 :           output_operand_lossage ("invalid operand size for operand code '%c'",
   13904                 :             :                                   code);
   13905                 :           2 :           return;
   13906                 :             : 
   13907                 :             :         case 'd':
   13908                 :             :         case 'b':
   13909                 :             :         case 'w':
   13910                 :             :         case 'k':
   13911                 :             :         case 'q':
   13912                 :             :         case 'h':
   13913                 :             :         case 't':
   13914                 :             :         case 'g':
   13915                 :             :         case 'y':
   13916                 :             :         case 'x':
   13917                 :             :         case 'X':
   13918                 :             :         case 'P':
   13919                 :             :         case 'p':
   13920                 :             :         case 'V':
   13921                 :             :           break;
   13922                 :             : 
   13923                 :           0 :         case 's':
   13924                 :           0 :           if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
   13925                 :             :             {
   13926                 :           0 :               ix86_print_operand (file, x, 0);
   13927                 :           0 :               fputs (", ", file);
   13928                 :             :             }
   13929                 :           0 :           return;
   13930                 :             : 
   13931                 :         531 :         case 'Y':
   13932                 :         531 :           switch (GET_CODE (x))
   13933                 :             :             {
   13934                 :         182 :             case NE:
   13935                 :         182 :               fputs ("neq", file);
   13936                 :         182 :               break;
   13937                 :          32 :             case EQ:
   13938                 :          32 :               fputs ("eq", file);
   13939                 :          32 :               break;
   13940                 :          64 :             case GE:
   13941                 :          64 :             case GEU:
   13942                 :          64 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
   13943                 :          64 :               break;
   13944                 :          42 :             case GT:
   13945                 :          42 :             case GTU:
   13946                 :          42 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
   13947                 :          42 :               break;
   13948                 :          64 :             case LE:
   13949                 :          64 :             case LEU:
   13950                 :          64 :               fputs ("le", file);
   13951                 :          64 :               break;
   13952                 :         147 :             case LT:
   13953                 :         147 :             case LTU:
   13954                 :         147 :               fputs ("lt", file);
   13955                 :         147 :               break;
   13956                 :           0 :             case UNORDERED:
   13957                 :           0 :               fputs ("unord", file);
   13958                 :           0 :               break;
   13959                 :           0 :             case ORDERED:
   13960                 :           0 :               fputs ("ord", file);
   13961                 :           0 :               break;
   13962                 :           0 :             case UNEQ:
   13963                 :           0 :               fputs ("ueq", file);
   13964                 :           0 :               break;
   13965                 :           0 :             case UNGE:
   13966                 :           0 :               fputs ("nlt", file);
   13967                 :           0 :               break;
   13968                 :           0 :             case UNGT:
   13969                 :           0 :               fputs ("nle", file);
   13970                 :           0 :               break;
   13971                 :           0 :             case UNLE:
   13972                 :           0 :               fputs ("ule", file);
   13973                 :           0 :               break;
   13974                 :           0 :             case UNLT:
   13975                 :           0 :               fputs ("ult", file);
   13976                 :           0 :               break;
   13977                 :           0 :             case LTGT:
   13978                 :           0 :               fputs ("une", file);
   13979                 :           0 :               break;
   13980                 :           0 :             default:
   13981                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   13982                 :             :                                       "invalid operand code 'Y'");
   13983                 :           0 :               return;
   13984                 :             :             }
   13985                 :         531 :           return;
   13986                 :             : 
   13987                 :        8546 :         case 'D':
   13988                 :             :           /* Little bit of braindamage here.  The SSE compare instructions
   13989                 :             :              does use completely different names for the comparisons that the
   13990                 :             :              fp conditional moves.  */
   13991                 :        8546 :           switch (GET_CODE (x))
   13992                 :             :             {
   13993                 :          14 :             case UNEQ:
   13994                 :          14 :               if (TARGET_AVX)
   13995                 :             :                 {
   13996                 :          14 :                   fputs ("eq_us", file);
   13997                 :          14 :                   break;
   13998                 :             :                 }
   13999                 :             :              /* FALLTHRU */
   14000                 :        4356 :             case EQ:
   14001                 :        4356 :               fputs ("eq", file);
   14002                 :        4356 :               break;
   14003                 :           0 :             case UNLT:
   14004                 :           0 :               if (TARGET_AVX)
   14005                 :             :                 {
   14006                 :           0 :                   fputs ("nge", file);
   14007                 :           0 :                   break;
   14008                 :             :                 }
   14009                 :             :              /* FALLTHRU */
   14010                 :        1410 :             case LT:
   14011                 :        1410 :               fputs ("lt", file);
   14012                 :        1410 :               break;
   14013                 :           0 :             case UNLE:
   14014                 :           0 :               if (TARGET_AVX)
   14015                 :             :                 {
   14016                 :           0 :                   fputs ("ngt", file);
   14017                 :           0 :                   break;
   14018                 :             :                 }
   14019                 :             :              /* FALLTHRU */
   14020                 :         427 :             case LE:
   14021                 :         427 :               fputs ("le", file);
   14022                 :         427 :               break;
   14023                 :          87 :             case UNORDERED:
   14024                 :          87 :               fputs ("unord", file);
   14025                 :          87 :               break;
   14026                 :           0 :             case LTGT:
   14027                 :           0 :               if (TARGET_AVX)
   14028                 :             :                 {
   14029                 :           0 :                   fputs ("neq_oq", file);
   14030                 :           0 :                   break;
   14031                 :             :                 }
   14032                 :             :              /* FALLTHRU */
   14033                 :        1063 :             case NE:
   14034                 :        1063 :               fputs ("neq", file);
   14035                 :        1063 :               break;
   14036                 :           0 :             case GE:
   14037                 :           0 :               if (TARGET_AVX)
   14038                 :             :                 {
   14039                 :           0 :                   fputs ("ge", file);
   14040                 :           0 :                   break;
   14041                 :             :                 }
   14042                 :             :              /* FALLTHRU */
   14043                 :         313 :             case UNGE:
   14044                 :         313 :               fputs ("nlt", file);
   14045                 :         313 :               break;
   14046                 :           0 :             case GT:
   14047                 :           0 :               if (TARGET_AVX)
   14048                 :             :                 {
   14049                 :           0 :                   fputs ("gt", file);
   14050                 :           0 :                   break;
   14051                 :             :                 }
   14052                 :             :              /* FALLTHRU */
   14053                 :         785 :             case UNGT:
   14054                 :         785 :               fputs ("nle", file);
   14055                 :         785 :               break;
   14056                 :          91 :             case ORDERED:
   14057                 :          91 :               fputs ("ord", file);
   14058                 :          91 :               break;
   14059                 :           0 :             default:
   14060                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   14061                 :             :                                       "invalid operand code 'D'");
   14062                 :           0 :               return;
   14063                 :             :             }
   14064                 :        8546 :           return;
   14065                 :             : 
   14066                 :     6240837 :         case 'F':
   14067                 :     6240837 :         case 'f':
   14068                 :             : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   14069                 :             :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14070                 :             :             putc ('.', file);
   14071                 :             :           gcc_fallthrough ();
   14072                 :             : #endif
   14073                 :             : 
   14074                 :     6240837 :         case 'C':
   14075                 :     6240837 :         case 'c':
   14076                 :     6240837 :           if (!COMPARISON_P (x))
   14077                 :             :             {
   14078                 :           0 :               output_operand_lossage ("operand is not a condition code, "
   14079                 :             :                                       "invalid operand code '%c'", code);
   14080                 :           0 :               return;
   14081                 :             :             }
   14082                 :     6240837 :           put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
   14083                 :     6240837 :                               code == 'c' || code == 'f',
   14084                 :     6240837 :                               code == 'F' || code == 'f',
   14085                 :             :                               file);
   14086                 :     6240837 :           return;
   14087                 :             : 
   14088                 :         395 :         case 'H':
   14089                 :         395 :           if (!offsettable_memref_p (x))
   14090                 :             :             {
   14091                 :           1 :               output_operand_lossage ("operand is not an offsettable memory "
   14092                 :             :                                       "reference, invalid operand code 'H'");
   14093                 :           1 :               return;
   14094                 :             :             }
   14095                 :             :           /* It doesn't actually matter what mode we use here, as we're
   14096                 :             :              only going to use this for printing.  */
   14097                 :         394 :           x = adjust_address_nv (x, DImode, 8);
   14098                 :             :           /* Output 'qword ptr' for intel assembler dialect.  */
   14099                 :         394 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14100                 :           0 :             code = 'q';
   14101                 :             :           break;
   14102                 :             : 
   14103                 :       73789 :         case 'K':
   14104                 :       73789 :           if (!CONST_INT_P (x))
   14105                 :             :             {
   14106                 :           1 :               output_operand_lossage ("operand is not an integer, invalid "
   14107                 :             :                                       "operand code 'K'");
   14108                 :           1 :               return;
   14109                 :             :             }
   14110                 :             : 
   14111                 :       73788 :           if (INTVAL (x) & IX86_HLE_ACQUIRE)
   14112                 :             : #ifdef HAVE_AS_IX86_HLE
   14113                 :          22 :             fputs ("xacquire ", file);
   14114                 :             : #else
   14115                 :             :             fputs ("\n" ASM_BYTE "0xf2\n\t", file);
   14116                 :             : #endif
   14117                 :       73766 :           else if (INTVAL (x) & IX86_HLE_RELEASE)
   14118                 :             : #ifdef HAVE_AS_IX86_HLE
   14119                 :          24 :             fputs ("xrelease ", file);
   14120                 :             : #else
   14121                 :             :             fputs ("\n" ASM_BYTE "0xf3\n\t", file);
   14122                 :             : #endif
   14123                 :             :           /* We do not want to print value of the operand.  */
   14124                 :       73788 :           return;
   14125                 :             : 
   14126                 :       35171 :         case 'N':
   14127                 :       35171 :           if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
   14128                 :       12061 :             fputs ("{z}", file);
   14129                 :       35171 :           return;
   14130                 :             : 
   14131                 :        3731 :         case 'r':
   14132                 :        3731 :           if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
   14133                 :             :             {
   14134                 :           2 :               output_operand_lossage ("operand is not a specific integer, "
   14135                 :             :                                       "invalid operand code 'r'");
   14136                 :           2 :               return;
   14137                 :             :             }
   14138                 :             : 
   14139                 :        3729 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14140                 :           1 :             fputs (", ", file);
   14141                 :             : 
   14142                 :        3729 :           fputs ("{sae}", file);
   14143                 :             : 
   14144                 :        3729 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14145                 :        3728 :             fputs (", ", file);
   14146                 :             : 
   14147                 :        3729 :           return;
   14148                 :             : 
   14149                 :        5823 :         case 'R':
   14150                 :        5823 :           if (!CONST_INT_P (x))
   14151                 :             :             {
   14152                 :           1 :               output_operand_lossage ("operand is not an integer, invalid "
   14153                 :             :                                       "operand code 'R'");
   14154                 :           1 :               return;
   14155                 :             :             }
   14156                 :             : 
   14157                 :        5822 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14158                 :           2 :             fputs (", ", file);
   14159                 :             : 
   14160                 :        5822 :           switch (INTVAL (x))
   14161                 :             :             {
   14162                 :        5015 :             case ROUND_NEAREST_INT | ROUND_SAE:
   14163                 :        5015 :               fputs ("{rn-sae}", file);
   14164                 :        5015 :               break;
   14165                 :         637 :             case ROUND_NEG_INF | ROUND_SAE:
   14166                 :         637 :               fputs ("{rd-sae}", file);
   14167                 :         637 :               break;
   14168                 :          52 :             case ROUND_POS_INF | ROUND_SAE:
   14169                 :          52 :               fputs ("{ru-sae}", file);
   14170                 :          52 :               break;
   14171                 :         117 :             case ROUND_ZERO | ROUND_SAE:
   14172                 :         117 :               fputs ("{rz-sae}", file);
   14173                 :         117 :               break;
   14174                 :           1 :             default:
   14175                 :           1 :               output_operand_lossage ("operand is not a specific integer, "
   14176                 :             :                                       "invalid operand code 'R'");
   14177                 :             :             }
   14178                 :             : 
   14179                 :        5822 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14180                 :        5820 :             fputs (", ", file);
   14181                 :             : 
   14182                 :        5822 :           return;
   14183                 :             : 
   14184                 :           0 :         case '*':
   14185                 :           0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14186                 :           0 :             putc ('*', file);
   14187                 :           0 :           return;
   14188                 :             : 
   14189                 :         269 :         case '&':
   14190                 :         269 :           {
   14191                 :         269 :             const char *name = get_some_local_dynamic_name ();
   14192                 :         269 :             if (name == NULL)
   14193                 :           1 :               output_operand_lossage ("'%%&' used without any "
   14194                 :             :                                       "local dynamic TLS references");
   14195                 :             :             else
   14196                 :         268 :               assemble_name (file, name);
   14197                 :         269 :             return;
   14198                 :             :           }
   14199                 :             : 
   14200                 :     5710876 :         case '+':
   14201                 :     5710876 :           {
   14202                 :     5710876 :             rtx x;
   14203                 :             : 
   14204                 :     5710876 :             if (!optimize
   14205                 :     4477908 :                 || optimize_function_for_size_p (cfun)
   14206                 :    10016845 :                 || !TARGET_BRANCH_PREDICTION_HINTS)
   14207                 :     5710876 :               return;
   14208                 :             : 
   14209                 :           0 :             x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
   14210                 :           0 :             if (x)
   14211                 :             :               {
   14212                 :           0 :                 int pred_val = profile_probability::from_reg_br_prob_note
   14213                 :           0 :                                  (XINT (x, 0)).to_reg_br_prob_base ();
   14214                 :             : 
   14215                 :           0 :                 if (pred_val < REG_BR_PROB_BASE * 45 / 100
   14216                 :           0 :                     || pred_val > REG_BR_PROB_BASE * 55 / 100)
   14217                 :             :                   {
   14218                 :           0 :                     bool taken = pred_val > REG_BR_PROB_BASE / 2;
   14219                 :           0 :                     bool cputaken
   14220                 :           0 :                       = final_forward_branch_p (current_output_insn) == 0;
   14221                 :             : 
   14222                 :             :                     /* Emit hints only in the case default branch prediction
   14223                 :             :                        heuristics would fail.  */
   14224                 :           0 :                     if (taken != cputaken)
   14225                 :             :                       {
   14226                 :             :                         /* We use 3e (DS) prefix for taken branches and
   14227                 :             :                            2e (CS) prefix for not taken branches.  */
   14228                 :           0 :                         if (taken)
   14229                 :           0 :                           fputs ("ds ; ", file);
   14230                 :             :                         else
   14231                 :           0 :                           fputs ("cs ; ", file);
   14232                 :             :                       }
   14233                 :             :                   }
   14234                 :             :               }
   14235                 :           0 :             return;
   14236                 :             :           }
   14237                 :             : 
   14238                 :             :         case ';':
   14239                 :             : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
   14240                 :             :           putc (';', file);
   14241                 :             : #endif
   14242                 :             :           return;
   14243                 :             : 
   14244                 :        3421 :         case '~':
   14245                 :        3421 :           putc (TARGET_AVX2 ? 'i' : 'f', file);
   14246                 :        3421 :           return;
   14247                 :             : 
   14248                 :        1900 :         case 'M':
   14249                 :        1900 :           if (TARGET_X32)
   14250                 :             :             {
   14251                 :             :               /* NB: 32-bit indices in VSIB address are sign-extended
   14252                 :             :                  to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
   14253                 :             :                  sign-extended to 0xfffffffff7fa3010 which is invalid
   14254                 :             :                  address.  Add addr32 prefix if there is no base
   14255                 :             :                  register nor symbol.  */
   14256                 :          44 :               bool ok;
   14257                 :          44 :               struct ix86_address parts;
   14258                 :          44 :               ok = ix86_decompose_address (x, &parts);
   14259                 :          44 :               gcc_assert (ok && parts.index == NULL_RTX);
   14260                 :          44 :               if (parts.base == NULL_RTX
   14261                 :          44 :                   && (parts.disp == NULL_RTX
   14262                 :          36 :                       || !symbolic_operand (parts.disp,
   14263                 :          36 :                                             GET_MODE (parts.disp))))
   14264                 :          36 :                 fputs ("addr32 ", file);
   14265                 :             :             }
   14266                 :        1900 :           return;
   14267                 :             : 
   14268                 :       49718 :         case '^':
   14269                 :       49718 :           if (TARGET_64BIT && Pmode != word_mode)
   14270                 :           0 :             fputs ("addr32 ", file);
   14271                 :       49718 :           return;
   14272                 :             : 
   14273                 :    13439297 :         case '!':
   14274                 :    13439297 :           if (ix86_notrack_prefixed_insn_p (current_output_insn))
   14275                 :        3751 :             fputs ("notrack ", file);
   14276                 :    13439297 :           return;
   14277                 :             : 
   14278                 :           1 :         default:
   14279                 :           1 :           output_operand_lossage ("invalid operand code '%c'", code);
   14280                 :             :         }
   14281                 :             :     }
   14282                 :             : 
   14283                 :   132555591 :   if (REG_P (x))
   14284                 :    79954702 :     print_reg (x, code, file);
   14285                 :             : 
   14286                 :    52600889 :   else if (MEM_P (x))
   14287                 :             :     {
   14288                 :    29886668 :       rtx addr = XEXP (x, 0);
   14289                 :             : 
   14290                 :             :       /* No `byte ptr' prefix for call instructions ... */
   14291                 :    29886668 :       if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
   14292                 :             :         {
   14293                 :         201 :           machine_mode mode = GET_MODE (x);
   14294                 :         201 :           const char *size;
   14295                 :             : 
   14296                 :             :           /* Check for explicit size override codes.  */
   14297                 :         201 :           if (code == 'b')
   14298                 :             :             size = "BYTE";
   14299                 :             :           else if (code == 'w')
   14300                 :             :             size = "WORD";
   14301                 :             :           else if (code == 'k')
   14302                 :             :             size = "DWORD";
   14303                 :             :           else if (code == 'q')
   14304                 :             :             size = "QWORD";
   14305                 :             :           else if (code == 'x')
   14306                 :             :             size = "XMMWORD";
   14307                 :             :           else if (code == 't')
   14308                 :             :             size = "YMMWORD";
   14309                 :             :           else if (code == 'g')
   14310                 :             :             size = "ZMMWORD";
   14311                 :         146 :           else if (mode == BLKmode)
   14312                 :             :             /* ... or BLKmode operands, when not overridden.  */
   14313                 :             :             size = NULL;
   14314                 :             :           else
   14315                 :         292 :             switch (GET_MODE_SIZE (mode))
   14316                 :             :               {
   14317                 :             :               case 1: size = "BYTE"; break;
   14318                 :             :               case 2: size = "WORD"; break;
   14319                 :             :               case 4: size = "DWORD"; break;
   14320                 :             :               case 8: size = "QWORD"; break;
   14321                 :             :               case 12: size = "TBYTE"; break;
   14322                 :           4 :               case 16:
   14323                 :           4 :                 if (mode == XFmode)
   14324                 :             :                   size = "TBYTE";
   14325                 :             :                 else
   14326                 :             :                   size = "XMMWORD";
   14327                 :             :                 break;
   14328                 :             :               case 32: size = "YMMWORD"; break;
   14329                 :             :               case 64: size = "ZMMWORD"; break;
   14330                 :           0 :               default:
   14331                 :           0 :                 gcc_unreachable ();
   14332                 :             :               }
   14333                 :             :           if (size)
   14334                 :             :             {
   14335                 :         201 :               fputs (size, file);
   14336                 :         201 :               fputs (" PTR ", file);
   14337                 :             :             }
   14338                 :             :         }
   14339                 :             : 
   14340                 :    29886668 :       if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14341                 :           0 :         output_operand_lossage ("invalid constraints for operand");
   14342                 :             :       else
   14343                 :    29886668 :         ix86_print_operand_address_as
   14344                 :    29886668 :           (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
   14345                 :             :     }
   14346                 :             : 
   14347                 :    22714221 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
   14348                 :             :     {
   14349                 :         750 :       long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   14350                 :         750 :                                REAL_MODE_FORMAT (HFmode));
   14351                 :         750 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14352                 :         750 :         putc ('$', file);
   14353                 :         750 :       fprintf (file, "0x%04x", (unsigned int) l);
   14354                 :             :     }
   14355                 :             : 
   14356                 :    22713471 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
   14357                 :             :     {
   14358                 :       17866 :       long l;
   14359                 :             : 
   14360                 :       17866 :       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14361                 :             : 
   14362                 :       17866 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14363                 :       17866 :         putc ('$', file);
   14364                 :             :       /* Sign extend 32bit SFmode immediate to 8 bytes.  */
   14365                 :       17866 :       if (code == 'q')
   14366                 :         370 :         fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
   14367                 :             :                  (unsigned long long) (int) l);
   14368                 :             :       else
   14369                 :       17496 :         fprintf (file, "0x%08x", (unsigned int) l);
   14370                 :             :     }
   14371                 :             : 
   14372                 :    22695605 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
   14373                 :             :     {
   14374                 :        3020 :       long l[2];
   14375                 :             : 
   14376                 :        3020 :       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14377                 :             : 
   14378                 :        3020 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14379                 :        3020 :         putc ('$', file);
   14380                 :        3020 :       fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
   14381                 :             :     }
   14382                 :             : 
   14383                 :             :   /* These float cases don't actually occur as immediate operands.  */
   14384                 :    22692585 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
   14385                 :             :     {
   14386                 :           0 :       char dstr[30];
   14387                 :             : 
   14388                 :           0 :       real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
   14389                 :           0 :       fputs (dstr, file);
   14390                 :             :     }
   14391                 :             : 
   14392                 :             :   /* Print bcst_mem_operand.  */
   14393                 :    22692585 :   else if (GET_CODE (x) == VEC_DUPLICATE)
   14394                 :             :     {
   14395                 :         318 :       machine_mode vmode = GET_MODE (x);
   14396                 :             :       /* Must be bcst_memory_operand.  */
   14397                 :         318 :       gcc_assert (bcst_mem_operand (x, vmode));
   14398                 :             : 
   14399                 :         318 :       rtx mem = XEXP (x,0);
   14400                 :         318 :       ix86_print_operand (file, mem, 0);
   14401                 :             : 
   14402                 :         318 :       switch (vmode)
   14403                 :             :         {
   14404                 :          28 :         case E_V2DImode:
   14405                 :          28 :         case E_V2DFmode:
   14406                 :          28 :           fputs ("{1to2}", file);
   14407                 :          28 :           break;
   14408                 :          77 :         case E_V4SImode:
   14409                 :          77 :         case E_V4SFmode:
   14410                 :          77 :         case E_V4DImode:
   14411                 :          77 :         case E_V4DFmode:
   14412                 :          77 :           fputs ("{1to4}", file);
   14413                 :          77 :           break;
   14414                 :          93 :         case E_V8SImode:
   14415                 :          93 :         case E_V8SFmode:
   14416                 :          93 :         case E_V8DFmode:
   14417                 :          93 :         case E_V8DImode:
   14418                 :          93 :         case E_V8HFmode:
   14419                 :          93 :           fputs ("{1to8}", file);
   14420                 :          93 :           break;
   14421                 :         112 :         case E_V16SFmode:
   14422                 :         112 :         case E_V16SImode:
   14423                 :         112 :         case E_V16HFmode:
   14424                 :         112 :           fputs ("{1to16}", file);
   14425                 :         112 :           break;
   14426                 :           8 :         case E_V32HFmode:
   14427                 :           8 :           fputs ("{1to32}", file);
   14428                 :           8 :           break;
   14429                 :           0 :         default:
   14430                 :           0 :           gcc_unreachable ();
   14431                 :             :         }
   14432                 :             :     }
   14433                 :             : 
   14434                 :             :   else
   14435                 :             :     {
   14436                 :             :       /* We have patterns that allow zero sets of memory, for instance.
   14437                 :             :          In 64-bit mode, we should probably support all 8-byte vectors,
   14438                 :             :          since we can in fact encode that into an immediate.  */
   14439                 :    22692267 :       if (GET_CODE (x) == CONST_VECTOR)
   14440                 :             :         {
   14441                 :         112 :           if (x != CONST0_RTX (GET_MODE (x)))
   14442                 :           2 :             output_operand_lossage ("invalid vector immediate");
   14443                 :         112 :           x = const0_rtx;
   14444                 :             :         }
   14445                 :             : 
   14446                 :    22692267 :       if (code == 'P')
   14447                 :             :         {
   14448                 :     5557772 :           if (ix86_force_load_from_GOT_p (x, true))
   14449                 :             :             {
   14450                 :             :               /* For inline assembly statement, load function address
   14451                 :             :                  from GOT with 'P' operand modifier to avoid PLT.  */
   14452                 :           4 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   14453                 :             :                                   (TARGET_64BIT
   14454                 :             :                                    ? UNSPEC_GOTPCREL
   14455                 :             :                                    : UNSPEC_GOT));
   14456                 :           4 :               x = gen_rtx_CONST (Pmode, x);
   14457                 :           4 :               x = gen_const_mem (Pmode, x);
   14458                 :           4 :               ix86_print_operand (file, x, 'A');
   14459                 :           4 :               return;
   14460                 :             :             }
   14461                 :             :         }
   14462                 :    17134495 :       else if (code != 'p')
   14463                 :             :         {
   14464                 :    17134386 :           if (CONST_INT_P (x))
   14465                 :             :             {
   14466                 :    14052536 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14467                 :    14052358 :                 putc ('$', file);
   14468                 :             :             }
   14469                 :     3081850 :           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
   14470                 :        9402 :                    || GET_CODE (x) == LABEL_REF)
   14471                 :             :             {
   14472                 :     3081848 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14473                 :     3081848 :                 putc ('$', file);
   14474                 :             :               else
   14475                 :           0 :                 fputs ("OFFSET FLAT:", file);
   14476                 :             :             }
   14477                 :             :         }
   14478                 :    22692263 :       if (CONST_INT_P (x))
   14479                 :    14052622 :         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
   14480                 :     8639641 :       else if (flag_pic || MACHOPIC_INDIRECT)
   14481                 :      509840 :         output_pic_addr_const (file, x, code);
   14482                 :             :       else
   14483                 :     8129801 :         output_addr_const (file, x);
   14484                 :             :     }
   14485                 :             : }
   14486                 :             : 
   14487                 :             : static bool
   14488                 :    19312113 : ix86_print_operand_punct_valid_p (unsigned char code)
   14489                 :             : {
   14490                 :    19312113 :   return (code == '*' || code == '+' || code == '&' || code == ';'
   14491                 :    13489015 :           || code == '~' || code == '^' || code == '!');
   14492                 :             : }
   14493                 :             : 
   14494                 :             : /* Print a memory operand whose address is ADDR.  */
   14495                 :             : 
   14496                 :             : static void
   14497                 :    32755330 : ix86_print_operand_address_as (FILE *file, rtx addr,
   14498                 :             :                                addr_space_t as, bool raw)
   14499                 :             : {
   14500                 :    32755330 :   struct ix86_address parts;
   14501                 :    32755330 :   rtx base, index, disp;
   14502                 :    32755330 :   int scale;
   14503                 :    32755330 :   int ok;
   14504                 :    32755330 :   bool vsib = false;
   14505                 :    32755330 :   int code = 0;
   14506                 :             : 
   14507                 :    32755330 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
   14508                 :             :     {
   14509                 :        1900 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   14510                 :        1900 :       gcc_assert (parts.index == NULL_RTX);
   14511                 :        1900 :       parts.index = XVECEXP (addr, 0, 1);
   14512                 :        1900 :       parts.scale = INTVAL (XVECEXP (addr, 0, 2));
   14513                 :        1900 :       addr = XVECEXP (addr, 0, 0);
   14514                 :        1900 :       vsib = true;
   14515                 :             :     }
   14516                 :    32753430 :   else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
   14517                 :             :     {
   14518                 :     2403550 :       gcc_assert (TARGET_64BIT);
   14519                 :     2403550 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   14520                 :     2403550 :       code = 'q';
   14521                 :             :     }
   14522                 :             :   else
   14523                 :    30349880 :     ok = ix86_decompose_address (addr, &parts);
   14524                 :             : 
   14525                 :    32755330 :   gcc_assert (ok);
   14526                 :             : 
   14527                 :    32755330 :   base = parts.base;
   14528                 :    32755330 :   index = parts.index;
   14529                 :    32755330 :   disp = parts.disp;
   14530                 :    32755330 :   scale = parts.scale;
   14531                 :             : 
   14532                 :    32755330 :   if (ADDR_SPACE_GENERIC_P (as))
   14533                 :    32476664 :     as = parts.seg;
   14534                 :             :   else
   14535                 :      278666 :     gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
   14536                 :             : 
   14537                 :    32755330 :   if (!ADDR_SPACE_GENERIC_P (as) && !raw)
   14538                 :             :     {
   14539                 :      278676 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14540                 :      278674 :         putc ('%', file);
   14541                 :             : 
   14542                 :      278676 :       switch (as)
   14543                 :             :         {
   14544                 :      179137 :         case ADDR_SPACE_SEG_FS:
   14545                 :      179137 :           fputs ("fs:", file);
   14546                 :      179137 :           break;
   14547                 :       99539 :         case ADDR_SPACE_SEG_GS:
   14548                 :       99539 :           fputs ("gs:", file);
   14549                 :       99539 :           break;
   14550                 :           0 :         default:
   14551                 :           0 :           gcc_unreachable ();
   14552                 :             :         }
   14553                 :             :     }
   14554                 :             : 
   14555                 :             :   /* Use one byte shorter RIP relative addressing for 64bit mode.  */
   14556                 :    32755330 :   if (TARGET_64BIT && !base && !index && !raw)
   14557                 :             :     {
   14558                 :     5720682 :       rtx symbol = disp;
   14559                 :             : 
   14560                 :     5720682 :       if (GET_CODE (disp) == CONST
   14561                 :     2053061 :           && GET_CODE (XEXP (disp, 0)) == PLUS
   14562                 :     1975057 :           && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   14563                 :     1975057 :         symbol = XEXP (XEXP (disp, 0), 0);
   14564                 :             : 
   14565                 :     5720682 :       if (GET_CODE (symbol) == LABEL_REF
   14566                 :     5720682 :           || (GET_CODE (symbol) == SYMBOL_REF
   14567                 :     5468378 :               && SYMBOL_REF_TLS_MODEL (symbol) == 0))
   14568                 :     5467394 :         base = pc_rtx;
   14569                 :             :     }
   14570                 :             : 
   14571                 :    32755330 :   if (!base && !index)
   14572                 :             :     {
   14573                 :             :       /* Displacement only requires special attention.  */
   14574                 :      596372 :       if (CONST_INT_P (disp))
   14575                 :             :         {
   14576                 :      267565 :           if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
   14577                 :           1 :             fputs ("ds:", file);
   14578                 :      267565 :           fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
   14579                 :             :         }
   14580                 :             :       /* Load the external function address via the GOT slot to avoid PLT.  */
   14581                 :      328807 :       else if (GET_CODE (disp) == CONST
   14582                 :      105539 :                && GET_CODE (XEXP (disp, 0)) == UNSPEC
   14583                 :       78227 :                && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
   14584                 :        6974 :                    || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
   14585                 :      400060 :                && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   14586                 :          16 :         output_pic_addr_const (file, disp, 0);
   14587                 :      328791 :       else if (flag_pic)
   14588                 :      108936 :         output_pic_addr_const (file, disp, 0);
   14589                 :             :       else
   14590                 :      219855 :         output_addr_const (file, disp);
   14591                 :             :     }
   14592                 :             :   else
   14593                 :             :     {
   14594                 :             :       /* Print SImode register names to force addr32 prefix.  */
   14595                 :    32158958 :       if (SImode_address_operand (addr, VOIDmode))
   14596                 :             :         {
   14597                 :          26 :           if (flag_checking)
   14598                 :             :             {
   14599                 :          26 :               gcc_assert (TARGET_64BIT);
   14600                 :          26 :               switch (GET_CODE (addr))
   14601                 :             :                 {
   14602                 :           0 :                 case SUBREG:
   14603                 :           0 :                   gcc_assert (GET_MODE (addr) == SImode);
   14604                 :           0 :                   gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
   14605                 :             :                   break;
   14606                 :          26 :                 case ZERO_EXTEND:
   14607                 :          26 :                 case AND:
   14608                 :          26 :                   gcc_assert (GET_MODE (addr) == DImode);
   14609                 :             :                   break;
   14610                 :           0 :                 default:
   14611                 :           0 :                   gcc_unreachable ();
   14612                 :             :                 }
   14613                 :             :             }
   14614                 :          26 :           gcc_assert (!code);
   14615                 :             :           code = 'k';
   14616                 :             :         }
   14617                 :    32158932 :       else if (code == 0
   14618                 :    29757869 :                && TARGET_X32
   14619                 :         237 :                && disp
   14620                 :         181 :                && CONST_INT_P (disp)
   14621                 :         114 :                && INTVAL (disp) < -16*1024*1024)
   14622                 :             :         {
   14623                 :             :           /* X32 runs in 64-bit mode, where displacement, DISP, in
   14624                 :             :              address DISP(%r64), is encoded as 32-bit immediate sign-
   14625                 :             :              extended from 32-bit to 64-bit.  For -0x40000300(%r64),
   14626                 :             :              address is %r64 + 0xffffffffbffffd00.  When %r64 <
   14627                 :             :              0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
   14628                 :             :              which is invalid for x32.  The correct address is %r64
   14629                 :             :              - 0x40000300 == 0xf7ffdd64.  To properly encode
   14630                 :             :              -0x40000300(%r64) for x32, we zero-extend negative
   14631                 :             :              displacement by forcing addr32 prefix which truncates
   14632                 :             :              0xfffffffff7ffdd64 to 0xf7ffdd64.  In theory, we should
   14633                 :             :              zero-extend all negative displacements, including -1(%rsp).
   14634                 :             :              However, for small negative displacements, sign-extension
   14635                 :             :              won't cause overflow.  We only zero-extend negative
   14636                 :             :              displacements if they < -16*1024*1024, which is also used
   14637                 :             :              to check legitimate address displacements for PIC.  */
   14638                 :          27 :           code = 'k';
   14639                 :             :         }
   14640                 :             : 
   14641                 :             :       /* Since the upper 32 bits of RSP are always zero for x32,
   14642                 :             :          we can encode %esp as %rsp to avoid 0x67 prefix if
   14643                 :             :          there is no index register.  */
   14644                 :         313 :       if (TARGET_X32 && Pmode == SImode
   14645                 :    32159148 :           && !index && base && REG_P (base) && REGNO (base) == SP_REG)
   14646                 :             :         code = 'q';
   14647                 :             : 
   14648                 :    32158958 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14649                 :             :         {
   14650                 :    32158708 :           if (disp)
   14651                 :             :             {
   14652                 :    28564300 :               if (flag_pic)
   14653                 :     2507855 :                 output_pic_addr_const (file, disp, 0);
   14654                 :    26056445 :               else if (GET_CODE (disp) == LABEL_REF)
   14655                 :       15283 :                 output_asm_label (disp);
   14656                 :             :               else
   14657                 :    26041162 :                 output_addr_const (file, disp);
   14658                 :             :             }
   14659                 :             : 
   14660                 :    32158708 :           putc ('(', file);
   14661                 :    32158708 :           if (base)
   14662                 :    31754005 :             print_reg (base, code, file);
   14663                 :    32158708 :           if (index)
   14664                 :             :             {
   14665                 :     1556849 :               putc (',', file);
   14666                 :     3111846 :               print_reg (index, vsib ? 0 : code, file);
   14667                 :     1556849 :               if (scale != 1 || vsib)
   14668                 :      895920 :                 fprintf (file, ",%d", scale);
   14669                 :             :             }
   14670                 :    32158708 :           putc (')', file);
   14671                 :             :         }
   14672                 :             :       else
   14673                 :             :         {
   14674                 :         250 :           rtx offset = NULL_RTX;
   14675                 :             : 
   14676                 :         250 :           if (disp)
   14677                 :             :             {
   14678                 :             :               /* Pull out the offset of a symbol; print any symbol itself.  */
   14679                 :         189 :               if (GET_CODE (disp) == CONST
   14680                 :          16 :                   && GET_CODE (XEXP (disp, 0)) == PLUS
   14681                 :          16 :                   && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   14682                 :             :                 {
   14683                 :          16 :                   offset = XEXP (XEXP (disp, 0), 1);
   14684                 :          16 :                   disp = gen_rtx_CONST (VOIDmode,
   14685                 :             :                                         XEXP (XEXP (disp, 0), 0));
   14686                 :             :                 }
   14687                 :             : 
   14688                 :         189 :               if (flag_pic)
   14689                 :           0 :                 output_pic_addr_const (file, disp, 0);
   14690                 :         189 :               else if (GET_CODE (disp) == LABEL_REF)
   14691                 :           0 :                 output_asm_label (disp);
   14692                 :         189 :               else if (CONST_INT_P (disp))
   14693                 :             :                 offset = disp;
   14694                 :             :               else
   14695                 :          91 :                 output_addr_const (file, disp);
   14696                 :             :             }
   14697                 :             : 
   14698                 :         250 :           putc ('[', file);
   14699                 :         250 :           if (base)
   14700                 :             :             {
   14701                 :         210 :               print_reg (base, code, file);
   14702                 :         210 :               if (offset)
   14703                 :             :                 {
   14704                 :         114 :                   if (INTVAL (offset) >= 0)
   14705                 :          18 :                     putc ('+', file);
   14706                 :         114 :                   fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   14707                 :             :                 }
   14708                 :             :             }
   14709                 :          40 :           else if (offset)
   14710                 :           0 :             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   14711                 :             :           else
   14712                 :          40 :             putc ('0', file);
   14713                 :             : 
   14714                 :         250 :           if (index)
   14715                 :             :             {
   14716                 :          93 :               putc ('+', file);
   14717                 :         138 :               print_reg (index, vsib ? 0 : code, file);
   14718                 :          93 :               if (scale != 1 || vsib)
   14719                 :          91 :                 fprintf (file, "*%d", scale);
   14720                 :             :             }
   14721                 :         250 :           putc (']', file);
   14722                 :             :         }
   14723                 :             :     }
   14724                 :    32755330 : }
   14725                 :             : 
   14726                 :             : static void
   14727                 :     2868663 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   14728                 :             : {
   14729                 :     2868663 :   if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14730                 :           1 :     output_operand_lossage ("invalid constraints for operand");
   14731                 :             :   else
   14732                 :     2868662 :     ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
   14733                 :     2868663 : }
   14734                 :             : 
   14735                 :             : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA.  */
   14736                 :             : 
   14737                 :             : static bool
   14738                 :       12451 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
   14739                 :             : {
   14740                 :       12451 :   rtx op;
   14741                 :             : 
   14742                 :       12451 :   if (GET_CODE (x) != UNSPEC)
   14743                 :             :     return false;
   14744                 :             : 
   14745                 :       12451 :   op = XVECEXP (x, 0, 0);
   14746                 :       12451 :   switch (XINT (x, 1))
   14747                 :             :     {
   14748                 :        1495 :     case UNSPEC_GOTOFF:
   14749                 :        1495 :       output_addr_const (file, op);
   14750                 :        1495 :       fputs ("@gotoff", file);
   14751                 :        1495 :       break;
   14752                 :           0 :     case UNSPEC_GOTTPOFF:
   14753                 :           0 :       output_addr_const (file, op);
   14754                 :             :       /* FIXME: This might be @TPOFF in Sun ld.  */
   14755                 :           0 :       fputs ("@gottpoff", file);
   14756                 :           0 :       break;
   14757                 :           0 :     case UNSPEC_TPOFF:
   14758                 :           0 :       output_addr_const (file, op);
   14759                 :           0 :       fputs ("@tpoff", file);
   14760                 :           0 :       break;
   14761                 :        9537 :     case UNSPEC_NTPOFF:
   14762                 :        9537 :       output_addr_const (file, op);
   14763                 :        9537 :       if (TARGET_64BIT)
   14764                 :        8827 :         fputs ("@tpoff", file);
   14765                 :             :       else
   14766                 :         710 :         fputs ("@ntpoff", file);
   14767                 :             :       break;
   14768                 :          30 :     case UNSPEC_DTPOFF:
   14769                 :          30 :       output_addr_const (file, op);
   14770                 :          30 :       fputs ("@dtpoff", file);
   14771                 :          30 :       break;
   14772                 :        1388 :     case UNSPEC_GOTNTPOFF:
   14773                 :        1388 :       output_addr_const (file, op);
   14774                 :        1388 :       if (TARGET_64BIT)
   14775                 :        1388 :         fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   14776                 :             :                "@gottpoff(%rip)" : "@gottpoff[rip]", file);
   14777                 :             :       else
   14778                 :           0 :         fputs ("@gotntpoff", file);
   14779                 :             :       break;
   14780                 :           1 :     case UNSPEC_INDNTPOFF:
   14781                 :           1 :       output_addr_const (file, op);
   14782                 :           1 :       fputs ("@indntpoff", file);
   14783                 :           1 :       break;
   14784                 :             : #if TARGET_MACHO
   14785                 :             :     case UNSPEC_MACHOPIC_OFFSET:
   14786                 :             :       output_addr_const (file, op);
   14787                 :             :       putc ('-', file);
   14788                 :             :       machopic_output_function_base_name (file);
   14789                 :             :       break;
   14790                 :             : #endif
   14791                 :             : 
   14792                 :             :     default:
   14793                 :             :       return false;
   14794                 :             :     }
   14795                 :             : 
   14796                 :             :   return true;
   14797                 :             : }
   14798                 :             : 
   14799                 :             : 
   14800                 :             : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
   14801                 :             :    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
   14802                 :             :    is the expression of the binary operation.  The output may either be
   14803                 :             :    emitted here, or returned to the caller, like all output_* functions.
   14804                 :             : 
   14805                 :             :    There is no guarantee that the operands are the same mode, as they
   14806                 :             :    might be within FLOAT or FLOAT_EXTEND expressions.  */
   14807                 :             : 
   14808                 :             : #ifndef SYSV386_COMPAT
   14809                 :             : /* Set to 1 for compatibility with brain-damaged assemblers.  No-one
   14810                 :             :    wants to fix the assemblers because that causes incompatibility
   14811                 :             :    with gcc.  No-one wants to fix gcc because that causes
   14812                 :             :    incompatibility with assemblers...  You can use the option of
   14813                 :             :    -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way.  */
   14814                 :             : #define SYSV386_COMPAT 1
   14815                 :             : #endif
   14816                 :             : 
   14817                 :             : const char *
   14818                 :      597229 : output_387_binary_op (rtx_insn *insn, rtx *operands)
   14819                 :             : {
   14820                 :      597229 :   static char buf[40];
   14821                 :      597229 :   const char *p;
   14822                 :      597229 :   bool is_sse
   14823                 :      597229 :     = (SSE_REG_P (operands[0])
   14824                 :      652960 :        || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
   14825                 :             : 
   14826                 :       55731 :   if (is_sse)
   14827                 :             :     p = "%v";
   14828                 :       55731 :   else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
   14829                 :       55724 :            || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
   14830                 :             :     p = "fi";
   14831                 :             :   else
   14832                 :      597229 :     p = "f";
   14833                 :             : 
   14834                 :      597229 :   strcpy (buf, p);
   14835                 :             : 
   14836                 :      597229 :   switch (GET_CODE (operands[3]))
   14837                 :             :     {
   14838                 :             :     case PLUS:
   14839                 :             :       p = "add"; break;
   14840                 :       56101 :     case MINUS:
   14841                 :       56101 :       p = "sub"; break;
   14842                 :       93027 :     case MULT:
   14843                 :       93027 :       p = "mul"; break;
   14844                 :       25981 :     case DIV:
   14845                 :       25981 :       p = "div"; break;
   14846                 :           0 :     default:
   14847                 :           0 :       gcc_unreachable ();
   14848                 :             :     }
   14849                 :             : 
   14850                 :      597229 :   strcat (buf, p);
   14851                 :             : 
   14852                 :      597229 :   if (is_sse)
   14853                 :             :    {
   14854                 :      541498 :      p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
   14855                 :      541498 :      strcat (buf, p);
   14856                 :             : 
   14857                 :      541498 :      if (TARGET_AVX)
   14858                 :             :        p = "\t{%2, %1, %0|%0, %1, %2}";
   14859                 :             :      else
   14860                 :      525846 :        p = "\t{%2, %0|%0, %2}";
   14861                 :             : 
   14862                 :      541498 :      strcat (buf, p);
   14863                 :      541498 :      return buf;
   14864                 :             :    }
   14865                 :             : 
   14866                 :             :   /* Even if we do not want to check the inputs, this documents input
   14867                 :             :      constraints.  Which helps in understanding the following code.  */
   14868                 :       55731 :   if (flag_checking)
   14869                 :             :     {
   14870                 :       55730 :       if (STACK_REG_P (operands[0])
   14871                 :       55730 :           && ((REG_P (operands[1])
   14872                 :       54121 :                && REGNO (operands[0]) == REGNO (operands[1])
   14873                 :       49978 :                && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
   14874                 :        5752 :               || (REG_P (operands[2])
   14875                 :        5752 :                   && REGNO (operands[0]) == REGNO (operands[2])
   14876                 :        5752 :                   && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
   14877                 :      111460 :           && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
   14878                 :             :         ; /* ok */
   14879                 :             :       else
   14880                 :           0 :         gcc_unreachable ();
   14881                 :             :     }
   14882                 :             : 
   14883                 :       55731 :   switch (GET_CODE (operands[3]))
   14884                 :             :     {
   14885                 :       40791 :     case MULT:
   14886                 :       40791 :     case PLUS:
   14887                 :       40791 :       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
   14888                 :        1943 :         std::swap (operands[1], operands[2]);
   14889                 :             : 
   14890                 :             :       /* know operands[0] == operands[1].  */
   14891                 :             : 
   14892                 :       40791 :       if (MEM_P (operands[2]))
   14893                 :             :         {
   14894                 :             :           p = "%Z2\t%2";
   14895                 :             :           break;
   14896                 :             :         }
   14897                 :             : 
   14898                 :       36789 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   14899                 :             :         {
   14900                 :       21790 :           if (STACK_TOP_P (operands[0]))
   14901                 :             :             /* How is it that we are storing to a dead operand[2]?
   14902                 :             :                Well, presumably operands[1] is dead too.  We can't
   14903                 :             :                store the result to st(0) as st(0) gets popped on this
   14904                 :             :                instruction.  Instead store to operands[2] (which I
   14905                 :             :                think has to be st(1)).  st(1) will be popped later.
   14906                 :             :                gcc <= 2.8.1 didn't have this check and generated
   14907                 :             :                assembly code that the Unixware assembler rejected.  */
   14908                 :             :             p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
   14909                 :             :           else
   14910                 :             :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   14911                 :             :           break;
   14912                 :             :         }
   14913                 :             : 
   14914                 :       14999 :       if (STACK_TOP_P (operands[0]))
   14915                 :             :         p = "\t{%y2, %0|%0, %y2}";    /* st(0) = st(0) op st(r2) */
   14916                 :             :       else
   14917                 :             :         p = "\t{%2, %0|%0, %2}";      /* st(r1) = st(r1) op st(0) */
   14918                 :             :       break;
   14919                 :             : 
   14920                 :       14940 :     case MINUS:
   14921                 :       14940 :     case DIV:
   14922                 :       14940 :       if (MEM_P (operands[1]))
   14923                 :             :         {
   14924                 :             :           p = "r%Z1\t%1";
   14925                 :             :           break;
   14926                 :             :         }
   14927                 :             : 
   14928                 :       14500 :       if (MEM_P (operands[2]))
   14929                 :             :         {
   14930                 :             :           p = "%Z2\t%2";
   14931                 :             :           break;
   14932                 :             :         }
   14933                 :             : 
   14934                 :       13242 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   14935                 :             :         {
   14936                 :             : #if SYSV386_COMPAT
   14937                 :             :           /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
   14938                 :             :              derived assemblers, confusingly reverse the direction of
   14939                 :             :              the operation for fsub{r} and fdiv{r} when the
   14940                 :             :              destination register is not st(0).  The Intel assembler
   14941                 :             :              doesn't have this brain damage.  Read !SYSV386_COMPAT to
   14942                 :             :              figure out what the hardware really does.  */
   14943                 :        6378 :           if (STACK_TOP_P (operands[0]))
   14944                 :             :             p = "{p\t%0, %2|rp\t%2, %0}";
   14945                 :             :           else
   14946                 :             :             p = "{rp\t%2, %0|p\t%0, %2}";
   14947                 :             : #else
   14948                 :             :           if (STACK_TOP_P (operands[0]))
   14949                 :             :             /* As above for fmul/fadd, we can't store to st(0).  */
   14950                 :             :             p = "rp\t{%0, %2|%2, %0}";        /* st(1) = st(0) op st(1); pop */
   14951                 :             :           else
   14952                 :             :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   14953                 :             : #endif
   14954                 :             :           break;
   14955                 :             :         }
   14956                 :             : 
   14957                 :        6864 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   14958                 :             :         {
   14959                 :             : #if SYSV386_COMPAT
   14960                 :        3160 :           if (STACK_TOP_P (operands[0]))
   14961                 :             :             p = "{rp\t%0, %1|p\t%1, %0}";
   14962                 :             :           else
   14963                 :             :             p = "{p\t%1, %0|rp\t%0, %1}";
   14964                 :             : #else
   14965                 :             :           if (STACK_TOP_P (operands[0]))
   14966                 :             :             p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
   14967                 :             :           else
   14968                 :             :             p = "rp\t{%1, %0|%0, %1}";        /* st(r2) = st(0) op st(r2); pop */
   14969                 :             : #endif
   14970                 :             :           break;
   14971                 :             :         }
   14972                 :             : 
   14973                 :        3704 :       if (STACK_TOP_P (operands[0]))
   14974                 :             :         {
   14975                 :        2898 :           if (STACK_TOP_P (operands[1]))
   14976                 :             :             p = "\t{%y2, %0|%0, %y2}";        /* st(0) = st(0) op st(r2) */
   14977                 :             :           else
   14978                 :             :             p = "r\t{%y1, %0|%0, %y1}";       /* st(0) = st(r1) op st(0) */
   14979                 :             :           break;
   14980                 :             :         }
   14981                 :         806 :       else if (STACK_TOP_P (operands[1]))
   14982                 :             :         {
   14983                 :             : #if SYSV386_COMPAT
   14984                 :             :           p = "{\t%1, %0|r\t%0, %1}";
   14985                 :             : #else
   14986                 :             :           p = "r\t{%1, %0|%0, %1}";   /* st(r2) = st(0) op st(r2) */
   14987                 :             : #endif
   14988                 :             :         }
   14989                 :             :       else
   14990                 :             :         {
   14991                 :             : #if SYSV386_COMPAT
   14992                 :             :           p = "{r\t%2, %0|\t%0, %2}";
   14993                 :             : #else
   14994                 :             :           p = "\t{%2, %0|%0, %2}";    /* st(r1) = st(r1) op st(0) */
   14995                 :             : #endif
   14996                 :             :         }
   14997                 :             :       break;
   14998                 :             : 
   14999                 :           0 :     default:
   15000                 :           0 :       gcc_unreachable ();
   15001                 :             :     }
   15002                 :             : 
   15003                 :       55731 :   strcat (buf, p);
   15004                 :       55731 :   return buf;
   15005                 :             : }
   15006                 :             : 
   15007                 :             : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15008                 :             : 
   15009                 :             : static int
   15010                 :        1655 : ix86_dirflag_mode_needed (rtx_insn *insn)
   15011                 :             : {
   15012                 :        1655 :   if (CALL_P (insn))
   15013                 :             :     {
   15014                 :         337 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15015                 :             :         return X86_DIRFLAG_ANY;
   15016                 :             :       else
   15017                 :             :         /* No need to emit CLD in interrupt handler for TARGET_CLD.  */
   15018                 :         337 :         return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
   15019                 :             :     }
   15020                 :             : 
   15021                 :        1318 :   if (recog_memoized (insn) < 0)
   15022                 :             :     return X86_DIRFLAG_ANY;
   15023                 :             : 
   15024                 :        1316 :   if (get_attr_type (insn) == TYPE_STR)
   15025                 :             :     {
   15026                 :             :       /* Emit cld instruction if stringops are used in the function.  */
   15027                 :           1 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15028                 :           0 :         return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
   15029                 :             :       else
   15030                 :             :         return X86_DIRFLAG_RESET;
   15031                 :             :     }
   15032                 :             : 
   15033                 :             :   return X86_DIRFLAG_ANY;
   15034                 :             : }
   15035                 :             : 
   15036                 :             : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP.   */
   15037                 :             : 
   15038                 :             : static bool
   15039                 :     8017783 : ix86_check_avx_upper_register (const_rtx exp)
   15040                 :             : {
   15041                 :     3895380 :   return (SSE_REG_P (exp)
   15042                 :     1264165 :           && !EXT_REX_SSE_REG_P (exp)
   15043                 :    10525031 :           && GET_MODE_BITSIZE (GET_MODE (exp)) > 128);
   15044                 :             : }
   15045                 :             : 
   15046                 :             : /* Check if a 256bit or 512bit AVX register is referenced in stores.   */
   15047                 :             : 
   15048                 :             : static void
   15049                 :       44163 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
   15050                 :             : {
   15051                 :       44163 :   if (ix86_check_avx_upper_register (dest))
   15052                 :             :     {
   15053                 :         704 :       bool *used = (bool *) data;
   15054                 :         704 :       *used = true;
   15055                 :             :     }
   15056                 :       44163 : }
   15057                 :             : 
   15058                 :             : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15059                 :             : 
   15060                 :             : static int
   15061                 :     1984299 : ix86_avx_u128_mode_needed (rtx_insn *insn)
   15062                 :             : {
   15063                 :     1984299 :   if (DEBUG_INSN_P (insn))
   15064                 :             :     return AVX_U128_ANY;
   15065                 :             : 
   15066                 :     1984299 :   if (CALL_P (insn))
   15067                 :             :     {
   15068                 :       44953 :       rtx link;
   15069                 :             : 
   15070                 :             :       /* Needed mode is set to AVX_U128_CLEAN if there are
   15071                 :             :          no 256bit or 512bit modes used in function arguments. */
   15072                 :       44953 :       for (link = CALL_INSN_FUNCTION_USAGE (insn);
   15073                 :      116742 :            link;
   15074                 :       71789 :            link = XEXP (link, 1))
   15075                 :             :         {
   15076                 :       72788 :           if (GET_CODE (XEXP (link, 0)) == USE)
   15077                 :             :             {
   15078                 :       71851 :               rtx arg = XEXP (XEXP (link, 0), 0);
   15079                 :             : 
   15080                 :       71851 :               if (ix86_check_avx_upper_register (arg))
   15081                 :             :                 return AVX_U128_DIRTY;
   15082                 :             :             }
   15083                 :             :         }
   15084                 :             : 
   15085                 :             :       /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
   15086                 :             :          nor 512bit registers used in the function return register.  */
   15087                 :       43954 :       bool avx_upper_reg_found = false;
   15088                 :       43954 :       note_stores (insn, ix86_check_avx_upper_stores,
   15089                 :             :                    &avx_upper_reg_found);
   15090                 :       43954 :       if (avx_upper_reg_found)
   15091                 :             :         return AVX_U128_DIRTY;
   15092                 :             : 
   15093                 :             :       /* If the function is known to preserve some SSE registers,
   15094                 :             :          RA and previous passes can legitimately rely on that for
   15095                 :             :          modes wider than 256 bits.  It's only safe to issue a
   15096                 :             :          vzeroupper if all SSE registers are clobbered.  */
   15097                 :       43774 :       const function_abi &abi = insn_callee_abi (insn);
   15098                 :       43774 :       if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
   15099                 :             :           /* Should be safe to issue an vzeroupper before sibling_call_p.
   15100                 :             :              Also there not mode_exit for sibling_call, so there could be
   15101                 :             :              missing vzeroupper for that.  */
   15102                 :       43774 :           || !(SIBLING_CALL_P (insn)
   15103                 :       42534 :                || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15104                 :       42534 :                                          abi.mode_clobbers (V4DImode))))
   15105                 :        9333 :         return AVX_U128_ANY;
   15106                 :             : 
   15107                 :       34441 :       return AVX_U128_CLEAN;
   15108                 :             :     }
   15109                 :             : 
   15110                 :     1939346 :   subrtx_iterator::array_type array;
   15111                 :             : 
   15112                 :     1939346 :   rtx set = single_set (insn);
   15113                 :     1939346 :   if (set)
   15114                 :             :     {
   15115                 :     1872348 :       rtx dest = SET_DEST (set);
   15116                 :     1872348 :       rtx src = SET_SRC (set);
   15117                 :     1872348 :       if (ix86_check_avx_upper_register (dest))
   15118                 :             :         {
   15119                 :             :           /* This is an YMM/ZMM load.  Return AVX_U128_DIRTY if the
   15120                 :             :              source isn't zero.  */
   15121                 :      159672 :           if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
   15122                 :             :             return AVX_U128_DIRTY;
   15123                 :             :           else
   15124                 :             :             return AVX_U128_ANY;
   15125                 :             :         }
   15126                 :             :       else
   15127                 :             :         {
   15128                 :     7044896 :           FOR_EACH_SUBRTX (iter, array, src, NONCONST)
   15129                 :     5400190 :             if (ix86_check_avx_upper_register (*iter))
   15130                 :       67970 :               return AVX_U128_DIRTY;
   15131                 :             :         }
   15132                 :             : 
   15133                 :             :       /* This isn't YMM/ZMM load/store.  */
   15134                 :     1644706 :       return AVX_U128_ANY;
   15135                 :             :     }
   15136                 :             : 
   15137                 :             :   /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
   15138                 :             :      Hardware changes state only when a 256bit register is written to,
   15139                 :             :      but we need to prevent the compiler from moving optimal insertion
   15140                 :             :      point above eventual read from 256bit or 512 bit register.  */
   15141                 :      426973 :   FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   15142                 :      381152 :     if (ix86_check_avx_upper_register (*iter))
   15143                 :       21177 :       return AVX_U128_DIRTY;
   15144                 :             : 
   15145                 :       45821 :   return AVX_U128_ANY;
   15146                 :     1939346 : }
   15147                 :             : 
   15148                 :             : /* Return mode that i387 must be switched into
   15149                 :             :    prior to the execution of insn.  */
   15150                 :             : 
   15151                 :             : static int
   15152                 :      476225 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
   15153                 :             : {
   15154                 :      476225 :   enum attr_i387_cw mode;
   15155                 :             : 
   15156                 :             :   /* The mode UNINITIALIZED is used to store control word after a
   15157                 :             :      function call or ASM pattern.  The mode ANY specify that function
   15158                 :             :      has no requirements on the control word and make no changes in the
   15159                 :             :      bits we are interested in.  */
   15160                 :             : 
   15161                 :      476225 :   if (CALL_P (insn)
   15162                 :      476225 :       || (NONJUMP_INSN_P (insn)
   15163                 :      392250 :           && (asm_noperands (PATTERN (insn)) >= 0
   15164                 :      392250 :               || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
   15165                 :       17162 :     return I387_CW_UNINITIALIZED;
   15166                 :             : 
   15167                 :      459063 :   if (recog_memoized (insn) < 0)
   15168                 :             :     return I387_CW_ANY;
   15169                 :             : 
   15170                 :      458038 :   mode = get_attr_i387_cw (insn);
   15171                 :             : 
   15172                 :      458038 :   switch (entity)
   15173                 :             :     {
   15174                 :           6 :     case I387_ROUNDEVEN:
   15175                 :           6 :       if (mode == I387_CW_ROUNDEVEN)
   15176                 :             :         return mode;
   15177                 :             :       break;
   15178                 :             : 
   15179                 :      450426 :     case I387_TRUNC:
   15180                 :      450426 :       if (mode == I387_CW_TRUNC)
   15181                 :             :         return mode;
   15182                 :             :       break;
   15183                 :             : 
   15184                 :        6040 :     case I387_FLOOR:
   15185                 :        6040 :       if (mode == I387_CW_FLOOR)
   15186                 :             :         return mode;
   15187                 :             :       break;
   15188                 :             : 
   15189                 :        1566 :     case I387_CEIL:
   15190                 :        1566 :       if (mode == I387_CW_CEIL)
   15191                 :             :         return mode;
   15192                 :             :       break;
   15193                 :             : 
   15194                 :           0 :     default:
   15195                 :           0 :       gcc_unreachable ();
   15196                 :             :     }
   15197                 :             : 
   15198                 :             :   return I387_CW_ANY;
   15199                 :             : }
   15200                 :             : 
   15201                 :             : /* Return mode that entity must be switched into
   15202                 :             :    prior to the execution of insn.  */
   15203                 :             : 
   15204                 :             : static int
   15205                 :     2462179 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
   15206                 :             : {
   15207                 :     2462179 :   switch (entity)
   15208                 :             :     {
   15209                 :        1655 :     case X86_DIRFLAG:
   15210                 :        1655 :       return ix86_dirflag_mode_needed (insn);
   15211                 :     1984299 :     case AVX_U128:
   15212                 :     1984299 :       return ix86_avx_u128_mode_needed (insn);
   15213                 :      476225 :     case I387_ROUNDEVEN:
   15214                 :      476225 :     case I387_TRUNC:
   15215                 :      476225 :     case I387_FLOOR:
   15216                 :      476225 :     case I387_CEIL:
   15217                 :      476225 :       return ix86_i387_mode_needed (entity, insn);
   15218                 :           0 :     default:
   15219                 :           0 :       gcc_unreachable ();
   15220                 :             :     }
   15221                 :             :   return 0;
   15222                 :             : }
   15223                 :             : 
   15224                 :             : /* Calculate mode of upper 128bit AVX registers after the insn.  */
   15225                 :             : 
   15226                 :             : static int
   15227                 :     1984299 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
   15228                 :             : {
   15229                 :     1984299 :   rtx pat = PATTERN (insn);
   15230                 :             : 
   15231                 :     1984299 :   if (vzeroupper_pattern (pat, VOIDmode)
   15232                 :     1984299 :       || vzeroall_pattern (pat, VOIDmode))
   15233                 :         180 :     return AVX_U128_CLEAN;
   15234                 :             : 
   15235                 :             :   /* We know that state is clean after CALL insn if there are no
   15236                 :             :      256bit or 512bit registers used in the function return register. */
   15237                 :     1984119 :   if (CALL_P (insn))
   15238                 :             :     {
   15239                 :       44907 :       bool avx_upper_reg_found = false;
   15240                 :       44907 :       note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
   15241                 :             : 
   15242                 :       44907 :       if (avx_upper_reg_found)
   15243                 :             :         return AVX_U128_DIRTY;
   15244                 :             : 
   15245                 :             :       /* If the function desn't clobber any sse registers or only clobber
   15246                 :             :          128-bit part, Then vzeroupper isn't issued before the function exit.
   15247                 :             :          the status not CLEAN but ANY after the function.  */
   15248                 :       44383 :       const function_abi &abi = insn_callee_abi (insn);
   15249                 :       44383 :       if (!(SIBLING_CALL_P (insn)
   15250                 :       43144 :             || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15251                 :       43144 :                                       abi.mode_clobbers (V4DImode))))
   15252                 :        9628 :         return AVX_U128_ANY;
   15253                 :             : 
   15254                 :       34755 :       return  AVX_U128_CLEAN;
   15255                 :             :     }
   15256                 :             : 
   15257                 :             :   /* Otherwise, return current mode.  Remember that if insn
   15258                 :             :      references AVX 256bit or 512bit registers, the mode was already
   15259                 :             :      changed to DIRTY from MODE_NEEDED.  */
   15260                 :             :   return mode;
   15261                 :             : }
   15262                 :             : 
   15263                 :             : /* Return the mode that an insn results in.  */
   15264                 :             : 
   15265                 :             : static int
   15266                 :     2461253 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
   15267                 :             : {
   15268                 :     2461253 :   switch (entity)
   15269                 :             :     {
   15270                 :             :     case X86_DIRFLAG:
   15271                 :             :       return mode;
   15272                 :     1984299 :     case AVX_U128:
   15273                 :     1984299 :       return ix86_avx_u128_mode_after (mode, insn);
   15274                 :             :     case I387_ROUNDEVEN:
   15275                 :             :     case I387_TRUNC:
   15276                 :             :     case I387_FLOOR:
   15277                 :             :     case I387_CEIL:
   15278                 :             :       return mode;
   15279                 :           0 :     default:
   15280                 :           0 :       gcc_unreachable ();
   15281                 :             :     }
   15282                 :             : }
   15283                 :             : 
   15284                 :             : static int
   15285                 :         118 : ix86_dirflag_mode_entry (void)
   15286                 :             : {
   15287                 :             :   /* For TARGET_CLD or in the interrupt handler we can't assume
   15288                 :             :      direction flag state at function entry.  */
   15289                 :         118 :   if (TARGET_CLD
   15290                 :         116 :       || cfun->machine->func_type != TYPE_NORMAL)
   15291                 :         118 :     return X86_DIRFLAG_ANY;
   15292                 :             : 
   15293                 :             :   return X86_DIRFLAG_RESET;
   15294                 :             : }
   15295                 :             : 
   15296                 :             : static int
   15297                 :      109523 : ix86_avx_u128_mode_entry (void)
   15298                 :             : {
   15299                 :      109523 :   tree arg;
   15300                 :             : 
   15301                 :             :   /* Entry mode is set to AVX_U128_DIRTY if there are
   15302                 :             :      256bit or 512bit modes used in function arguments.  */
   15303                 :      278181 :   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
   15304                 :      168658 :        arg = TREE_CHAIN (arg))
   15305                 :             :     {
   15306                 :      197979 :       rtx incoming = DECL_INCOMING_RTL (arg);
   15307                 :             : 
   15308                 :      197979 :       if (incoming && ix86_check_avx_upper_register (incoming))
   15309                 :             :         return AVX_U128_DIRTY;
   15310                 :             :     }
   15311                 :             : 
   15312                 :             :   return AVX_U128_CLEAN;
   15313                 :             : }
   15314                 :             : 
   15315                 :             : /* Return a mode that ENTITY is assumed to be
   15316                 :             :    switched to at function entry.  */
   15317                 :             : 
   15318                 :             : static int
   15319                 :       67090 : ix86_mode_entry (int entity)
   15320                 :             : {
   15321                 :       67090 :   switch (entity)
   15322                 :             :     {
   15323                 :         118 :     case X86_DIRFLAG:
   15324                 :         118 :       return ix86_dirflag_mode_entry ();
   15325                 :       65746 :     case AVX_U128:
   15326                 :       65746 :       return ix86_avx_u128_mode_entry ();
   15327                 :             :     case I387_ROUNDEVEN:
   15328                 :             :     case I387_TRUNC:
   15329                 :             :     case I387_FLOOR:
   15330                 :             :     case I387_CEIL:
   15331                 :             :       return I387_CW_ANY;
   15332                 :           0 :     default:
   15333                 :           0 :       gcc_unreachable ();
   15334                 :             :     }
   15335                 :             : }
   15336                 :             : 
   15337                 :             : static int
   15338                 :       64504 : ix86_avx_u128_mode_exit (void)
   15339                 :             : {
   15340                 :       64504 :   rtx reg = crtl->return_rtx;
   15341                 :             : 
   15342                 :             :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
   15343                 :             :      or 512 bit modes used in the function return register. */
   15344                 :       64504 :   if (reg && ix86_check_avx_upper_register (reg))
   15345                 :             :     return AVX_U128_DIRTY;
   15346                 :             : 
   15347                 :             :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
   15348                 :             :      modes used in function arguments, otherwise return AVX_U128_CLEAN.
   15349                 :             :    */
   15350                 :       43777 :   return ix86_avx_u128_mode_entry ();
   15351                 :             : }
   15352                 :             : 
   15353                 :             : /* Return a mode that ENTITY is assumed to be
   15354                 :             :    switched to at function exit.  */
   15355                 :             : 
   15356                 :             : static int
   15357                 :       65706 : ix86_mode_exit (int entity)
   15358                 :             : {
   15359                 :       65706 :   switch (entity)
   15360                 :             :     {
   15361                 :             :     case X86_DIRFLAG:
   15362                 :             :       return X86_DIRFLAG_ANY;
   15363                 :       64504 :     case AVX_U128:
   15364                 :       64504 :       return ix86_avx_u128_mode_exit ();
   15365                 :        1170 :     case I387_ROUNDEVEN:
   15366                 :        1170 :     case I387_TRUNC:
   15367                 :        1170 :     case I387_FLOOR:
   15368                 :        1170 :     case I387_CEIL:
   15369                 :        1170 :       return I387_CW_ANY;
   15370                 :           0 :     default:
   15371                 :           0 :       gcc_unreachable ();
   15372                 :             :     }
   15373                 :             : }
   15374                 :             : 
   15375                 :             : static int
   15376                 :     2104892 : ix86_mode_priority (int, int n)
   15377                 :             : {
   15378                 :     2104892 :   return n;
   15379                 :             : }
   15380                 :             : 
   15381                 :             : /* Output code to initialize control word copies used by trunc?f?i and
   15382                 :             :    rounding patterns.  CURRENT_MODE is set to current control word,
   15383                 :             :    while NEW_MODE is set to new control word.  */
   15384                 :             : 
   15385                 :             : static void
   15386                 :        3480 : emit_i387_cw_initialization (int mode)
   15387                 :             : {
   15388                 :        3480 :   rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
   15389                 :        3480 :   rtx new_mode;
   15390                 :             : 
   15391                 :        3480 :   enum ix86_stack_slot slot;
   15392                 :             : 
   15393                 :        3480 :   rtx reg = gen_reg_rtx (HImode);
   15394                 :             : 
   15395                 :        3480 :   emit_insn (gen_x86_fnstcw_1 (stored_mode));
   15396                 :        3480 :   emit_move_insn (reg, copy_rtx (stored_mode));
   15397                 :             : 
   15398                 :        3480 :   switch (mode)
   15399                 :             :     {
   15400                 :           1 :     case I387_CW_ROUNDEVEN:
   15401                 :             :       /* round to nearest */
   15402                 :           1 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15403                 :           1 :       slot = SLOT_CW_ROUNDEVEN;
   15404                 :           1 :       break;
   15405                 :             : 
   15406                 :        3213 :     case I387_CW_TRUNC:
   15407                 :             :       /* round toward zero (truncate) */
   15408                 :        3213 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
   15409                 :        3213 :       slot = SLOT_CW_TRUNC;
   15410                 :        3213 :       break;
   15411                 :             : 
   15412                 :         177 :     case I387_CW_FLOOR:
   15413                 :             :       /* round down toward -oo */
   15414                 :         177 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15415                 :         177 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
   15416                 :         177 :       slot = SLOT_CW_FLOOR;
   15417                 :         177 :       break;
   15418                 :             : 
   15419                 :          89 :     case I387_CW_CEIL:
   15420                 :             :       /* round up toward +oo */
   15421                 :          89 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15422                 :          89 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
   15423                 :          89 :       slot = SLOT_CW_CEIL;
   15424                 :          89 :       break;
   15425                 :             : 
   15426                 :           0 :     default:
   15427                 :           0 :       gcc_unreachable ();
   15428                 :             :     }
   15429                 :             : 
   15430                 :        3480 :   gcc_assert (slot < MAX_386_STACK_LOCALS);
   15431                 :             : 
   15432                 :        3480 :   new_mode = assign_386_stack_local (HImode, slot);
   15433                 :        3480 :   emit_move_insn (new_mode, reg);
   15434                 :        3480 : }
   15435                 :             : 
   15436                 :             : /* Generate one or more insns to set ENTITY to MODE.  */
   15437                 :             : 
   15438                 :             : static void
   15439                 :       45251 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
   15440                 :             :                     HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
   15441                 :             : {
   15442                 :       45251 :   switch (entity)
   15443                 :             :     {
   15444                 :         263 :     case X86_DIRFLAG:
   15445                 :         263 :       if (mode == X86_DIRFLAG_RESET)
   15446                 :         263 :         emit_insn (gen_cld ());
   15447                 :             :       break;
   15448                 :       35887 :     case AVX_U128:
   15449                 :       35887 :       if (mode == AVX_U128_CLEAN)
   15450                 :       17282 :         ix86_expand_avx_vzeroupper ();
   15451                 :             :       break;
   15452                 :        9101 :     case I387_ROUNDEVEN:
   15453                 :        9101 :     case I387_TRUNC:
   15454                 :        9101 :     case I387_FLOOR:
   15455                 :        9101 :     case I387_CEIL:
   15456                 :        9101 :       if (mode != I387_CW_ANY
   15457                 :        9101 :           && mode != I387_CW_UNINITIALIZED)
   15458                 :        3480 :         emit_i387_cw_initialization (mode);
   15459                 :             :       break;
   15460                 :           0 :     default:
   15461                 :           0 :       gcc_unreachable ();
   15462                 :             :     }
   15463                 :       45251 : }
   15464                 :             : 
   15465                 :             : /* Output code for INSN to convert a float to a signed int.  OPERANDS
   15466                 :             :    are the insn operands.  The output may be [HSD]Imode and the input
   15467                 :             :    operand may be [SDX]Fmode.  */
   15468                 :             : 
   15469                 :             : const char *
   15470                 :        7585 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
   15471                 :             : {
   15472                 :        7585 :   bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   15473                 :        7585 :   bool dimode_p = GET_MODE (operands[0]) == DImode;
   15474                 :        7585 :   int round_mode = get_attr_i387_cw (insn);
   15475                 :             : 
   15476                 :        7585 :   static char buf[40];
   15477                 :        7585 :   const char *p;
   15478                 :             : 
   15479                 :             :   /* Jump through a hoop or two for DImode, since the hardware has no
   15480                 :             :      non-popping instruction.  We used to do this a different way, but
   15481                 :             :      that was somewhat fragile and broke with post-reload splitters.  */
   15482                 :        7585 :   if ((dimode_p || fisttp) && !stack_top_dies)
   15483                 :          25 :     output_asm_insn ("fld\t%y1", operands);
   15484                 :             : 
   15485                 :        7585 :   gcc_assert (STACK_TOP_P (operands[1]));
   15486                 :        7585 :   gcc_assert (MEM_P (operands[0]));
   15487                 :        7585 :   gcc_assert (GET_MODE (operands[1]) != TFmode);
   15488                 :             : 
   15489                 :        7585 :   if (fisttp)
   15490                 :             :     return "fisttp%Z0\t%0";
   15491                 :             : 
   15492                 :        7584 :   strcpy (buf, "fist");
   15493                 :             : 
   15494                 :        7584 :   if (round_mode != I387_CW_ANY)
   15495                 :        7536 :     output_asm_insn ("fldcw\t%3", operands);
   15496                 :             : 
   15497                 :        7584 :   p = "p%Z0\t%0";
   15498                 :        7584 :   strcat (buf, p + !(stack_top_dies || dimode_p));
   15499                 :             : 
   15500                 :        7584 :   output_asm_insn (buf, operands);
   15501                 :             : 
   15502                 :        7584 :   if (round_mode != I387_CW_ANY)
   15503                 :        7536 :     output_asm_insn ("fldcw\t%2", operands);
   15504                 :             : 
   15505                 :             :   return "";
   15506                 :             : }
   15507                 :             : 
   15508                 :             : /* Output code for x87 ffreep insn.  The OPNO argument, which may only
   15509                 :             :    have the values zero or one, indicates the ffreep insn's operand
   15510                 :             :    from the OPERANDS array.  */
   15511                 :             : 
   15512                 :             : static const char *
   15513                 :      282177 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
   15514                 :             : {
   15515                 :           0 :   if (TARGET_USE_FFREEP)
   15516                 :             : #ifdef HAVE_AS_IX86_FFREEP
   15517                 :           0 :     return opno ? "ffreep\t%y1" : "ffreep\t%y0";
   15518                 :             : #else
   15519                 :             :     {
   15520                 :             :       static char retval[32];
   15521                 :             :       int regno = REGNO (operands[opno]);
   15522                 :             : 
   15523                 :             :       gcc_assert (STACK_REGNO_P (regno));
   15524                 :             : 
   15525                 :             :       regno -= FIRST_STACK_REG;
   15526                 :             : 
   15527                 :             :       snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
   15528                 :             :       return retval;
   15529                 :             :     }
   15530                 :             : #endif
   15531                 :             : 
   15532                 :           0 :   return opno ? "fstp\t%y1" : "fstp\t%y0";
   15533                 :             : }
   15534                 :             : 
   15535                 :             : 
   15536                 :             : /* Output code for INSN to compare OPERANDS.  EFLAGS_P is 1 when fcomi
   15537                 :             :    should be used.  UNORDERED_P is true when fucom should be used.  */
   15538                 :             : 
   15539                 :             : const char *
   15540                 :      107636 : output_fp_compare (rtx_insn *insn, rtx *operands,
   15541                 :             :                    bool eflags_p, bool unordered_p)
   15542                 :             : {
   15543                 :      107636 :   rtx *xops = eflags_p ? &operands[0] : &operands[1];
   15544                 :      107636 :   bool stack_top_dies;
   15545                 :             : 
   15546                 :      107636 :   static char buf[40];
   15547                 :      107636 :   const char *p;
   15548                 :             : 
   15549                 :      107636 :   gcc_assert (STACK_TOP_P (xops[0]));
   15550                 :             : 
   15551                 :      107636 :   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   15552                 :             : 
   15553                 :      107636 :   if (eflags_p)
   15554                 :             :     {
   15555                 :      107636 :       p = unordered_p ? "fucomi" : "fcomi";
   15556                 :      107636 :       strcpy (buf, p);
   15557                 :             : 
   15558                 :      107636 :       p = "p\t{%y1, %0|%0, %y1}";
   15559                 :      107636 :       strcat (buf, p + !stack_top_dies);
   15560                 :             : 
   15561                 :      107636 :       return buf;
   15562                 :             :     }
   15563                 :             : 
   15564                 :           0 :   if (STACK_REG_P (xops[1])
   15565                 :           0 :       && stack_top_dies
   15566                 :           0 :       && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
   15567                 :             :     {
   15568                 :           0 :       gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
   15569                 :             : 
   15570                 :             :       /* If both the top of the 387 stack die, and the other operand
   15571                 :             :          is also a stack register that dies, then this must be a
   15572                 :             :          `fcompp' float compare.  */
   15573                 :           0 :       p = unordered_p ? "fucompp" : "fcompp";
   15574                 :           0 :       strcpy (buf, p);
   15575                 :             :     }
   15576                 :           0 :   else if (const0_operand (xops[1], VOIDmode))
   15577                 :             :     {
   15578                 :           0 :       gcc_assert (!unordered_p);
   15579                 :           0 :       strcpy (buf, "ftst");
   15580                 :             :     }
   15581                 :             :   else
   15582                 :             :     {
   15583                 :           0 :       if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
   15584                 :             :         {
   15585                 :           0 :           gcc_assert (!unordered_p);
   15586                 :             :           p = "ficom";
   15587                 :             :         }
   15588                 :             :       else
   15589                 :           0 :         p = unordered_p ? "fucom" : "fcom";
   15590                 :             : 
   15591                 :           0 :       strcpy (buf, p);
   15592                 :             : 
   15593                 :           0 :       p = "p%Z2\t%y2";
   15594                 :           0 :       strcat (buf, p + !stack_top_dies);
   15595                 :             :     }
   15596                 :             : 
   15597                 :           0 :   output_asm_insn (buf, operands);
   15598                 :           0 :   return "fnstsw\t%0";
   15599                 :             : }
   15600                 :             : 
   15601                 :             : void
   15602                 :      333927 : ix86_output_addr_vec_elt (FILE *file, int value)
   15603                 :             : {
   15604                 :      333927 :   const char *directive = ASM_LONG;
   15605                 :             : 
   15606                 :             : #ifdef ASM_QUAD
   15607                 :      333927 :   if (TARGET_LP64)
   15608                 :      320909 :     directive = ASM_QUAD;
   15609                 :             : #else
   15610                 :             :   gcc_assert (!TARGET_64BIT);
   15611                 :             : #endif
   15612                 :             : 
   15613                 :      333927 :   fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
   15614                 :      333927 : }
   15615                 :             : 
   15616                 :             : void
   15617                 :       27747 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
   15618                 :             : {
   15619                 :       27747 :   const char *directive = ASM_LONG;
   15620                 :             : 
   15621                 :             : #ifdef ASM_QUAD
   15622                 :       42409 :   if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
   15623                 :             :     directive = ASM_QUAD;
   15624                 :             : #else
   15625                 :             :   gcc_assert (!TARGET_64BIT);
   15626                 :             : #endif
   15627                 :             :   /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand.  */
   15628                 :       27747 :   if (TARGET_64BIT || TARGET_VXWORKS_RTP)
   15629                 :       14662 :     fprintf (file, "%s%s%d-%s%d\n",
   15630                 :             :              directive, LPREFIX, value, LPREFIX, rel);
   15631                 :             : #if TARGET_MACHO
   15632                 :             :   else if (TARGET_MACHO)
   15633                 :             :     {
   15634                 :             :       fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
   15635                 :             :       machopic_output_function_base_name (file);
   15636                 :             :       putc ('\n', file);
   15637                 :             :     }
   15638                 :             : #endif
   15639                 :       13085 :   else if (HAVE_AS_GOTOFF_IN_DATA)
   15640                 :       13085 :     fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
   15641                 :             :   else
   15642                 :             :     asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
   15643                 :             :                  GOT_SYMBOL_NAME, LPREFIX, value);
   15644                 :       27747 : }
   15645                 :             : 
   15646                 :             : #define LEA_MAX_STALL (3)
   15647                 :             : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
   15648                 :             : 
   15649                 :             : /* Increase given DISTANCE in half-cycles according to
   15650                 :             :    dependencies between PREV and NEXT instructions.
   15651                 :             :    Add 1 half-cycle if there is no dependency and
   15652                 :             :    go to next cycle if there is some dependecy.  */
   15653                 :             : 
   15654                 :             : static unsigned int
   15655                 :        2416 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
   15656                 :             : {
   15657                 :        2416 :   df_ref def, use;
   15658                 :             : 
   15659                 :        2416 :   if (!prev || !next)
   15660                 :         880 :     return distance + (distance & 1) + 2;
   15661                 :             : 
   15662                 :        1536 :   if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
   15663                 :         259 :     return distance + 1;
   15664                 :             : 
   15665                 :        2123 :   FOR_EACH_INSN_USE (use, next)
   15666                 :        2668 :     FOR_EACH_INSN_DEF (def, prev)
   15667                 :        1822 :       if (!DF_REF_IS_ARTIFICIAL (def)
   15668                 :        1822 :           && DF_REF_REGNO (use) == DF_REF_REGNO (def))
   15669                 :         769 :         return distance + (distance & 1) + 2;
   15670                 :             : 
   15671                 :         508 :   return distance + 1;
   15672                 :             : }
   15673                 :             : 
   15674                 :             : /* Function checks if instruction INSN defines register number
   15675                 :             :    REGNO1 or REGNO2.  */
   15676                 :             : 
   15677                 :             : bool
   15678                 :        2383 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
   15679                 :             :                   rtx_insn *insn)
   15680                 :             : {
   15681                 :        2383 :   df_ref def;
   15682                 :             : 
   15683                 :        4320 :   FOR_EACH_INSN_DEF (def, insn)
   15684                 :        2411 :     if (DF_REF_REG_DEF_P (def)
   15685                 :        2411 :         && !DF_REF_IS_ARTIFICIAL (def)
   15686                 :        2411 :         && (regno1 == DF_REF_REGNO (def)
   15687                 :        1968 :             || regno2 == DF_REF_REGNO (def)))
   15688                 :             :       return true;
   15689                 :             : 
   15690                 :             :   return false;
   15691                 :             : }
   15692                 :             : 
   15693                 :             : /* Function checks if instruction INSN uses register number
   15694                 :             :    REGNO as a part of address expression.  */
   15695                 :             : 
   15696                 :             : static bool
   15697                 :        1355 : insn_uses_reg_mem (unsigned int regno, rtx insn)
   15698                 :             : {
   15699                 :        1355 :   df_ref use;
   15700                 :             : 
   15701                 :        2857 :   FOR_EACH_INSN_USE (use, insn)
   15702                 :        1570 :     if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
   15703                 :             :       return true;
   15704                 :             : 
   15705                 :             :   return false;
   15706                 :             : }
   15707                 :             : 
   15708                 :             : /* Search backward for non-agu definition of register number REGNO1
   15709                 :             :    or register number REGNO2 in basic block starting from instruction
   15710                 :             :    START up to head of basic block or instruction INSN.
   15711                 :             : 
   15712                 :             :    Function puts true value into *FOUND var if definition was found
   15713                 :             :    and false otherwise.
   15714                 :             : 
   15715                 :             :    Distance in half-cycles between START and found instruction or head
   15716                 :             :    of BB is added to DISTANCE and returned.  */
   15717                 :             : 
   15718                 :             : static int
   15719                 :         703 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
   15720                 :             :                                rtx_insn *insn, int distance,
   15721                 :             :                                rtx_insn *start, bool *found)
   15722                 :             : {
   15723                 :         703 :   basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
   15724                 :         703 :   rtx_insn *prev = start;
   15725                 :         703 :   rtx_insn *next = NULL;
   15726                 :             : 
   15727                 :         703 :   *found = false;
   15728                 :             : 
   15729                 :         703 :   while (prev
   15730                 :        2117 :          && prev != insn
   15731                 :        2117 :          && distance < LEA_SEARCH_THRESHOLD)
   15732                 :             :     {
   15733                 :        1915 :       if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
   15734                 :             :         {
   15735                 :        1061 :           distance = increase_distance (prev, next, distance);
   15736                 :        1061 :           if (insn_defines_reg (regno1, regno2, prev))
   15737                 :             :             {
   15738                 :         287 :               if (recog_memoized (prev) < 0
   15739                 :         287 :                   || get_attr_type (prev) != TYPE_LEA)
   15740                 :             :                 {
   15741                 :         253 :                   *found = true;
   15742                 :         253 :                   return distance;
   15743                 :             :                 }
   15744                 :             :             }
   15745                 :             : 
   15746                 :             :           next = prev;
   15747                 :             :         }
   15748                 :        1662 :       if (prev == BB_HEAD (bb))
   15749                 :             :         break;
   15750                 :             : 
   15751                 :        1414 :       prev = PREV_INSN (prev);
   15752                 :             :     }
   15753                 :             : 
   15754                 :             :   return distance;
   15755                 :             : }
   15756                 :             : 
   15757                 :             : /* Search backward for non-agu definition of register number REGNO1
   15758                 :             :    or register number REGNO2 in INSN's basic block until
   15759                 :             :    1. Pass LEA_SEARCH_THRESHOLD instructions, or
   15760                 :             :    2. Reach neighbor BBs boundary, or
   15761                 :             :    3. Reach agu definition.
   15762                 :             :    Returns the distance between the non-agu definition point and INSN.
   15763                 :             :    If no definition point, returns -1.  */
   15764                 :             : 
   15765                 :             : static int
   15766                 :         480 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
   15767                 :             :                          rtx_insn *insn)
   15768                 :             : {
   15769                 :         480 :   basic_block bb = BLOCK_FOR_INSN (insn);
   15770                 :         480 :   int distance = 0;
   15771                 :         480 :   bool found = false;
   15772                 :             : 
   15773                 :         480 :   if (insn != BB_HEAD (bb))
   15774                 :         480 :     distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
   15775                 :             :                                               distance, PREV_INSN (insn),
   15776                 :             :                                               &found);
   15777                 :             : 
   15778                 :         480 :   if (!found && distance < LEA_SEARCH_THRESHOLD)
   15779                 :             :     {
   15780                 :         180 :       edge e;
   15781                 :         180 :       edge_iterator ei;
   15782                 :         180 :       bool simple_loop = false;
   15783                 :             : 
   15784                 :         379 :       FOR_EACH_EDGE (e, ei, bb->preds)
   15785                 :         239 :         if (e->src == bb)
   15786                 :             :           {
   15787                 :             :             simple_loop = true;
   15788                 :             :             break;
   15789                 :             :           }
   15790                 :             : 
   15791                 :         180 :       if (simple_loop)
   15792                 :          40 :         distance = distance_non_agu_define_in_bb (regno1, regno2,
   15793                 :             :                                                   insn, distance,
   15794                 :          40 :                                                   BB_END (bb), &found);
   15795                 :             :       else
   15796                 :             :         {
   15797                 :         140 :           int shortest_dist = -1;
   15798                 :         140 :           bool found_in_bb = false;
   15799                 :             : 
   15800                 :         323 :           FOR_EACH_EDGE (e, ei, bb->preds)
   15801                 :             :             {
   15802                 :         183 :               int bb_dist
   15803                 :         366 :                 = distance_non_agu_define_in_bb (regno1, regno2,
   15804                 :             :                                                  insn, distance,
   15805                 :         183 :                                                  BB_END (e->src),
   15806                 :             :                                                  &found_in_bb);
   15807                 :         183 :               if (found_in_bb)
   15808                 :             :                 {
   15809                 :          29 :                   if (shortest_dist < 0)
   15810                 :             :                     shortest_dist = bb_dist;
   15811                 :           0 :                   else if (bb_dist > 0)
   15812                 :           0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   15813                 :             : 
   15814                 :          29 :                   found = true;
   15815                 :             :                 }
   15816                 :             :             }
   15817                 :             : 
   15818                 :         140 :           distance = shortest_dist;
   15819                 :             :         }
   15820                 :             :     }
   15821                 :             : 
   15822                 :         480 :   if (!found)
   15823                 :             :     return -1;
   15824                 :             : 
   15825                 :         253 :   return distance >> 1;
   15826                 :             : }
   15827                 :             : 
   15828                 :             : /* Return the distance in half-cycles between INSN and the next
   15829                 :             :    insn that uses register number REGNO in memory address added
   15830                 :             :    to DISTANCE.  Return -1 if REGNO0 is set.
   15831                 :             : 
   15832                 :             :    Put true value into *FOUND if register usage was found and
   15833                 :             :    false otherwise.
   15834                 :             :    Put true value into *REDEFINED if register redefinition was
   15835                 :             :    found and false otherwise.  */
   15836                 :             : 
   15837                 :             : static int
   15838                 :         842 : distance_agu_use_in_bb (unsigned int regno,
   15839                 :             :                         rtx_insn *insn, int distance, rtx_insn *start,
   15840                 :             :                         bool *found, bool *redefined)
   15841                 :             : {
   15842                 :         842 :   basic_block bb = NULL;
   15843                 :         842 :   rtx_insn *next = start;
   15844                 :         842 :   rtx_insn *prev = NULL;
   15845                 :             : 
   15846                 :         842 :   *found = false;
   15847                 :         842 :   *redefined = false;
   15848                 :             : 
   15849                 :         842 :   if (start != NULL_RTX)
   15850                 :             :     {
   15851                 :         825 :       bb = BLOCK_FOR_INSN (start);
   15852                 :         825 :       if (start != BB_HEAD (bb))
   15853                 :             :         /* If insn and start belong to the same bb, set prev to insn,
   15854                 :             :            so the call to increase_distance will increase the distance
   15855                 :             :            between insns by 1.  */
   15856                 :         446 :         prev = insn;
   15857                 :             :     }
   15858                 :             : 
   15859                 :        2923 :   while (next
   15860                 :        2923 :          && next != insn
   15861                 :        2923 :          && distance < LEA_SEARCH_THRESHOLD)
   15862                 :             :     {
   15863                 :        2698 :       if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
   15864                 :             :         {
   15865                 :        1355 :           distance = increase_distance(prev, next, distance);
   15866                 :        1355 :           if (insn_uses_reg_mem (regno, next))
   15867                 :             :             {
   15868                 :             :               /* Return DISTANCE if OP0 is used in memory
   15869                 :             :                  address in NEXT.  */
   15870                 :          68 :               *found = true;
   15871                 :          68 :               return distance;
   15872                 :             :             }
   15873                 :             : 
   15874                 :        1287 :           if (insn_defines_reg (regno, INVALID_REGNUM, next))
   15875                 :             :             {
   15876                 :             :               /* Return -1 if OP0 is set in NEXT.  */
   15877                 :         182 :               *redefined = true;
   15878                 :         182 :               return -1;
   15879                 :             :             }
   15880                 :             : 
   15881                 :             :           prev = next;
   15882                 :             :         }
   15883                 :             : 
   15884                 :        2448 :       if (next == BB_END (bb))
   15885                 :             :         break;
   15886                 :             : 
   15887                 :        2081 :       next = NEXT_INSN (next);
   15888                 :             :     }
   15889                 :             : 
   15890                 :             :   return distance;
   15891                 :             : }
   15892                 :             : 
   15893                 :             : /* Return the distance between INSN and the next insn that uses
   15894                 :             :    register number REGNO0 in memory address.  Return -1 if no such
   15895                 :             :    a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set.  */
   15896                 :             : 
   15897                 :             : static int
   15898                 :         480 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
   15899                 :             : {
   15900                 :         480 :   basic_block bb = BLOCK_FOR_INSN (insn);
   15901                 :         480 :   int distance = 0;
   15902                 :         480 :   bool found = false;
   15903                 :         480 :   bool redefined = false;
   15904                 :             : 
   15905                 :         480 :   if (insn != BB_END (bb))
   15906                 :         446 :     distance = distance_agu_use_in_bb (regno0, insn, distance,
   15907                 :             :                                        NEXT_INSN (insn),
   15908                 :             :                                        &found, &redefined);
   15909                 :             : 
   15910                 :         480 :   if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
   15911                 :             :     {
   15912                 :         276 :       edge e;
   15913                 :         276 :       edge_iterator ei;
   15914                 :         276 :       bool simple_loop = false;
   15915                 :             : 
   15916                 :         608 :       FOR_EACH_EDGE (e, ei, bb->succs)
   15917                 :         396 :         if (e->dest == bb)
   15918                 :             :           {
   15919                 :             :             simple_loop = true;
   15920                 :             :             break;
   15921                 :             :           }
   15922                 :             : 
   15923                 :         276 :       if (simple_loop)
   15924                 :          64 :         distance = distance_agu_use_in_bb (regno0, insn,
   15925                 :             :                                            distance, BB_HEAD (bb),
   15926                 :             :                                            &found, &redefined);
   15927                 :             :       else
   15928                 :             :         {
   15929                 :         212 :           int shortest_dist = -1;
   15930                 :         212 :           bool found_in_bb = false;
   15931                 :         212 :           bool redefined_in_bb = false;
   15932                 :             : 
   15933                 :         544 :           FOR_EACH_EDGE (e, ei, bb->succs)
   15934                 :             :             {
   15935                 :         332 :               int bb_dist
   15936                 :         664 :                 = distance_agu_use_in_bb (regno0, insn,
   15937                 :         332 :                                           distance, BB_HEAD (e->dest),
   15938                 :             :                                           &found_in_bb, &redefined_in_bb);
   15939                 :         332 :               if (found_in_bb)
   15940                 :             :                 {
   15941                 :          10 :                   if (shortest_dist < 0)
   15942                 :             :                     shortest_dist = bb_dist;
   15943                 :           0 :                   else if (bb_dist > 0)
   15944                 :           0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   15945                 :             : 
   15946                 :          10 :                   found = true;
   15947                 :             :                 }
   15948                 :             :             }
   15949                 :             : 
   15950                 :         212 :           distance = shortest_dist;
   15951                 :             :         }
   15952                 :             :     }
   15953                 :             : 
   15954                 :         480 :   if (!found || redefined)
   15955                 :             :     return -1;
   15956                 :             : 
   15957                 :          68 :   return distance >> 1;
   15958                 :             : }
   15959                 :             : 
   15960                 :             : /* Define this macro to tune LEA priority vs ADD, it take effect when
   15961                 :             :    there is a dilemma of choosing LEA or ADD
   15962                 :             :    Negative value: ADD is more preferred than LEA
   15963                 :             :    Zero: Neutral
   15964                 :             :    Positive value: LEA is more preferred than ADD.  */
   15965                 :             : #define IX86_LEA_PRIORITY 0
   15966                 :             : 
   15967                 :             : /* Return true if usage of lea INSN has performance advantage
   15968                 :             :    over a sequence of instructions.  Instructions sequence has
   15969                 :             :    SPLIT_COST cycles higher latency than lea latency.  */
   15970                 :             : 
   15971                 :             : static bool
   15972                 :        1802 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
   15973                 :             :                       unsigned int regno2, int split_cost, bool has_scale)
   15974                 :             : {
   15975                 :        1802 :   int dist_define, dist_use;
   15976                 :             : 
   15977                 :             :   /* For Atom processors newer than Bonnell, if using a 2-source or
   15978                 :             :      3-source LEA for non-destructive destination purposes, or due to
   15979                 :             :      wanting ability to use SCALE, the use of LEA is justified.  */
   15980                 :        1802 :   if (!TARGET_CPU_P (BONNELL))
   15981                 :             :     {
   15982                 :        1322 :       if (has_scale)
   15983                 :             :         return true;
   15984                 :        1303 :       if (split_cost < 1)
   15985                 :             :         return false;
   15986                 :         483 :       if (regno0 == regno1 || regno0 == regno2)
   15987                 :             :         return false;
   15988                 :             :       return true;
   15989                 :             :     }
   15990                 :             : 
   15991                 :             :   /* Remember recog_data content.  */
   15992                 :         480 :   struct recog_data_d recog_data_save = recog_data;
   15993                 :             : 
   15994                 :         480 :   dist_define = distance_non_agu_define (regno1, regno2, insn);
   15995                 :         480 :   dist_use = distance_agu_use (regno0, insn);
   15996                 :             : 
   15997                 :             :   /* distance_non_agu_define can call get_attr_type which can call
   15998                 :             :      recog_memoized, restore recog_data back to previous content.  */
   15999                 :         480 :   recog_data = recog_data_save;
   16000                 :             : 
   16001                 :         480 :   if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
   16002                 :             :     {
   16003                 :             :       /* If there is no non AGU operand definition, no AGU
   16004                 :             :          operand usage and split cost is 0 then both lea
   16005                 :             :          and non lea variants have same priority.  Currently
   16006                 :             :          we prefer lea for 64 bit code and non lea on 32 bit
   16007                 :             :          code.  */
   16008                 :         233 :       if (dist_use < 0 && split_cost == 0)
   16009                 :         136 :         return TARGET_64BIT || IX86_LEA_PRIORITY;
   16010                 :             :       else
   16011                 :             :         return true;
   16012                 :             :     }
   16013                 :             : 
   16014                 :             :   /* With longer definitions distance lea is more preferable.
   16015                 :             :      Here we change it to take into account splitting cost and
   16016                 :             :      lea priority.  */
   16017                 :         247 :   dist_define += split_cost + IX86_LEA_PRIORITY;
   16018                 :             : 
   16019                 :             :   /* If there is no use in memory addess then we just check
   16020                 :             :      that split cost exceeds AGU stall.  */
   16021                 :         247 :   if (dist_use < 0)
   16022                 :         242 :     return dist_define > LEA_MAX_STALL;
   16023                 :             : 
   16024                 :             :   /* If this insn has both backward non-agu dependence and forward
   16025                 :             :      agu dependence, the one with short distance takes effect.  */
   16026                 :           5 :   return dist_define >= dist_use;
   16027                 :             : }
   16028                 :             : 
   16029                 :             : /* Return true if we need to split op0 = op1 + op2 into a sequence of
   16030                 :             :    move and add to avoid AGU stalls.  */
   16031                 :             : 
   16032                 :             : bool
   16033                 :     8665355 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
   16034                 :             : {
   16035                 :     8665355 :   unsigned int regno0, regno1, regno2;
   16036                 :             : 
   16037                 :             :   /* Check if we need to optimize.  */
   16038                 :     8665355 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16039                 :     8664430 :     return false;
   16040                 :             : 
   16041                 :         925 :   regno0 = true_regnum (operands[0]);
   16042                 :         925 :   regno1 = true_regnum (operands[1]);
   16043                 :         925 :   regno2 = true_regnum (operands[2]);
   16044                 :             : 
   16045                 :             :   /* We need to split only adds with non destructive
   16046                 :             :      destination operand.  */
   16047                 :         925 :   if (regno0 == regno1 || regno0 == regno2)
   16048                 :             :     return false;
   16049                 :             :   else
   16050                 :         313 :     return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
   16051                 :             : }
   16052                 :             : 
   16053                 :             : /* Return true if we should emit lea instruction instead of mov
   16054                 :             :    instruction.  */
   16055                 :             : 
   16056                 :             : bool
   16057                 :    27016272 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
   16058                 :             : {
   16059                 :    27016272 :   unsigned int regno0, regno1;
   16060                 :             : 
   16061                 :             :   /* Check if we need to optimize.  */
   16062                 :    27016272 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16063                 :    27014078 :     return false;
   16064                 :             : 
   16065                 :             :   /* Use lea for reg to reg moves only.  */
   16066                 :        2194 :   if (!REG_P (operands[0]) || !REG_P (operands[1]))
   16067                 :             :     return false;
   16068                 :             : 
   16069                 :         516 :   regno0 = true_regnum (operands[0]);
   16070                 :         516 :   regno1 = true_regnum (operands[1]);
   16071                 :             : 
   16072                 :         516 :   return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
   16073                 :             : }
   16074                 :             : 
   16075                 :             : /* Return true if we need to split lea into a sequence of
   16076                 :             :    instructions to avoid AGU stalls during peephole2. */
   16077                 :             : 
   16078                 :             : bool
   16079                 :    10482873 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
   16080                 :             : {
   16081                 :    10482873 :   unsigned int regno0, regno1, regno2;
   16082                 :    10482873 :   int split_cost;
   16083                 :    10482873 :   struct ix86_address parts;
   16084                 :    10482873 :   int ok;
   16085                 :             : 
   16086                 :             :   /* The "at least two components" test below might not catch simple
   16087                 :             :      move or zero extension insns if parts.base is non-NULL and parts.disp
   16088                 :             :      is const0_rtx as the only components in the address, e.g. if the
   16089                 :             :      register is %rbp or %r13.  As this test is much cheaper and moves or
   16090                 :             :      zero extensions are the common case, do this check first.  */
   16091                 :    10482873 :   if (REG_P (operands[1])
   16092                 :    10482873 :       || (SImode_address_operand (operands[1], VOIDmode)
   16093                 :       90832 :           && REG_P (XEXP (operands[1], 0))))
   16094                 :     4403457 :     return false;
   16095                 :             : 
   16096                 :     6079416 :   ok = ix86_decompose_address (operands[1], &parts);
   16097                 :     6079416 :   gcc_assert (ok);
   16098                 :             : 
   16099                 :             :   /* There should be at least two components in the address.  */
   16100                 :     6079416 :   if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
   16101                 :     6079416 :       + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
   16102                 :             :     return false;
   16103                 :             : 
   16104                 :             :   /* We should not split into add if non legitimate pic
   16105                 :             :      operand is used as displacement. */
   16106                 :     2048665 :   if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
   16107                 :             :     return false;
   16108                 :             : 
   16109                 :     1998674 :   regno0 = true_regnum (operands[0]) ;
   16110                 :     1998674 :   regno1 = INVALID_REGNUM;
   16111                 :     1998674 :   regno2 = INVALID_REGNUM;
   16112                 :             : 
   16113                 :     1998674 :   if (parts.base)
   16114                 :     1935936 :     regno1 = true_regnum (parts.base);
   16115                 :     1998674 :   if (parts.index)
   16116                 :      385280 :     regno2 = true_regnum (parts.index);
   16117                 :             : 
   16118                 :             :   /* Use add for a = a + b and a = b + a since it is faster and shorter
   16119                 :             :      than lea for most processors.  For the processors like BONNELL, if
   16120                 :             :      the destination register of LEA holds an actual address which will
   16121                 :             :      be used soon, LEA is better and otherwise ADD is better.  */
   16122                 :     1998674 :   if (!TARGET_CPU_P (BONNELL)
   16123                 :     1998551 :       && parts.scale == 1
   16124                 :     1793855 :       && (!parts.disp || parts.disp == const0_rtx)
   16125                 :      141744 :       && (regno0 == regno1 || regno0 == regno2))
   16126                 :             :     return true;
   16127                 :             : 
   16128                 :             :   /* Split with -Oz if the encoding requires fewer bytes.  */
   16129                 :     1996691 :   if (optimize_size > 1
   16130                 :          23 :       && parts.scale > 1
   16131                 :           4 :       && !parts.base
   16132                 :           4 :       && (!parts.disp || parts.disp == const0_rtx)) 
   16133                 :             :     return true;
   16134                 :             : 
   16135                 :             :   /* Check we need to optimize.  */
   16136                 :     1996687 :   if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
   16137                 :     1996341 :     return false;
   16138                 :             : 
   16139                 :         346 :   split_cost = 0;
   16140                 :             : 
   16141                 :             :   /* Compute how many cycles we will add to execution time
   16142                 :             :      if split lea into a sequence of instructions.  */
   16143                 :         346 :   if (parts.base || parts.index)
   16144                 :             :     {
   16145                 :             :       /* Have to use mov instruction if non desctructive
   16146                 :             :          destination form is used.  */
   16147                 :         346 :       if (regno1 != regno0 && regno2 != regno0)
   16148                 :         260 :         split_cost += 1;
   16149                 :             : 
   16150                 :             :       /* Have to add index to base if both exist.  */
   16151                 :         346 :       if (parts.base && parts.index)
   16152                 :          49 :         split_cost += 1;
   16153                 :             : 
   16154                 :             :       /* Have to use shift and adds if scale is 2 or greater.  */
   16155                 :         346 :       if (parts.scale > 1)
   16156                 :             :         {
   16157                 :          28 :           if (regno0 != regno1)
   16158                 :          20 :             split_cost += 1;
   16159                 :           8 :           else if (regno2 == regno0)
   16160                 :           2 :             split_cost += 4;
   16161                 :             :           else
   16162                 :           6 :             split_cost += parts.scale;
   16163                 :             :         }
   16164                 :             : 
   16165                 :             :       /* Have to use add instruction with immediate if
   16166                 :             :          disp is non zero.  */
   16167                 :         346 :       if (parts.disp && parts.disp != const0_rtx)
   16168                 :         296 :         split_cost += 1;
   16169                 :             : 
   16170                 :             :       /* Subtract the price of lea.  */
   16171                 :         346 :       split_cost -= 1;
   16172                 :             :     }
   16173                 :             : 
   16174                 :         346 :   return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
   16175                 :         346 :                                 parts.scale > 1);
   16176                 :             : }
   16177                 :             : 
   16178                 :             : /* Return true if it is ok to optimize an ADD operation to LEA
   16179                 :             :    operation to avoid flag register consumation.  For most processors,
   16180                 :             :    ADD is faster than LEA.  For the processors like BONNELL, if the
   16181                 :             :    destination register of LEA holds an actual address which will be
   16182                 :             :    used soon, LEA is better and otherwise ADD is better.  */
   16183                 :             : 
   16184                 :             : bool
   16185                 :     8718407 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
   16186                 :             : {
   16187                 :     8718407 :   unsigned int regno0 = true_regnum (operands[0]);
   16188                 :     8718407 :   unsigned int regno1 = true_regnum (operands[1]);
   16189                 :     8718407 :   unsigned int regno2 = true_regnum (operands[2]);
   16190                 :             : 
   16191                 :             :   /* If a = b + c, (a!=b && a!=c), must use lea form. */
   16192                 :     8718407 :   if (regno0 != regno1 && regno0 != regno2)
   16193                 :             :     return true;
   16194                 :             : 
   16195                 :     6785827 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16196                 :     6785200 :     return false;
   16197                 :             : 
   16198                 :         627 :   return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
   16199                 :             : }
   16200                 :             : 
   16201                 :             : /* Return true if destination reg of SET_BODY is shift count of
   16202                 :             :    USE_BODY.  */
   16203                 :             : 
   16204                 :             : static bool
   16205                 :         375 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
   16206                 :             : {
   16207                 :         375 :   rtx set_dest;
   16208                 :         375 :   rtx shift_rtx;
   16209                 :         375 :   int i;
   16210                 :             : 
   16211                 :             :   /* Retrieve destination of SET_BODY.  */
   16212                 :         375 :   switch (GET_CODE (set_body))
   16213                 :             :     {
   16214                 :         301 :     case SET:
   16215                 :         301 :       set_dest = SET_DEST (set_body);
   16216                 :         301 :       if (!set_dest || !REG_P (set_dest))
   16217                 :             :         return false;
   16218                 :         300 :       break;
   16219                 :          37 :     case PARALLEL:
   16220                 :         111 :       for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
   16221                 :          74 :         if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
   16222                 :             :                                           use_body))
   16223                 :             :           return true;
   16224                 :             :       /* FALLTHROUGH */
   16225                 :             :     default:
   16226                 :             :       return false;
   16227                 :             :     }
   16228                 :             : 
   16229                 :             :   /* Retrieve shift count of USE_BODY.  */
   16230                 :         300 :   switch (GET_CODE (use_body))
   16231                 :             :     {
   16232                 :         100 :     case SET:
   16233                 :         100 :       shift_rtx = XEXP (use_body, 1);
   16234                 :         100 :       break;
   16235                 :         100 :     case PARALLEL:
   16236                 :         300 :       for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
   16237                 :         200 :         if (ix86_dep_by_shift_count_body (set_body,
   16238                 :         200 :                                           XVECEXP (use_body, 0, i)))
   16239                 :             :           return true;
   16240                 :             :       /* FALLTHROUGH */
   16241                 :             :     default:
   16242                 :             :       return false;
   16243                 :             :     }
   16244                 :             : 
   16245                 :         100 :   if (shift_rtx
   16246                 :         100 :       && (GET_CODE (shift_rtx) == ASHIFT
   16247                 :          64 :           || GET_CODE (shift_rtx) == LSHIFTRT
   16248                 :          24 :           || GET_CODE (shift_rtx) == ASHIFTRT
   16249                 :          13 :           || GET_CODE (shift_rtx) == ROTATE
   16250                 :          13 :           || GET_CODE (shift_rtx) == ROTATERT))
   16251                 :             :     {
   16252                 :          87 :       rtx shift_count = XEXP (shift_rtx, 1);
   16253                 :             : 
   16254                 :             :       /* Return true if shift count is dest of SET_BODY.  */
   16255                 :          87 :       if (REG_P (shift_count))
   16256                 :             :         {
   16257                 :             :           /* Add check since it can be invoked before register
   16258                 :             :              allocation in pre-reload schedule.  */
   16259                 :           0 :           if (reload_completed
   16260                 :           0 :               && true_regnum (set_dest) == true_regnum (shift_count))
   16261                 :             :             return true;
   16262                 :           0 :           else if (REGNO(set_dest) == REGNO(shift_count))
   16263                 :             :             return true;
   16264                 :             :         }
   16265                 :             :     }
   16266                 :             : 
   16267                 :             :   return false;
   16268                 :             : }
   16269                 :             : 
   16270                 :             : /* Return true if destination reg of SET_INSN is shift count of
   16271                 :             :    USE_INSN.  */
   16272                 :             : 
   16273                 :             : bool
   16274                 :         101 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
   16275                 :             : {
   16276                 :         101 :   return ix86_dep_by_shift_count_body (PATTERN (set_insn),
   16277                 :         101 :                                        PATTERN (use_insn));
   16278                 :             : }
   16279                 :             : 
   16280                 :             : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
   16281                 :             :    are ok, keeping in mind the possible movddup alternative.  */
   16282                 :             : 
   16283                 :             : bool
   16284                 :       27009 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
   16285                 :             : {
   16286                 :       27009 :   if (MEM_P (operands[0]))
   16287                 :         332 :     return rtx_equal_p (operands[0], operands[1 + high]);
   16288                 :       26677 :   if (MEM_P (operands[1]) && MEM_P (operands[2]))
   16289                 :         540 :     return false;
   16290                 :             :   return true;
   16291                 :             : }
   16292                 :             : 
   16293                 :             : /* A subroutine of ix86_build_signbit_mask.  If VECT is true,
   16294                 :             :    then replicate the value for all elements of the vector
   16295                 :             :    register.  */
   16296                 :             : 
   16297                 :             : rtx
   16298                 :       72652 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
   16299                 :             : {
   16300                 :       72652 :   int i, n_elt;
   16301                 :       72652 :   rtvec v;
   16302                 :       72652 :   machine_mode scalar_mode;
   16303                 :             : 
   16304                 :       72652 :   switch (mode)
   16305                 :             :     {
   16306                 :         962 :     case E_V64QImode:
   16307                 :         962 :     case E_V32QImode:
   16308                 :         962 :     case E_V16QImode:
   16309                 :         962 :     case E_V32HImode:
   16310                 :         962 :     case E_V16HImode:
   16311                 :         962 :     case E_V8HImode:
   16312                 :         962 :     case E_V16SImode:
   16313                 :         962 :     case E_V8SImode:
   16314                 :         962 :     case E_V4SImode:
   16315                 :         962 :     case E_V2SImode:
   16316                 :         962 :     case E_V8DImode:
   16317                 :         962 :     case E_V4DImode:
   16318                 :         962 :     case E_V2DImode:
   16319                 :         962 :       gcc_assert (vect);
   16320                 :             :       /* FALLTHRU */
   16321                 :       72652 :     case E_V2HFmode:
   16322                 :       72652 :     case E_V4HFmode:
   16323                 :       72652 :     case E_V8HFmode:
   16324                 :       72652 :     case E_V16HFmode:
   16325                 :       72652 :     case E_V32HFmode:
   16326                 :       72652 :     case E_V16SFmode:
   16327                 :       72652 :     case E_V8SFmode:
   16328                 :       72652 :     case E_V4SFmode:
   16329                 :       72652 :     case E_V2SFmode:
   16330                 :       72652 :     case E_V8DFmode:
   16331                 :       72652 :     case E_V4DFmode:
   16332                 :       72652 :     case E_V2DFmode:
   16333                 :       72652 :       n_elt = GET_MODE_NUNITS (mode);
   16334                 :       72652 :       v = rtvec_alloc (n_elt);
   16335                 :       72652 :       scalar_mode = GET_MODE_INNER (mode);
   16336                 :             : 
   16337                 :       72652 :       RTVEC_ELT (v, 0) = value;
   16338                 :             : 
   16339                 :      224970 :       for (i = 1; i < n_elt; ++i)
   16340                 :      152318 :         RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
   16341                 :             : 
   16342                 :       72652 :       return gen_rtx_CONST_VECTOR (mode, v);
   16343                 :             : 
   16344                 :           0 :     default:
   16345                 :           0 :       gcc_unreachable ();
   16346                 :             :     }
   16347                 :             : }
   16348                 :             : 
   16349                 :             : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
   16350                 :             :    and ix86_expand_int_vcond.  Create a mask for the sign bit in MODE
   16351                 :             :    for an SSE register.  If VECT is true, then replicate the mask for
   16352                 :             :    all elements of the vector register.  If INVERT is true, then create
   16353                 :             :    a mask excluding the sign bit.  */
   16354                 :             : 
   16355                 :             : rtx
   16356                 :       51589 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
   16357                 :             : {
   16358                 :       51589 :   machine_mode vec_mode, imode;
   16359                 :       51589 :   wide_int w;
   16360                 :       51589 :   rtx mask, v;
   16361                 :             : 
   16362                 :       51589 :   switch (mode)
   16363                 :             :     {
   16364                 :             :     case E_V2HFmode:
   16365                 :             :     case E_V4HFmode:
   16366                 :             :     case E_V8HFmode:
   16367                 :             :     case E_V16HFmode:
   16368                 :             :     case E_V32HFmode:
   16369                 :             :       vec_mode = mode;
   16370                 :             :       imode = HImode;
   16371                 :             :       break;
   16372                 :             : 
   16373                 :       22157 :     case E_V16SImode:
   16374                 :       22157 :     case E_V16SFmode:
   16375                 :       22157 :     case E_V8SImode:
   16376                 :       22157 :     case E_V4SImode:
   16377                 :       22157 :     case E_V8SFmode:
   16378                 :       22157 :     case E_V4SFmode:
   16379                 :       22157 :     case E_V2SFmode:
   16380                 :       22157 :     case E_V2SImode:
   16381                 :       22157 :       vec_mode = mode;
   16382                 :       22157 :       imode = SImode;
   16383                 :       22157 :       break;
   16384                 :             : 
   16385                 :       26866 :     case E_V8DImode:
   16386                 :       26866 :     case E_V4DImode:
   16387                 :       26866 :     case E_V2DImode:
   16388                 :       26866 :     case E_V8DFmode:
   16389                 :       26866 :     case E_V4DFmode:
   16390                 :       26866 :     case E_V2DFmode:
   16391                 :       26866 :       vec_mode = mode;
   16392                 :       26866 :       imode = DImode;
   16393                 :       26866 :       break;
   16394                 :             : 
   16395                 :        2184 :     case E_TImode:
   16396                 :        2184 :     case E_TFmode:
   16397                 :        2184 :       vec_mode = VOIDmode;
   16398                 :        2184 :       imode = TImode;
   16399                 :        2184 :       break;
   16400                 :             : 
   16401                 :           0 :     default:
   16402                 :           0 :       gcc_unreachable ();
   16403                 :             :     }
   16404                 :             : 
   16405                 :       51589 :   machine_mode inner_mode = GET_MODE_INNER (mode);
   16406                 :      103178 :   w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
   16407                 :      103178 :                            GET_MODE_BITSIZE (inner_mode));
   16408                 :       51589 :   if (invert)
   16409                 :       15843 :     w = wi::bit_not (w);
   16410                 :             : 
   16411                 :             :   /* Force this value into the low part of a fp vector constant.  */
   16412                 :       51589 :   mask = immed_wide_int_const (w, imode);
   16413                 :       51589 :   mask = gen_lowpart (inner_mode, mask);
   16414                 :             : 
   16415                 :       51589 :   if (vec_mode == VOIDmode)
   16416                 :        2184 :     return force_reg (inner_mode, mask);
   16417                 :             : 
   16418                 :       49405 :   v = ix86_build_const_vector (vec_mode, vect, mask);
   16419                 :       49405 :   return force_reg (vec_mode, v);
   16420                 :       51589 : }
   16421                 :             : 
   16422                 :             : /* Return HOST_WIDE_INT for const vector OP in MODE.  */
   16423                 :             : 
   16424                 :             : HOST_WIDE_INT
   16425                 :      106294 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
   16426                 :             : {
   16427                 :      228533 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   16428                 :           0 :     gcc_unreachable ();
   16429                 :             : 
   16430                 :      106294 :   int nunits = GET_MODE_NUNITS (mode);
   16431                 :      212588 :   wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
   16432                 :      106294 :   machine_mode innermode = GET_MODE_INNER (mode);
   16433                 :      106294 :   unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
   16434                 :             : 
   16435                 :      106294 :   switch (mode)
   16436                 :             :     {
   16437                 :             :     case E_V2QImode:
   16438                 :             :     case E_V4QImode:
   16439                 :             :     case E_V2HImode:
   16440                 :             :     case E_V8QImode:
   16441                 :             :     case E_V4HImode:
   16442                 :             :     case E_V2SImode:
   16443                 :      358251 :       for (int i = 0; i < nunits; ++i)
   16444                 :             :         {
   16445                 :      255360 :           int v = INTVAL (XVECEXP (op, 0, i));
   16446                 :      255360 :           wide_int wv = wi::shwi (v, innermode_bits);
   16447                 :      255360 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16448                 :      255360 :         }
   16449                 :             :       break;
   16450                 :             :     case E_V2HFmode:
   16451                 :             :     case E_V2BFmode:
   16452                 :             :     case E_V4HFmode:
   16453                 :             :     case E_V4BFmode:
   16454                 :             :     case E_V2SFmode:
   16455                 :       10285 :       for (int i = 0; i < nunits; ++i)
   16456                 :             :         {
   16457                 :        6882 :           rtx x = XVECEXP (op, 0, i);
   16458                 :        6882 :           int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   16459                 :        6882 :                                   REAL_MODE_FORMAT (innermode));
   16460                 :        6882 :           wide_int wv = wi::shwi (v, innermode_bits);
   16461                 :        6882 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16462                 :        6882 :         }
   16463                 :             :       break;
   16464                 :           0 :     default:
   16465                 :           0 :       gcc_unreachable ();
   16466                 :             :     }
   16467                 :             : 
   16468                 :      212588 :   return val.to_shwi ();
   16469                 :      106294 : }
   16470                 :             : 
   16471                 :             : /* Return TRUE or FALSE depending on whether the first SET in INSN
   16472                 :             :    has source and destination with matching CC modes, and that the
   16473                 :             :    CC mode is at least as constrained as REQ_MODE.  */
   16474                 :             : 
   16475                 :             : bool
   16476                 :    11368360 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
   16477                 :             : {
   16478                 :    11368360 :   rtx set;
   16479                 :    11368360 :   machine_mode set_mode;
   16480                 :             : 
   16481                 :    11368360 :   set = PATTERN (insn);
   16482                 :    11368360 :   if (GET_CODE (set) == PARALLEL)
   16483                 :      322614 :     set = XVECEXP (set, 0, 0);
   16484                 :    11368360 :   gcc_assert (GET_CODE (set) == SET);
   16485                 :    11368360 :   gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
   16486                 :             : 
   16487                 :    11368360 :   set_mode = GET_MODE (SET_DEST (set));
   16488                 :    11368360 :   switch (set_mode)
   16489                 :             :     {
   16490                 :      274741 :     case E_CCNOmode:
   16491                 :      274741 :       if (req_mode != CCNOmode
   16492                 :       33033 :           && (req_mode != CCmode
   16493                 :           0 :               || XEXP (SET_SRC (set), 1) != const0_rtx))
   16494                 :             :         return false;
   16495                 :             :       break;
   16496                 :     1038354 :     case E_CCmode:
   16497                 :     1038354 :       if (req_mode == CCGCmode)
   16498                 :             :         return false;
   16499                 :             :       /* FALLTHRU */
   16500                 :     1766843 :     case E_CCGCmode:
   16501                 :     1766843 :       if (req_mode == CCGOCmode || req_mode == CCNOmode)
   16502                 :             :         return false;
   16503                 :             :       /* FALLTHRU */
   16504                 :     2107763 :     case E_CCGOCmode:
   16505                 :     2107763 :       if (req_mode == CCZmode)
   16506                 :             :         return false;
   16507                 :             :       /* FALLTHRU */
   16508                 :             :     case E_CCZmode:
   16509                 :             :       break;
   16510                 :             : 
   16511                 :         356 :     case E_CCGZmode:
   16512                 :             : 
   16513                 :         356 :     case E_CCAmode:
   16514                 :         356 :     case E_CCCmode:
   16515                 :         356 :     case E_CCOmode:
   16516                 :         356 :     case E_CCPmode:
   16517                 :         356 :     case E_CCSmode:
   16518                 :         356 :       if (set_mode != req_mode)
   16519                 :             :         return false;
   16520                 :             :       break;
   16521                 :             : 
   16522                 :           0 :     default:
   16523                 :           0 :       gcc_unreachable ();
   16524                 :             :     }
   16525                 :             : 
   16526                 :    11329290 :   return GET_MODE (SET_SRC (set)) == set_mode;
   16527                 :             : }
   16528                 :             : 
   16529                 :             : machine_mode
   16530                 :    11764276 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
   16531                 :             : {
   16532                 :    11764276 :   machine_mode mode = GET_MODE (op0);
   16533                 :             : 
   16534                 :    11764276 :   if (SCALAR_FLOAT_MODE_P (mode))
   16535                 :             :     {
   16536                 :      107091 :       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
   16537                 :             :       return CCFPmode;
   16538                 :             :     }
   16539                 :             : 
   16540                 :    11657185 :   switch (code)
   16541                 :             :     {
   16542                 :             :       /* Only zero flag is needed.  */
   16543                 :             :     case EQ:                    /* ZF=0 */
   16544                 :             :     case NE:                    /* ZF!=0 */
   16545                 :             :       return CCZmode;
   16546                 :             :       /* Codes needing carry flag.  */
   16547                 :      789948 :     case GEU:                   /* CF=0 */
   16548                 :      789948 :     case LTU:                   /* CF=1 */
   16549                 :      789948 :       rtx geu;
   16550                 :             :       /* Detect overflow checks.  They need just the carry flag.  */
   16551                 :      789948 :       if (GET_CODE (op0) == PLUS
   16552                 :      789948 :           && (rtx_equal_p (op1, XEXP (op0, 0))
   16553                 :       95908 :               || rtx_equal_p (op1, XEXP (op0, 1))))
   16554                 :       17852 :         return CCCmode;
   16555                 :             :       /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
   16556                 :             :          Match LTU of op0
   16557                 :             :          (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   16558                 :             :          and op1
   16559                 :             :          (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
   16560                 :             :          where CC_CCC is either CC or CCC.  */
   16561                 :      772096 :       else if (code == LTU
   16562                 :      275464 :                && GET_CODE (op0) == NEG
   16563                 :        2465 :                && GET_CODE (geu = XEXP (op0, 0)) == GEU
   16564                 :        1142 :                && REG_P (XEXP (geu, 0))
   16565                 :         816 :                && (GET_MODE (XEXP (geu, 0)) == CCCmode
   16566                 :          14 :                    || GET_MODE (XEXP (geu, 0)) == CCmode)
   16567                 :         810 :                && REGNO (XEXP (geu, 0)) == FLAGS_REG
   16568                 :         810 :                && XEXP (geu, 1) == const0_rtx
   16569                 :         810 :                && GET_CODE (op1) == LTU
   16570                 :         810 :                && REG_P (XEXP (op1, 0))
   16571                 :         810 :                && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   16572                 :         810 :                && REGNO (XEXP (op1, 0)) == FLAGS_REG
   16573                 :      772906 :                && XEXP (op1, 1) == const0_rtx)
   16574                 :             :         return CCCmode;
   16575                 :             :       /* Similarly for *x86_cmc pattern.
   16576                 :             :          Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   16577                 :             :          and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
   16578                 :             :          It is sufficient to test that the operand modes are CCCmode.  */
   16579                 :      771286 :       else if (code == LTU
   16580                 :      274654 :                && GET_CODE (op0) == NEG
   16581                 :        1655 :                && GET_CODE (XEXP (op0, 0)) == LTU
   16582                 :         340 :                && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   16583                 :           3 :                && GET_CODE (op1) == GEU
   16584                 :           3 :                && GET_MODE (XEXP (op1, 0)) == CCCmode)
   16585                 :             :         return CCCmode;
   16586                 :             :       else
   16587                 :             :         return CCmode;
   16588                 :             :     case GTU:                   /* CF=0 & ZF=0 */
   16589                 :             :     case LEU:                   /* CF=1 | ZF=1 */
   16590                 :             :       return CCmode;
   16591                 :             :       /* Codes possibly doable only with sign flag when
   16592                 :             :          comparing against zero.  */
   16593                 :      654848 :     case GE:                    /* SF=OF   or   SF=0 */
   16594                 :      654848 :     case LT:                    /* SF<>OF  or   SF=1 */
   16595                 :      654848 :       if (op1 == const0_rtx)
   16596                 :             :         return CCGOCmode;
   16597                 :             :       else
   16598                 :             :         /* For other cases Carry flag is not required.  */
   16599                 :      335615 :         return CCGCmode;
   16600                 :             :       /* Codes doable only with sign flag when comparing
   16601                 :             :          against zero, but we miss jump instruction for it
   16602                 :             :          so we need to use relational tests against overflow
   16603                 :             :          that thus needs to be zero.  */
   16604                 :      740562 :     case GT:                    /* ZF=0 & SF=OF */
   16605                 :      740562 :     case LE:                    /* ZF=1 | SF<>OF */
   16606                 :      740562 :       if (op1 == const0_rtx)
   16607                 :             :         return CCNOmode;
   16608                 :             :       else
   16609                 :      478000 :         return CCGCmode;
   16610                 :             :     default:
   16611                 :             :       /* CCmode should be used in all other cases.  */
   16612                 :             :       return CCmode;
   16613                 :             :     }
   16614                 :             : }
   16615                 :             : 
   16616                 :             : /* Return TRUE or FALSE depending on whether the ptest instruction
   16617                 :             :    INSN has source and destination with suitable matching CC modes.  */
   16618                 :             : 
   16619                 :             : bool
   16620                 :        7549 : ix86_match_ptest_ccmode (rtx insn)
   16621                 :             : {
   16622                 :        7549 :   rtx set, src;
   16623                 :        7549 :   machine_mode set_mode;
   16624                 :             : 
   16625                 :        7549 :   set = PATTERN (insn);
   16626                 :        7549 :   gcc_assert (GET_CODE (set) == SET);
   16627                 :        7549 :   src = SET_SRC (set);
   16628                 :        7549 :   gcc_assert (GET_CODE (src) == UNSPEC
   16629                 :             :               && XINT (src, 1) == UNSPEC_PTEST);
   16630                 :             : 
   16631                 :        7549 :   set_mode = GET_MODE (src);
   16632                 :        7549 :   if (set_mode != CCZmode
   16633                 :             :       && set_mode != CCCmode
   16634                 :             :       && set_mode != CCmode)
   16635                 :             :     return false;
   16636                 :        7549 :   return GET_MODE (SET_DEST (set)) == set_mode;
   16637                 :             : }
   16638                 :             : 
   16639                 :             : /* Return the fixed registers used for condition codes.  */
   16640                 :             : 
   16641                 :             : static bool
   16642                 :     9153338 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
   16643                 :             : {
   16644                 :     9153338 :   *p1 = FLAGS_REG;
   16645                 :     9153338 :   *p2 = INVALID_REGNUM;
   16646                 :     9153338 :   return true;
   16647                 :             : }
   16648                 :             : 
   16649                 :             : /* If two condition code modes are compatible, return a condition code
   16650                 :             :    mode which is compatible with both.  Otherwise, return
   16651                 :             :    VOIDmode.  */
   16652                 :             : 
   16653                 :             : static machine_mode
   16654                 :       30202 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
   16655                 :             : {
   16656                 :       30202 :   if (m1 == m2)
   16657                 :             :     return m1;
   16658                 :             : 
   16659                 :       30110 :   if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
   16660                 :             :     return VOIDmode;
   16661                 :             : 
   16662                 :       30110 :   if ((m1 == CCGCmode && m2 == CCGOCmode)
   16663                 :       30110 :       || (m1 == CCGOCmode && m2 == CCGCmode))
   16664                 :             :     return CCGCmode;
   16665                 :             : 
   16666                 :       30110 :   if ((m1 == CCNOmode && m2 == CCGOCmode)
   16667                 :       29888 :       || (m1 == CCGOCmode && m2 == CCNOmode))
   16668                 :             :     return CCNOmode;
   16669                 :             : 
   16670                 :       29738 :   if (m1 == CCZmode
   16671                 :       18387 :       && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
   16672                 :             :     return m2;
   16673                 :       15689 :   else if (m2 == CCZmode
   16674                 :       11142 :            && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
   16675                 :             :     return m1;
   16676                 :             : 
   16677                 :        5676 :   switch (m1)
   16678                 :             :     {
   16679                 :           0 :     default:
   16680                 :           0 :       gcc_unreachable ();
   16681                 :             : 
   16682                 :        5676 :     case E_CCmode:
   16683                 :        5676 :     case E_CCGCmode:
   16684                 :        5676 :     case E_CCGOCmode:
   16685                 :        5676 :     case E_CCNOmode:
   16686                 :        5676 :     case E_CCAmode:
   16687                 :        5676 :     case E_CCCmode:
   16688                 :        5676 :     case E_CCOmode:
   16689                 :        5676 :     case E_CCPmode:
   16690                 :        5676 :     case E_CCSmode:
   16691                 :        5676 :     case E_CCZmode:
   16692                 :        5676 :       switch (m2)
   16693                 :             :         {
   16694                 :             :         default:
   16695                 :             :           return VOIDmode;
   16696                 :             : 
   16697                 :             :         case E_CCmode:
   16698                 :             :         case E_CCGCmode:
   16699                 :             :         case E_CCGOCmode:
   16700                 :             :         case E_CCNOmode:
   16701                 :             :         case E_CCAmode:
   16702                 :             :         case E_CCCmode:
   16703                 :             :         case E_CCOmode:
   16704                 :             :         case E_CCPmode:
   16705                 :             :         case E_CCSmode:
   16706                 :             :         case E_CCZmode:
   16707                 :             :           return CCmode;
   16708                 :             :         }
   16709                 :             : 
   16710                 :             :     case E_CCFPmode:
   16711                 :             :       /* These are only compatible with themselves, which we already
   16712                 :             :          checked above.  */
   16713                 :             :       return VOIDmode;
   16714                 :             :     }
   16715                 :             : }
   16716                 :             : 
   16717                 :             : /* Return strategy to use for floating-point.  We assume that fcomi is always
   16718                 :             :    preferrable where available, since that is also true when looking at size
   16719                 :             :    (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
   16720                 :             : 
   16721                 :             : enum ix86_fpcmp_strategy
   16722                 :     5264584 : ix86_fp_comparison_strategy (enum rtx_code)
   16723                 :             : {
   16724                 :             :   /* Do fcomi/sahf based test when profitable.  */
   16725                 :             : 
   16726                 :     5264584 :   if (TARGET_CMOVE)
   16727                 :             :     return IX86_FPCMP_COMI;
   16728                 :             : 
   16729                 :           0 :   if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
   16730                 :           0 :     return IX86_FPCMP_SAHF;
   16731                 :             : 
   16732                 :             :   return IX86_FPCMP_ARITH;
   16733                 :             : }
   16734                 :             : 
   16735                 :             : /* Convert comparison codes we use to represent FP comparison to integer
   16736                 :             :    code that will result in proper branch.  Return UNKNOWN if no such code
   16737                 :             :    is available.  */
   16738                 :             : 
   16739                 :             : enum rtx_code
   16740                 :      556093 : ix86_fp_compare_code_to_integer (enum rtx_code code)
   16741                 :             : {
   16742                 :      556093 :   switch (code)
   16743                 :             :     {
   16744                 :             :     case GT:
   16745                 :             :       return GTU;
   16746                 :       13641 :     case GE:
   16747                 :       13641 :       return GEU;
   16748                 :      234221 :     case ORDERED:
   16749                 :      234221 :     case UNORDERED:
   16750                 :      234221 :       return code;
   16751                 :      117677 :     case UNEQ:
   16752                 :      117677 :       return EQ;
   16753                 :       15625 :     case UNLT:
   16754                 :       15625 :       return LTU;
   16755                 :       31915 :     case UNLE:
   16756                 :       31915 :       return LEU;
   16757                 :      109958 :     case LTGT:
   16758                 :      109958 :       return NE;
   16759                 :         173 :     default:
   16760                 :         173 :       return UNKNOWN;
   16761                 :             :     }
   16762                 :             : }
   16763                 :             : 
   16764                 :             : /* Zero extend possibly SImode EXP to Pmode register.  */
   16765                 :             : rtx
   16766                 :       63018 : ix86_zero_extend_to_Pmode (rtx exp)
   16767                 :             : {
   16768                 :       63018 :   return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
   16769                 :             : }
   16770                 :             : 
   16771                 :             : /* Return true if the function is called via PLT.   */
   16772                 :             : 
   16773                 :             : bool
   16774                 :      959256 : ix86_call_use_plt_p (rtx call_op)
   16775                 :             : {
   16776                 :      959256 :   if (SYMBOL_REF_LOCAL_P (call_op))
   16777                 :             :     {
   16778                 :      184688 :       if (SYMBOL_REF_DECL (call_op)
   16779                 :      184688 :           && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
   16780                 :             :         {
   16781                 :             :           /* NB: All ifunc functions must be called via PLT.  */
   16782                 :      101582 :           cgraph_node *node
   16783                 :      101582 :             = cgraph_node::get (SYMBOL_REF_DECL (call_op));
   16784                 :      101582 :           if (node && node->ifunc_resolver)
   16785                 :             :             return true;
   16786                 :             :         }
   16787                 :      184662 :       return false;
   16788                 :             :     }
   16789                 :             :   return true;
   16790                 :             : }
   16791                 :             : 
   16792                 :             : /* Implement TARGET_IFUNC_REF_LOCAL_OK.  If this hook returns true,
   16793                 :             :    the PLT entry will be used as the function address for local IFUNC
   16794                 :             :    functions.  When the PIC register is needed for PLT call, indirect
   16795                 :             :    call via the PLT entry will fail since the PIC register may not be
   16796                 :             :    set up properly for indirect call.  In this case, we should return
   16797                 :             :    false.  */
   16798                 :             : 
   16799                 :             : static bool
   16800                 :   636884010 : ix86_ifunc_ref_local_ok (void)
   16801                 :             : {
   16802                 :   636884010 :   return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
   16803                 :             : }
   16804                 :             : 
   16805                 :             : /* Return true if the function being called was marked with attribute
   16806                 :             :    "noplt" or using -fno-plt and we are compiling for non-PIC.  We need
   16807                 :             :    to handle the non-PIC case in the backend because there is no easy
   16808                 :             :    interface for the front-end to force non-PLT calls to use the GOT.
   16809                 :             :    This is currently used only with 64-bit or 32-bit GOT32X ELF targets
   16810                 :             :    to call the function marked "noplt" indirectly.  */
   16811                 :             : 
   16812                 :             : static bool
   16813                 :     5539839 : ix86_nopic_noplt_attribute_p (rtx call_op)
   16814                 :             : {
   16815                 :     5066265 :   if (flag_pic || ix86_cmodel == CM_LARGE
   16816                 :             :       || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
   16817                 :             :       || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
   16818                 :    10606104 :       || SYMBOL_REF_LOCAL_P (call_op))
   16819                 :             :     return false;
   16820                 :             : 
   16821                 :     3556336 :   tree symbol_decl = SYMBOL_REF_DECL (call_op);
   16822                 :             : 
   16823                 :     3556336 :   if (!flag_plt
   16824                 :     3556336 :       || (symbol_decl != NULL_TREE
   16825                 :     3556328 :           && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
   16826                 :          10 :     return true;
   16827                 :             : 
   16828                 :             :   return false;
   16829                 :             : }
   16830                 :             : 
   16831                 :             : /* Helper to output the jmp/call.  */
   16832                 :             : static void
   16833                 :          33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
   16834                 :             : {
   16835                 :          33 :   if (thunk_name != NULL)
   16836                 :             :     {
   16837                 :          22 :       if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   16838                 :           1 :           && ix86_indirect_branch_cs_prefix)
   16839                 :           1 :         fprintf (asm_out_file, "\tcs\n");
   16840                 :          22 :       fprintf (asm_out_file, "\tjmp\t");
   16841                 :          22 :       assemble_name (asm_out_file, thunk_name);
   16842                 :          22 :       putc ('\n', asm_out_file);
   16843                 :          22 :       if ((ix86_harden_sls & harden_sls_indirect_jmp))
   16844                 :           2 :         fputs ("\tint3\n", asm_out_file);
   16845                 :             :     }
   16846                 :             :   else
   16847                 :          11 :     output_indirect_thunk (regno);
   16848                 :          33 : }
   16849                 :             : 
   16850                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is a
   16851                 :             :    register which contains the branch target.  XASM is the assembly
   16852                 :             :    template for CALL_OP.  Branch is a tail call if SIBCALL_P is true.
   16853                 :             :    A normal call is converted to:
   16854                 :             : 
   16855                 :             :         call __x86_indirect_thunk_reg
   16856                 :             : 
   16857                 :             :    and a tail call is converted to:
   16858                 :             : 
   16859                 :             :         jmp __x86_indirect_thunk_reg
   16860                 :             :  */
   16861                 :             : 
   16862                 :             : static void
   16863                 :          50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
   16864                 :             : {
   16865                 :          50 :   char thunk_name_buf[32];
   16866                 :          50 :   char *thunk_name;
   16867                 :          50 :   enum indirect_thunk_prefix need_prefix
   16868                 :          50 :     = indirect_thunk_need_prefix (current_output_insn);
   16869                 :          50 :   int regno = REGNO (call_op);
   16870                 :             : 
   16871                 :          50 :   if (cfun->machine->indirect_branch_type
   16872                 :          50 :       != indirect_branch_thunk_inline)
   16873                 :             :     {
   16874                 :          39 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   16875                 :          16 :         SET_HARD_REG_BIT (indirect_thunks_used, regno);
   16876                 :             : 
   16877                 :          39 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   16878                 :          39 :       thunk_name = thunk_name_buf;
   16879                 :             :     }
   16880                 :             :   else
   16881                 :             :     thunk_name = NULL;
   16882                 :             : 
   16883                 :          50 :   if (sibcall_p)
   16884                 :          27 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16885                 :             :   else
   16886                 :             :     {
   16887                 :          23 :       if (thunk_name != NULL)
   16888                 :             :         {
   16889                 :          17 :           if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
   16890                 :           1 :               && ix86_indirect_branch_cs_prefix)
   16891                 :           1 :             fprintf (asm_out_file, "\tcs\n");
   16892                 :          17 :           fprintf (asm_out_file, "\tcall\t");
   16893                 :          17 :           assemble_name (asm_out_file, thunk_name);
   16894                 :          17 :           putc ('\n', asm_out_file);
   16895                 :          17 :           return;
   16896                 :             :         }
   16897                 :             : 
   16898                 :           6 :       char indirectlabel1[32];
   16899                 :           6 :       char indirectlabel2[32];
   16900                 :             : 
   16901                 :           6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   16902                 :             :                                    INDIRECT_LABEL,
   16903                 :             :                                    indirectlabelno++);
   16904                 :           6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   16905                 :             :                                    INDIRECT_LABEL,
   16906                 :             :                                    indirectlabelno++);
   16907                 :             : 
   16908                 :             :       /* Jump.  */
   16909                 :           6 :       fputs ("\tjmp\t", asm_out_file);
   16910                 :           6 :       assemble_name_raw (asm_out_file, indirectlabel2);
   16911                 :           6 :       fputc ('\n', asm_out_file);
   16912                 :             : 
   16913                 :           6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   16914                 :             : 
   16915                 :           6 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16916                 :             : 
   16917                 :           6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   16918                 :             : 
   16919                 :             :       /* Call.  */
   16920                 :           6 :       fputs ("\tcall\t", asm_out_file);
   16921                 :           6 :       assemble_name_raw (asm_out_file, indirectlabel1);
   16922                 :           6 :       fputc ('\n', asm_out_file);
   16923                 :             :     }
   16924                 :             : }
   16925                 :             : 
   16926                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is
   16927                 :             :    the branch target.  XASM is the assembly template for CALL_OP.
   16928                 :             :    Branch is a tail call if SIBCALL_P is true.  A normal call is
   16929                 :             :    converted to:
   16930                 :             : 
   16931                 :             :         jmp L2
   16932                 :             :    L1:
   16933                 :             :         push CALL_OP
   16934                 :             :         jmp __x86_indirect_thunk
   16935                 :             :    L2:
   16936                 :             :         call L1
   16937                 :             : 
   16938                 :             :    and a tail call is converted to:
   16939                 :             : 
   16940                 :             :         push CALL_OP
   16941                 :             :         jmp __x86_indirect_thunk
   16942                 :             :  */
   16943                 :             : 
   16944                 :             : static void
   16945                 :           0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
   16946                 :             :                                       bool sibcall_p)
   16947                 :             : {
   16948                 :           0 :   char thunk_name_buf[32];
   16949                 :           0 :   char *thunk_name;
   16950                 :           0 :   char push_buf[64];
   16951                 :           0 :   enum indirect_thunk_prefix need_prefix
   16952                 :           0 :     = indirect_thunk_need_prefix (current_output_insn);
   16953                 :           0 :   int regno = -1;
   16954                 :             : 
   16955                 :           0 :   if (cfun->machine->indirect_branch_type
   16956                 :           0 :       != indirect_branch_thunk_inline)
   16957                 :             :     {
   16958                 :           0 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   16959                 :           0 :         indirect_thunk_needed = true;
   16960                 :           0 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   16961                 :           0 :       thunk_name = thunk_name_buf;
   16962                 :             :     }
   16963                 :             :   else
   16964                 :             :     thunk_name = NULL;
   16965                 :             : 
   16966                 :           0 :   snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
   16967                 :           0 :             TARGET_64BIT ? 'q' : 'l', xasm);
   16968                 :             : 
   16969                 :           0 :   if (sibcall_p)
   16970                 :             :     {
   16971                 :           0 :       output_asm_insn (push_buf, &call_op);
   16972                 :           0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   16973                 :             :     }
   16974                 :             :   else
   16975                 :             :     {
   16976                 :           0 :       char indirectlabel1[32];
   16977                 :           0 :       char indirectlabel2[32];
   16978                 :             : 
   16979                 :           0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   16980                 :             :                                    INDIRECT_LABEL,
   16981                 :             :                                    indirectlabelno++);
   16982                 :           0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   16983                 :             :                                    INDIRECT_LABEL,
   16984                 :             :                                    indirectlabelno++);
   16985                 :             : 
   16986                 :             :       /* Jump.  */
   16987                 :           0 :       fputs ("\tjmp\t", asm_out_file);
   16988                 :           0 :       assemble_name_raw (asm_out_file, indirectlabel2);
   16989                 :           0 :       fputc ('\n', asm_out_file);
   16990                 :             : 
   16991                 :           0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   16992                 :             : 
   16993                 :             :       /* An external function may be called via GOT, instead of PLT.  */
   16994                 :           0 :       if (MEM_P (call_op))
   16995                 :             :         {
   16996                 :           0 :           struct ix86_address parts;
   16997                 :           0 :           rtx addr = XEXP (call_op, 0);
   16998                 :           0 :           if (ix86_decompose_address (addr, &parts)
   16999                 :           0 :               && parts.base == stack_pointer_rtx)
   17000                 :             :             {
   17001                 :             :               /* Since call will adjust stack by -UNITS_PER_WORD,
   17002                 :             :                  we must convert "disp(stack, index, scale)" to
   17003                 :             :                  "disp+UNITS_PER_WORD(stack, index, scale)".  */
   17004                 :           0 :               if (parts.index)
   17005                 :             :                 {
   17006                 :           0 :                   addr = gen_rtx_MULT (Pmode, parts.index,
   17007                 :             :                                        GEN_INT (parts.scale));
   17008                 :           0 :                   addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   17009                 :             :                                        addr);
   17010                 :             :                 }
   17011                 :             :               else
   17012                 :             :                 addr = stack_pointer_rtx;
   17013                 :             : 
   17014                 :           0 :               rtx disp;
   17015                 :           0 :               if (parts.disp != NULL_RTX)
   17016                 :           0 :                 disp = plus_constant (Pmode, parts.disp,
   17017                 :           0 :                                       UNITS_PER_WORD);
   17018                 :             :               else
   17019                 :           0 :                 disp = GEN_INT (UNITS_PER_WORD);
   17020                 :             : 
   17021                 :           0 :               addr = gen_rtx_PLUS (Pmode, addr, disp);
   17022                 :           0 :               call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
   17023                 :             :             }
   17024                 :             :         }
   17025                 :             : 
   17026                 :           0 :       output_asm_insn (push_buf, &call_op);
   17027                 :             : 
   17028                 :           0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17029                 :             : 
   17030                 :           0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   17031                 :             : 
   17032                 :             :       /* Call.  */
   17033                 :           0 :       fputs ("\tcall\t", asm_out_file);
   17034                 :           0 :       assemble_name_raw (asm_out_file, indirectlabel1);
   17035                 :           0 :       fputc ('\n', asm_out_file);
   17036                 :             :     }
   17037                 :           0 : }
   17038                 :             : 
   17039                 :             : /* Output indirect branch via a call and return thunk.  CALL_OP is
   17040                 :             :    the branch target.  XASM is the assembly template for CALL_OP.
   17041                 :             :    Branch is a tail call if SIBCALL_P is true.   */
   17042                 :             : 
   17043                 :             : static void
   17044                 :          50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
   17045                 :             :                              bool sibcall_p)
   17046                 :             : {
   17047                 :          50 :   if (REG_P (call_op))
   17048                 :          50 :     ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
   17049                 :             :   else
   17050                 :           0 :     ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
   17051                 :          50 : }
   17052                 :             : 
   17053                 :             : /* Output indirect jump.  CALL_OP is the jump target.  */
   17054                 :             : 
   17055                 :             : const char *
   17056                 :       17683 : ix86_output_indirect_jmp (rtx call_op)
   17057                 :             : {
   17058                 :       17683 :   if (cfun->machine->indirect_branch_type != indirect_branch_keep)
   17059                 :             :     {
   17060                 :             :       /* We can't have red-zone since "call" in the indirect thunk
   17061                 :             :          pushes the return address onto stack, destroying red-zone.  */
   17062                 :           4 :       if (ix86_red_zone_used)
   17063                 :           0 :         gcc_unreachable ();
   17064                 :             : 
   17065                 :           4 :       ix86_output_indirect_branch (call_op, "%0", true);
   17066                 :             :     }
   17067                 :             :   else
   17068                 :       17679 :     output_asm_insn ("%!jmp\t%A0", &call_op);
   17069                 :       17683 :   return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
   17070                 :             : }
   17071                 :             : 
   17072                 :             : /* Output return instrumentation for current function if needed.  */
   17073                 :             : 
   17074                 :             : static void
   17075                 :     1609924 : output_return_instrumentation (void)
   17076                 :             : {
   17077                 :     1609924 :   if (ix86_instrument_return != instrument_return_none
   17078                 :           6 :       && flag_fentry
   17079                 :     1609930 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
   17080                 :             :     {
   17081                 :           5 :       if (ix86_flag_record_return)
   17082                 :           5 :         fprintf (asm_out_file, "1:\n");
   17083                 :           5 :       switch (ix86_instrument_return)
   17084                 :             :         {
   17085                 :           2 :         case instrument_return_call:
   17086                 :           2 :           fprintf (asm_out_file, "\tcall\t__return__\n");
   17087                 :           2 :           break;
   17088                 :           3 :         case instrument_return_nop5:
   17089                 :             :           /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1)  */
   17090                 :           3 :           fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   17091                 :           3 :           break;
   17092                 :             :         case instrument_return_none:
   17093                 :             :           break;
   17094                 :             :         }
   17095                 :             : 
   17096                 :           5 :       if (ix86_flag_record_return)
   17097                 :             :         {
   17098                 :           5 :           fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
   17099                 :           5 :           fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   17100                 :           5 :           fprintf (asm_out_file, "\t.previous\n");
   17101                 :             :         }
   17102                 :             :     }
   17103                 :     1609924 : }
   17104                 :             : 
   17105                 :             : /* Output function return.  CALL_OP is the jump target.  Add a REP
   17106                 :             :    prefix to RET if LONG_P is true and function return is kept.  */
   17107                 :             : 
   17108                 :             : const char *
   17109                 :     1496141 : ix86_output_function_return (bool long_p)
   17110                 :             : {
   17111                 :     1496141 :   output_return_instrumentation ();
   17112                 :             : 
   17113                 :     1496141 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17114                 :             :     {
   17115                 :          17 :       char thunk_name[32];
   17116                 :          17 :       enum indirect_thunk_prefix need_prefix
   17117                 :          17 :         = indirect_thunk_need_prefix (current_output_insn);
   17118                 :             : 
   17119                 :          17 :       if (cfun->machine->function_return_type
   17120                 :          17 :           != indirect_branch_thunk_inline)
   17121                 :             :         {
   17122                 :          12 :           bool need_thunk = (cfun->machine->function_return_type
   17123                 :             :                              == indirect_branch_thunk);
   17124                 :          12 :           indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
   17125                 :             :                                true);
   17126                 :          12 :           indirect_return_needed |= need_thunk;
   17127                 :          12 :           fprintf (asm_out_file, "\tjmp\t");
   17128                 :          12 :           assemble_name (asm_out_file, thunk_name);
   17129                 :          12 :           putc ('\n', asm_out_file);
   17130                 :             :         }
   17131                 :             :       else
   17132                 :           5 :         output_indirect_thunk (INVALID_REGNUM);
   17133                 :             : 
   17134                 :          17 :       return "";
   17135                 :             :     }
   17136                 :             : 
   17137                 :     2991696 :   output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
   17138                 :     1496124 :   return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
   17139                 :             : }
   17140                 :             : 
   17141                 :             : /* Output indirect function return.  RET_OP is the function return
   17142                 :             :    target.  */
   17143                 :             : 
   17144                 :             : const char *
   17145                 :          17 : ix86_output_indirect_function_return (rtx ret_op)
   17146                 :             : {
   17147                 :          17 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17148                 :             :     {
   17149                 :           0 :       char thunk_name[32];
   17150                 :           0 :       enum indirect_thunk_prefix need_prefix
   17151                 :           0 :         = indirect_thunk_need_prefix (current_output_insn);
   17152                 :           0 :       unsigned int regno = REGNO (ret_op);
   17153                 :           0 :       gcc_assert (regno == CX_REG);
   17154                 :             : 
   17155                 :           0 :       if (cfun->machine->function_return_type
   17156                 :           0 :           != indirect_branch_thunk_inline)
   17157                 :             :         {
   17158                 :           0 :           bool need_thunk = (cfun->machine->function_return_type
   17159                 :             :                              == indirect_branch_thunk);
   17160                 :           0 :           indirect_thunk_name (thunk_name, regno, need_prefix, true);
   17161                 :             : 
   17162                 :           0 :           if (need_thunk)
   17163                 :             :             {
   17164                 :           0 :               indirect_return_via_cx = true;
   17165                 :           0 :               SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
   17166                 :             :             }
   17167                 :           0 :           fprintf (asm_out_file, "\tjmp\t");
   17168                 :           0 :           assemble_name (asm_out_file, thunk_name);
   17169                 :           0 :           putc ('\n', asm_out_file);
   17170                 :             :         }
   17171                 :             :       else
   17172                 :           0 :         output_indirect_thunk (regno);
   17173                 :             :     }
   17174                 :             :   else
   17175                 :             :     {
   17176                 :          17 :       output_asm_insn ("%!jmp\t%A0", &ret_op);
   17177                 :          17 :       if (ix86_harden_sls & harden_sls_indirect_jmp)
   17178                 :           1 :         fputs ("\tint3\n", asm_out_file);
   17179                 :             :     }
   17180                 :          17 :   return "";
   17181                 :             : }
   17182                 :             : 
   17183                 :             : /* Output the assembly for a call instruction.  */
   17184                 :             : 
   17185                 :             : const char *
   17186                 :     5716752 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
   17187                 :             : {
   17188                 :     5716752 :   bool direct_p = constant_call_address_operand (call_op, VOIDmode);
   17189                 :     5716752 :   bool output_indirect_p
   17190                 :             :     = (!TARGET_SEH
   17191                 :     5716752 :        && cfun->machine->indirect_branch_type != indirect_branch_keep);
   17192                 :     5716752 :   bool seh_nop_p = false;
   17193                 :     5716752 :   const char *xasm;
   17194                 :             : 
   17195                 :     5716752 :   if (SIBLING_CALL_P (insn))
   17196                 :             :     {
   17197                 :      113783 :       output_return_instrumentation ();
   17198                 :      113783 :       if (direct_p)
   17199                 :             :         {
   17200                 :      105139 :           if (ix86_nopic_noplt_attribute_p (call_op))
   17201                 :             :             {
   17202                 :           4 :               direct_p = false;
   17203                 :           4 :               if (TARGET_64BIT)
   17204                 :             :                 {
   17205                 :           4 :                   if (output_indirect_p)
   17206                 :             :                     xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17207                 :             :                   else
   17208                 :           4 :                     xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17209                 :             :                 }
   17210                 :             :               else
   17211                 :             :                 {
   17212                 :           0 :                   if (output_indirect_p)
   17213                 :             :                     xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17214                 :             :                   else
   17215                 :           0 :                     xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17216                 :             :                 }
   17217                 :             :             }
   17218                 :             :           else
   17219                 :             :             xasm = "%!jmp\t%P0";
   17220                 :             :         }
   17221                 :             :       /* SEH epilogue detection requires the indirect branch case
   17222                 :             :          to include REX.W.  */
   17223                 :        8644 :       else if (TARGET_SEH)
   17224                 :             :         xasm = "%!rex.W jmp\t%A0";
   17225                 :             :       else
   17226                 :             :         {
   17227                 :        8644 :           if (output_indirect_p)
   17228                 :             :             xasm = "%0";
   17229                 :             :           else
   17230                 :        8621 :             xasm = "%!jmp\t%A0";
   17231                 :             :         }
   17232                 :             : 
   17233                 :      113783 :       if (output_indirect_p && !direct_p)
   17234                 :          23 :         ix86_output_indirect_branch (call_op, xasm, true);
   17235                 :             :       else
   17236                 :             :         {
   17237                 :      113760 :           output_asm_insn (xasm, &call_op);
   17238                 :      113760 :           if (!direct_p
   17239                 :        8625 :               && (ix86_harden_sls & harden_sls_indirect_jmp))
   17240                 :             :             return "int3";
   17241                 :             :         }
   17242                 :      113782 :       return "";
   17243                 :             :     }
   17244                 :             : 
   17245                 :             :   /* SEH unwinding can require an extra nop to be emitted in several
   17246                 :             :      circumstances.  Determine if we have one of those.  */
   17247                 :     5602969 :   if (TARGET_SEH)
   17248                 :             :     {
   17249                 :             :       rtx_insn *i;
   17250                 :             : 
   17251                 :             :       for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
   17252                 :             :         {
   17253                 :             :           /* Prevent a catch region from being adjacent to a jump that would
   17254                 :             :              be interpreted as an epilogue sequence by the unwinder.  */
   17255                 :             :           if (JUMP_P(i) && CROSSING_JUMP_P (i))
   17256                 :             :             {
   17257                 :             :               seh_nop_p = true;
   17258                 :             :               break;
   17259                 :             :             }
   17260                 :             :             
   17261                 :             :           /* If we get to another real insn, we don't need the nop.  */
   17262                 :             :           if (INSN_P (i))
   17263                 :             :             break;
   17264                 :             : 
   17265                 :             :           /* If we get to the epilogue note, prevent a catch region from
   17266                 :             :              being adjacent to the standard epilogue sequence.  Note that,
   17267                 :             :              if non-call exceptions are enabled, we already did it during
   17268                 :             :              epilogue expansion, or else, if the insn can throw internally,
   17269                 :             :              we already did it during the reorg pass.  */
   17270                 :             :           if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
   17271                 :             :               && !flag_non_call_exceptions
   17272                 :             :               && !can_throw_internal (insn))
   17273                 :             :             {
   17274                 :             :               seh_nop_p = true;
   17275                 :             :               break;
   17276                 :             :             }
   17277                 :             :         }
   17278                 :             : 
   17279                 :             :       /* If we didn't find a real insn following the call, prevent the
   17280                 :             :          unwinder from looking into the next function.  */
   17281                 :             :       if (i == NULL)
   17282                 :             :         seh_nop_p = true;
   17283                 :             :     }
   17284                 :             : 
   17285                 :     5602969 :   if (direct_p)
   17286                 :             :     {
   17287                 :     5434700 :       if (ix86_nopic_noplt_attribute_p (call_op))
   17288                 :             :         {
   17289                 :           6 :           direct_p = false;
   17290                 :           6 :           if (TARGET_64BIT)
   17291                 :             :             {
   17292                 :           6 :               if (output_indirect_p)
   17293                 :             :                 xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17294                 :             :               else
   17295                 :           6 :                 xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17296                 :             :             }
   17297                 :             :           else
   17298                 :             :             {
   17299                 :           0 :               if (output_indirect_p)
   17300                 :             :                 xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17301                 :             :               else
   17302                 :           0 :                 xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17303                 :             :             }
   17304                 :             :         }
   17305                 :             :       else
   17306                 :             :         xasm = "%!call\t%P0";
   17307                 :             :     }
   17308                 :             :   else
   17309                 :             :     {
   17310                 :      168269 :       if (output_indirect_p)
   17311                 :             :         xasm = "%0";
   17312                 :             :       else
   17313                 :      168246 :         xasm = "%!call\t%A0";
   17314                 :             :     }
   17315                 :             : 
   17316                 :     5602969 :   if (output_indirect_p && !direct_p)
   17317                 :          23 :     ix86_output_indirect_branch (call_op, xasm, false);
   17318                 :             :   else
   17319                 :     5602946 :     output_asm_insn (xasm, &call_op);
   17320                 :             : 
   17321                 :             :   if (seh_nop_p)
   17322                 :             :     return "nop";
   17323                 :             : 
   17324                 :             :   return "";
   17325                 :             : }
   17326                 :             : 
   17327                 :             : /* Return a MEM corresponding to a stack slot with mode MODE.
   17328                 :             :    Allocate a new slot if necessary.
   17329                 :             : 
   17330                 :             :    The RTL for a function can have several slots available: N is
   17331                 :             :    which slot to use.  */
   17332                 :             : 
   17333                 :             : rtx
   17334                 :       60939 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
   17335                 :             : {
   17336                 :       60939 :   struct stack_local_entry *s;
   17337                 :             : 
   17338                 :       60939 :   gcc_assert (n < MAX_386_STACK_LOCALS);
   17339                 :             : 
   17340                 :       72847 :   for (s = ix86_stack_locals; s; s = s->next)
   17341                 :       67869 :     if (s->mode == mode && s->n == n)
   17342                 :       55961 :       return validize_mem (copy_rtx (s->rtl));
   17343                 :             : 
   17344                 :        4978 :   int align = 0;
   17345                 :             :   /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
   17346                 :             :      alignment with -m32 -mpreferred-stack-boundary=2.  */
   17347                 :        4978 :   if (mode == DImode
   17348                 :         523 :       && !TARGET_64BIT
   17349                 :         523 :       && n == SLOT_FLOATxFDI_387
   17350                 :        5326 :       && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
   17351                 :             :     align = 32;
   17352                 :        4978 :   s = ggc_alloc<stack_local_entry> ();
   17353                 :        4978 :   s->n = n;
   17354                 :        4978 :   s->mode = mode;
   17355                 :        9956 :   s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
   17356                 :             : 
   17357                 :        4978 :   s->next = ix86_stack_locals;
   17358                 :        4978 :   ix86_stack_locals = s;
   17359                 :        4978 :   return validize_mem (copy_rtx (s->rtl));
   17360                 :             : }
   17361                 :             : 
   17362                 :             : static void
   17363                 :     1392354 : ix86_instantiate_decls (void)
   17364                 :             : {
   17365                 :     1392354 :   struct stack_local_entry *s;
   17366                 :             : 
   17367                 :     1394548 :   for (s = ix86_stack_locals; s; s = s->next)
   17368                 :        2194 :     if (s->rtl != NULL_RTX)
   17369                 :        2194 :       instantiate_decl_rtl (s->rtl);
   17370                 :     1392354 : }
   17371                 :             : 
   17372                 :             : /* Check whether x86 address PARTS is a pc-relative address.  */
   17373                 :             : 
   17374                 :             : bool
   17375                 :    21769146 : ix86_rip_relative_addr_p (struct ix86_address *parts)
   17376                 :             : {
   17377                 :    21769146 :   rtx base, index, disp;
   17378                 :             : 
   17379                 :    21769146 :   base = parts->base;
   17380                 :    21769146 :   index = parts->index;
   17381                 :    21769146 :   disp = parts->disp;
   17382                 :             : 
   17383                 :    21769146 :   if (disp && !base && !index)
   17384                 :             :     {
   17385                 :    21545133 :       if (TARGET_64BIT)
   17386                 :             :         {
   17387                 :    20052246 :           rtx symbol = disp;
   17388                 :             : 
   17389                 :    20052246 :           if (GET_CODE (disp) == CONST)
   17390                 :     5673458 :             symbol = XEXP (disp, 0);
   17391                 :    20052246 :           if (GET_CODE (symbol) == PLUS
   17392                 :     5228879 :               && CONST_INT_P (XEXP (symbol, 1)))
   17393                 :     5228879 :             symbol = XEXP (symbol, 0);
   17394                 :             : 
   17395                 :    20052246 :           if (GET_CODE (symbol) == LABEL_REF
   17396                 :    20044961 :               || (GET_CODE (symbol) == SYMBOL_REF
   17397                 :    18996549 :                   && SYMBOL_REF_TLS_MODEL (symbol) == 0)
   17398                 :    21100658 :               || (GET_CODE (symbol) == UNSPEC
   17399                 :      462623 :                   && (XINT (symbol, 1) == UNSPEC_GOTPCREL
   17400                 :             :                       || XINT (symbol, 1) == UNSPEC_PCREL
   17401                 :             :                       || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
   17402                 :    19441837 :             return true;
   17403                 :             :         }
   17404                 :             :     }
   17405                 :             :   return false;
   17406                 :             : }
   17407                 :             : 
   17408                 :             : /* Calculate the length of the memory address in the instruction encoding.
   17409                 :             :    Includes addr32 prefix, does not include the one-byte modrm, opcode,
   17410                 :             :    or other prefixes.  We never generate addr32 prefix for LEA insn.  */
   17411                 :             : 
   17412                 :             : int
   17413                 :   222341895 : memory_address_length (rtx addr, bool lea)
   17414                 :             : {
   17415                 :   222341895 :   struct ix86_address parts;
   17416                 :   222341895 :   rtx base, index, disp;
   17417                 :   222341895 :   int len;
   17418                 :   222341895 :   int ok;
   17419                 :             : 
   17420                 :   222341895 :   if (GET_CODE (addr) == PRE_DEC
   17421                 :   213304195 :       || GET_CODE (addr) == POST_INC
   17422                 :   207573913 :       || GET_CODE (addr) == PRE_MODIFY
   17423                 :   207573913 :       || GET_CODE (addr) == POST_MODIFY)
   17424                 :             :     return 0;
   17425                 :             : 
   17426                 :   207573913 :   ok = ix86_decompose_address (addr, &parts);
   17427                 :   207573913 :   gcc_assert (ok);
   17428                 :             : 
   17429                 :   207573913 :   len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
   17430                 :             : 
   17431                 :             :   /*  If this is not LEA instruction, add the length of addr32 prefix.  */
   17432                 :   170518119 :   if (TARGET_64BIT && !lea
   17433                 :   360321107 :       && (SImode_address_operand (addr, VOIDmode)
   17434                 :   152747116 :           || (parts.base && GET_MODE (parts.base) == SImode)
   17435                 :   152746893 :           || (parts.index && GET_MODE (parts.index) == SImode)))
   17436                 :         301 :     len++;
   17437                 :             : 
   17438                 :   207573913 :   base = parts.base;
   17439                 :   207573913 :   index = parts.index;
   17440                 :   207573913 :   disp = parts.disp;
   17441                 :             : 
   17442                 :   207573913 :   if (base && SUBREG_P (base))
   17443                 :           2 :     base = SUBREG_REG (base);
   17444                 :   207573913 :   if (index && SUBREG_P (index))
   17445                 :           0 :     index = SUBREG_REG (index);
   17446                 :             : 
   17447                 :   207573913 :   gcc_assert (base == NULL_RTX || REG_P (base));
   17448                 :   207573913 :   gcc_assert (index == NULL_RTX || REG_P (index));
   17449                 :             : 
   17450                 :             :   /* Rule of thumb:
   17451                 :             :        - esp as the base always wants an index,
   17452                 :             :        - ebp as the base always wants a displacement,
   17453                 :             :        - r12 as the base always wants an index,
   17454                 :             :        - r13 as the base always wants a displacement.  */
   17455                 :             : 
   17456                 :             :   /* Register Indirect.  */
   17457                 :   207573913 :   if (base && !index && !disp)
   17458                 :             :     {
   17459                 :             :       /* esp (for its index) and ebp (for its displacement) need
   17460                 :             :          the two-byte modrm form.  Similarly for r12 and r13 in 64-bit
   17461                 :             :          code.  */
   17462                 :    13301199 :       if (base == arg_pointer_rtx
   17463                 :    13301199 :           || base == frame_pointer_rtx
   17464                 :    13301199 :           || REGNO (base) == SP_REG
   17465                 :     8962923 :           || REGNO (base) == BP_REG
   17466                 :     8962923 :           || REGNO (base) == R12_REG
   17467                 :    21846365 :           || REGNO (base) == R13_REG)
   17468                 :     4756033 :         len++;
   17469                 :             :     }
   17470                 :             : 
   17471                 :             :   /* Direct Addressing.  In 64-bit mode mod 00 r/m 5
   17472                 :             :      is not disp32, but disp32(%rip), so for disp32
   17473                 :             :      SIB byte is needed, unless print_operand_address
   17474                 :             :      optimizes it into disp32(%rip) or (%rip) is implied
   17475                 :             :      by UNSPEC.  */
   17476                 :   194272714 :   else if (disp && !base && !index)
   17477                 :             :     {
   17478                 :    21288577 :       len += 4;
   17479                 :    21288577 :       if (!ix86_rip_relative_addr_p (&parts))
   17480                 :     1864299 :         len++;
   17481                 :             :     }
   17482                 :             :   else
   17483                 :             :     {
   17484                 :             :       /* Find the length of the displacement constant.  */
   17485                 :   172984137 :       if (disp)
   17486                 :             :         {
   17487                 :   169417494 :           if (base && satisfies_constraint_K (disp))
   17488                 :    94093150 :             len += 1;
   17489                 :             :           else
   17490                 :    75324344 :             len += 4;
   17491                 :             :         }
   17492                 :             :       /* ebp always wants a displacement.  Similarly r13.  */
   17493                 :     3566643 :       else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
   17494                 :        5817 :         len++;
   17495                 :             : 
   17496                 :             :       /* An index requires the two-byte modrm form....  */
   17497                 :   172984137 :       if (index
   17498                 :             :           /* ...like esp (or r12), which always wants an index.  */
   17499                 :   165078397 :           || base == arg_pointer_rtx
   17500                 :   165078397 :           || base == frame_pointer_rtx
   17501                 :   338062534 :           || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
   17502                 :   118446588 :         len++;
   17503                 :             :     }
   17504                 :             : 
   17505                 :             :   return len;
   17506                 :             : }
   17507                 :             : 
   17508                 :             : /* Compute default value for "length_immediate" attribute.  When SHORTFORM
   17509                 :             :    is set, expect that insn have 8bit immediate alternative.  */
   17510                 :             : int
   17511                 :   266460138 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
   17512                 :             : {
   17513                 :   266460138 :   int len = 0;
   17514                 :   266460138 :   int i;
   17515                 :   266460138 :   extract_insn_cached (insn);
   17516                 :   832632327 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17517                 :   566172189 :     if (CONSTANT_P (recog_data.operand[i]))
   17518                 :             :       {
   17519                 :   116208646 :         enum attr_mode mode = get_attr_mode (insn);
   17520                 :             : 
   17521                 :   116208646 :         gcc_assert (!len);
   17522                 :   116208646 :         if (shortform && CONST_INT_P (recog_data.operand[i]))
   17523                 :             :           {
   17524                 :    30220760 :             HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
   17525                 :    30220760 :             switch (mode)
   17526                 :             :               {
   17527                 :      781143 :               case MODE_QI:
   17528                 :      781143 :                 len = 1;
   17529                 :      781143 :                 continue;
   17530                 :      305945 :               case MODE_HI:
   17531                 :      305945 :                 ival = trunc_int_for_mode (ival, HImode);
   17532                 :      305945 :                 break;
   17533                 :    13638247 :               case MODE_SI:
   17534                 :    13638247 :                 ival = trunc_int_for_mode (ival, SImode);
   17535                 :    13638247 :                 break;
   17536                 :             :               default:
   17537                 :             :                 break;
   17538                 :             :               }
   17539                 :    29439617 :             if (IN_RANGE (ival, -128, 127))
   17540                 :             :               {
   17541                 :    26253029 :                 len = 1;
   17542                 :    26253029 :                 continue;
   17543                 :             :               }
   17544                 :             :           }
   17545                 :    89174474 :         switch (mode)
   17546                 :             :           {
   17547                 :             :           case MODE_QI:
   17548                 :             :             len = 1;
   17549                 :             :             break;
   17550                 :             :           case MODE_HI:
   17551                 :   566172189 :             len = 2;
   17552                 :             :             break;
   17553                 :             :           case MODE_SI:
   17554                 :    84740031 :             len = 4;
   17555                 :             :             break;
   17556                 :             :           /* Immediates for DImode instructions are encoded
   17557                 :             :              as 32bit sign extended values.  */
   17558                 :             :           case MODE_DI:
   17559                 :    84740031 :             len = 4;
   17560                 :             :             break;
   17561                 :           0 :           default:
   17562                 :           0 :             fatal_insn ("unknown insn mode", insn);
   17563                 :             :         }
   17564                 :             :       }
   17565                 :   266460138 :   return len;
   17566                 :             : }
   17567                 :             : 
   17568                 :             : /* Compute default value for "length_address" attribute.  */
   17569                 :             : int
   17570                 :   376998324 : ix86_attr_length_address_default (rtx_insn *insn)
   17571                 :             : {
   17572                 :   376998324 :   int i;
   17573                 :             : 
   17574                 :   376998324 :   if (get_attr_type (insn) == TYPE_LEA)
   17575                 :             :     {
   17576                 :    20365390 :       rtx set = PATTERN (insn), addr;
   17577                 :             : 
   17578                 :    20365390 :       if (GET_CODE (set) == PARALLEL)
   17579                 :       87218 :         set = XVECEXP (set, 0, 0);
   17580                 :             : 
   17581                 :    20365390 :       gcc_assert (GET_CODE (set) == SET);
   17582                 :             : 
   17583                 :    20365390 :       addr = SET_SRC (set);
   17584                 :             : 
   17585                 :    20365390 :       return memory_address_length (addr, true);
   17586                 :             :     }
   17587                 :             : 
   17588                 :   356632934 :   extract_insn_cached (insn);
   17589                 :   824958423 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17590                 :             :     {
   17591                 :   670043116 :       rtx op = recog_data.operand[i];
   17592                 :   670043116 :       if (MEM_P (op))
   17593                 :             :         {
   17594                 :   202015937 :           constrain_operands_cached (insn, reload_completed);
   17595                 :   202015937 :           if (which_alternative != -1)
   17596                 :             :             {
   17597                 :   202015937 :               const char *constraints = recog_data.constraints[i];
   17598                 :   202015937 :               int alt = which_alternative;
   17599                 :             : 
   17600                 :   316846134 :               while (*constraints == '=' || *constraints == '+')
   17601                 :   114830197 :                 constraints++;
   17602                 :   888298026 :               while (alt-- > 0)
   17603                 :  1698381530 :                 while (*constraints++ != ',')
   17604                 :             :                   ;
   17605                 :             :               /* Skip ignored operands.  */
   17606                 :   202015937 :               if (*constraints == 'X')
   17607                 :      298310 :                 continue;
   17608                 :             :             }
   17609                 :             : 
   17610                 :   201717627 :           int len = memory_address_length (XEXP (op, 0), false);
   17611                 :             : 
   17612                 :             :           /* Account for segment prefix for non-default addr spaces.  */
   17613                 :   213809445 :           if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
   17614                 :      778707 :             len++;
   17615                 :             : 
   17616                 :   201717627 :           return len;
   17617                 :             :         }
   17618                 :             :     }
   17619                 :             :   return 0;
   17620                 :             : }
   17621                 :             : 
   17622                 :             : /* Compute default value for "length_vex" attribute. It includes
   17623                 :             :    2 or 3 byte VEX prefix and 1 opcode byte.  */
   17624                 :             : 
   17625                 :             : int
   17626                 :     4480363 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
   17627                 :             :                               bool has_vex_w)
   17628                 :             : {
   17629                 :     4480363 :   int i, reg_only = 2 + 1;
   17630                 :     4480363 :   bool has_mem = false;
   17631                 :             : 
   17632                 :             :   /* Only 0f opcode can use 2 byte VEX prefix and  VEX W bit uses 3
   17633                 :             :      byte VEX prefix.  */
   17634                 :     4480363 :   if (!has_0f_opcode || has_vex_w)
   17635                 :             :     return 3 + 1;
   17636                 :             : 
   17637                 :             :  /* We can always use 2 byte VEX prefix in 32bit.  */
   17638                 :     4063256 :   if (!TARGET_64BIT)
   17639                 :             :     return 2 + 1;
   17640                 :             : 
   17641                 :     3076412 :   extract_insn_cached (insn);
   17642                 :             : 
   17643                 :     9555416 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   17644                 :     6773690 :     if (REG_P (recog_data.operand[i]))
   17645                 :             :       {
   17646                 :             :         /* REX.W bit uses 3 byte VEX prefix.
   17647                 :             :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   17648                 :     4526842 :         if (GET_MODE (recog_data.operand[i]) == DImode
   17649                 :     4526842 :             && GENERAL_REG_P (recog_data.operand[i]))
   17650                 :             :           return 3 + 1;
   17651                 :             : 
   17652                 :             :         /* REX.B bit requires 3-byte VEX. Right here we don't know which
   17653                 :             :            operand will be encoded using VEX.B, so be conservative.
   17654                 :             :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   17655                 :     4513253 :         if (REX_INT_REGNO_P (recog_data.operand[i])
   17656                 :     4513253 :             || REX2_INT_REGNO_P (recog_data.operand[i])
   17657                 :     4513253 :             || REX_SSE_REGNO_P (recog_data.operand[i]))
   17658                 :           0 :           reg_only = 3 + 1;
   17659                 :             :       }
   17660                 :     2246848 :     else if (MEM_P (recog_data.operand[i]))
   17661                 :             :       {
   17662                 :             :         /* REX2.X or REX2.B bits use 3 byte VEX prefix.  */
   17663                 :     1801382 :         if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
   17664                 :             :           return 4;
   17665                 :             : 
   17666                 :             :         /* REX.X or REX.B bits use 3 byte VEX prefix.  */
   17667                 :     1801141 :         if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
   17668                 :             :           return 3 + 1;
   17669                 :             : 
   17670                 :             :         has_mem = true;
   17671                 :             :       }
   17672                 :             : 
   17673                 :     2781726 :   return has_mem ? 2 + 1 : reg_only;
   17674                 :             : }
   17675                 :             : 
   17676                 :             : 
   17677                 :             : static bool
   17678                 :             : ix86_class_likely_spilled_p (reg_class_t);
   17679                 :             : 
   17680                 :             : /* Returns true if lhs of insn is HW function argument register and set up
   17681                 :             :    is_spilled to true if it is likely spilled HW register.  */
   17682                 :             : static bool
   17683                 :        1167 : insn_is_function_arg (rtx insn, bool* is_spilled)
   17684                 :             : {
   17685                 :        1167 :   rtx dst;
   17686                 :             : 
   17687                 :        1167 :   if (!NONDEBUG_INSN_P (insn))
   17688                 :             :     return false;
   17689                 :             :   /* Call instructions are not movable, ignore it.  */
   17690                 :        1167 :   if (CALL_P (insn))
   17691                 :             :     return false;
   17692                 :        1095 :   insn = PATTERN (insn);
   17693                 :        1095 :   if (GET_CODE (insn) == PARALLEL)
   17694                 :          73 :     insn = XVECEXP (insn, 0, 0);
   17695                 :        1095 :   if (GET_CODE (insn) != SET)
   17696                 :             :     return false;
   17697                 :        1095 :   dst = SET_DEST (insn);
   17698                 :        1005 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   17699                 :        2007 :       && ix86_function_arg_regno_p (REGNO (dst)))
   17700                 :             :     {
   17701                 :             :       /* Is it likely spilled HW register?  */
   17702                 :         912 :       if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
   17703                 :         912 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
   17704                 :         859 :         *is_spilled = true;
   17705                 :         912 :       return true;
   17706                 :             :     }
   17707                 :             :   return false;
   17708                 :             : }
   17709                 :             : 
   17710                 :             : /* Add output dependencies for chain of function adjacent arguments if only
   17711                 :             :    there is a move to likely spilled HW register.  Return first argument
   17712                 :             :    if at least one dependence was added or NULL otherwise.  */
   17713                 :             : static rtx_insn *
   17714                 :         416 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
   17715                 :             : {
   17716                 :         416 :   rtx_insn *insn;
   17717                 :         416 :   rtx_insn *last = call;
   17718                 :         416 :   rtx_insn *first_arg = NULL;
   17719                 :         416 :   bool is_spilled = false;
   17720                 :             : 
   17721                 :         416 :   head = PREV_INSN (head);
   17722                 :             : 
   17723                 :             :   /* Find nearest to call argument passing instruction.  */
   17724                 :         416 :   while (true)
   17725                 :             :     {
   17726                 :         416 :       last = PREV_INSN (last);
   17727                 :         416 :       if (last == head)
   17728                 :             :         return NULL;
   17729                 :         416 :       if (!NONDEBUG_INSN_P (last))
   17730                 :           0 :         continue;
   17731                 :         416 :       if (insn_is_function_arg (last, &is_spilled))
   17732                 :             :         break;
   17733                 :             :       return NULL;
   17734                 :             :     }
   17735                 :             : 
   17736                 :             :   first_arg = last;
   17737                 :        1103 :   while (true)
   17738                 :             :     {
   17739                 :        1103 :       insn = PREV_INSN (last);
   17740                 :        1103 :       if (!INSN_P (insn))
   17741                 :             :         break;
   17742                 :         983 :       if (insn == head)
   17743                 :             :         break;
   17744                 :         942 :       if (!NONDEBUG_INSN_P (insn))
   17745                 :             :         {
   17746                 :         191 :           last = insn;
   17747                 :         191 :           continue;
   17748                 :             :         }
   17749                 :         751 :       if (insn_is_function_arg (insn, &is_spilled))
   17750                 :             :         {
   17751                 :             :           /* Add output depdendence between two function arguments if chain
   17752                 :             :              of output arguments contains likely spilled HW registers.  */
   17753                 :         506 :           if (is_spilled)
   17754                 :         506 :             add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   17755                 :             :           first_arg = last = insn;
   17756                 :             :         }
   17757                 :             :       else
   17758                 :             :         break;
   17759                 :             :     }
   17760                 :         406 :   if (!is_spilled)
   17761                 :             :     return NULL;
   17762                 :             :   return first_arg;
   17763                 :             : }
   17764                 :             : 
   17765                 :             : /* Add output or anti dependency from insn to first_arg to restrict its code
   17766                 :             :    motion.  */
   17767                 :             : static void
   17768                 :        1901 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
   17769                 :             : {
   17770                 :        1901 :   rtx set;
   17771                 :        1901 :   rtx tmp;
   17772                 :             : 
   17773                 :        1901 :   set = single_set (insn);
   17774                 :        1901 :   if (!set)
   17775                 :             :     return;
   17776                 :        1089 :   tmp = SET_DEST (set);
   17777                 :        1089 :   if (REG_P (tmp))
   17778                 :             :     {
   17779                 :             :       /* Add output dependency to the first function argument.  */
   17780                 :         906 :       add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   17781                 :         906 :       return;
   17782                 :             :     }
   17783                 :             :   /* Add anti dependency.  */
   17784                 :         183 :   add_dependence (first_arg, insn, REG_DEP_ANTI);
   17785                 :             : }
   17786                 :             : 
   17787                 :             : /* Avoid cross block motion of function argument through adding dependency
   17788                 :             :    from the first non-jump instruction in bb.  */
   17789                 :             : static void
   17790                 :          68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
   17791                 :             : {
   17792                 :          68 :   rtx_insn *insn = BB_END (bb);
   17793                 :             : 
   17794                 :         134 :   while (insn)
   17795                 :             :     {
   17796                 :         134 :       if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
   17797                 :             :         {
   17798                 :          67 :           rtx set = single_set (insn);
   17799                 :          67 :           if (set)
   17800                 :             :             {
   17801                 :          67 :               avoid_func_arg_motion (arg, insn);
   17802                 :          67 :               return;
   17803                 :             :             }
   17804                 :             :         }
   17805                 :          67 :       if (insn == BB_HEAD (bb))
   17806                 :             :         return;
   17807                 :          66 :       insn = PREV_INSN (insn);
   17808                 :             :     }
   17809                 :             : }
   17810                 :             : 
   17811                 :             : /* Hook for pre-reload schedule - avoid motion of function arguments
   17812                 :             :    passed in likely spilled HW registers.  */
   17813                 :             : static void
   17814                 :     9131007 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
   17815                 :             : {
   17816                 :     9131007 :   rtx_insn *insn;
   17817                 :     9131007 :   rtx_insn *first_arg = NULL;
   17818                 :     9131007 :   if (reload_completed)
   17819                 :             :     return;
   17820                 :        2044 :   while (head != tail && DEBUG_INSN_P (head))
   17821                 :         712 :     head = NEXT_INSN (head);
   17822                 :        8642 :   for (insn = tail; insn != head; insn = PREV_INSN (insn))
   17823                 :        7459 :     if (INSN_P (insn) && CALL_P (insn))
   17824                 :             :       {
   17825                 :         416 :         first_arg = add_parameter_dependencies (insn, head);
   17826                 :         416 :         if (first_arg)
   17827                 :             :           {
   17828                 :             :             /* Add dependee for first argument to predecessors if only
   17829                 :             :                region contains more than one block.  */
   17830                 :         406 :             basic_block bb =  BLOCK_FOR_INSN (insn);
   17831                 :         406 :             int rgn = CONTAINING_RGN (bb->index);
   17832                 :         406 :             int nr_blks = RGN_NR_BLOCKS (rgn);
   17833                 :             :             /* Skip trivial regions and region head blocks that can have
   17834                 :             :                predecessors outside of region.  */
   17835                 :         406 :             if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
   17836                 :             :               {
   17837                 :          67 :                 edge e;
   17838                 :          67 :                 edge_iterator ei;
   17839                 :             : 
   17840                 :             :                 /* Regions are SCCs with the exception of selective
   17841                 :             :                    scheduling with pipelining of outer blocks enabled.
   17842                 :             :                    So also check that immediate predecessors of a non-head
   17843                 :             :                    block are in the same region.  */
   17844                 :         137 :                 FOR_EACH_EDGE (e, ei, bb->preds)
   17845                 :             :                   {
   17846                 :             :                     /* Avoid creating of loop-carried dependencies through
   17847                 :             :                        using topological ordering in the region.  */
   17848                 :          70 :                     if (rgn == CONTAINING_RGN (e->src->index)
   17849                 :          69 :                         && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
   17850                 :          68 :                       add_dependee_for_func_arg (first_arg, e->src); 
   17851                 :             :                   }
   17852                 :             :               }
   17853                 :         406 :             insn = first_arg;
   17854                 :         406 :             if (insn == head)
   17855                 :             :               break;
   17856                 :             :           }
   17857                 :             :       }
   17858                 :        7043 :     else if (first_arg)
   17859                 :        1834 :       avoid_func_arg_motion (first_arg, insn);
   17860                 :             : }
   17861                 :             : 
   17862                 :             : /* Hook for pre-reload schedule - set priority of moves from likely spilled
   17863                 :             :    HW registers to maximum, to schedule them at soon as possible. These are
   17864                 :             :    moves from function argument registers at the top of the function entry
   17865                 :             :    and moves from function return value registers after call.  */
   17866                 :             : static int
   17867                 :    90083576 : ix86_adjust_priority (rtx_insn *insn, int priority)
   17868                 :             : {
   17869                 :    90083576 :   rtx set;
   17870                 :             : 
   17871                 :    90083576 :   if (reload_completed)
   17872                 :             :     return priority;
   17873                 :             : 
   17874                 :       13742 :   if (!NONDEBUG_INSN_P (insn))
   17875                 :             :     return priority;
   17876                 :             : 
   17877                 :       11717 :   set = single_set (insn);
   17878                 :       11717 :   if (set)
   17879                 :             :     {
   17880                 :       11185 :       rtx tmp = SET_SRC (set);
   17881                 :       11185 :       if (REG_P (tmp)
   17882                 :        2910 :           && HARD_REGISTER_P (tmp)
   17883                 :         477 :           && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
   17884                 :       11185 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
   17885                 :         427 :         return current_sched_info->sched_max_insns_priority;
   17886                 :             :     }
   17887                 :             : 
   17888                 :             :   return priority;
   17889                 :             : }
   17890                 :             : 
   17891                 :             : /* Prepare for scheduling pass.  */
   17892                 :             : static void
   17893                 :      901359 : ix86_sched_init_global (FILE *, int, int)
   17894                 :             : {
   17895                 :             :   /* Install scheduling hooks for current CPU.  Some of these hooks are used
   17896                 :             :      in time-critical parts of the scheduler, so we only set them up when
   17897                 :             :      they are actually used.  */
   17898                 :      901359 :   switch (ix86_tune)
   17899                 :             :     {
   17900                 :      859346 :     case PROCESSOR_CORE2:
   17901                 :      859346 :     case PROCESSOR_NEHALEM:
   17902                 :      859346 :     case PROCESSOR_SANDYBRIDGE:
   17903                 :      859346 :     case PROCESSOR_HASWELL:
   17904                 :      859346 :     case PROCESSOR_TREMONT:
   17905                 :      859346 :     case PROCESSOR_ALDERLAKE:
   17906                 :      859346 :     case PROCESSOR_GENERIC:
   17907                 :             :       /* Do not perform multipass scheduling for pre-reload schedule
   17908                 :             :          to save compile time.  */
   17909                 :      859346 :       if (reload_completed)
   17910                 :             :         {
   17911                 :      859062 :           ix86_core2i7_init_hooks ();
   17912                 :      859062 :           break;
   17913                 :             :         }
   17914                 :             :       /* Fall through.  */
   17915                 :       42297 :     default:
   17916                 :       42297 :       targetm.sched.dfa_post_advance_cycle = NULL;
   17917                 :       42297 :       targetm.sched.first_cycle_multipass_init = NULL;
   17918                 :       42297 :       targetm.sched.first_cycle_multipass_begin = NULL;
   17919                 :       42297 :       targetm.sched.first_cycle_multipass_issue = NULL;
   17920                 :       42297 :       targetm.sched.first_cycle_multipass_backtrack = NULL;
   17921                 :       42297 :       targetm.sched.first_cycle_multipass_end = NULL;
   17922                 :       42297 :       targetm.sched.first_cycle_multipass_fini = NULL;
   17923                 :       42297 :       break;
   17924                 :             :     }
   17925                 :      901359 : }
   17926                 :             : 
   17927                 :             : 
   17928                 :             : /* Implement TARGET_STATIC_RTX_ALIGNMENT.  */
   17929                 :             : 
   17930                 :             : static HOST_WIDE_INT
   17931                 :      705343 : ix86_static_rtx_alignment (machine_mode mode)
   17932                 :             : {
   17933                 :      705343 :   if (mode == DFmode)
   17934                 :             :     return 64;
   17935                 :             :   if (ALIGN_MODE_128 (mode))
   17936                 :      146604 :     return MAX (128, GET_MODE_ALIGNMENT (mode));
   17937                 :      474896 :   return GET_MODE_ALIGNMENT (mode);
   17938                 :             : }
   17939                 :             : 
   17940                 :             : /* Implement TARGET_CONSTANT_ALIGNMENT.  */
   17941                 :             : 
   17942                 :             : static HOST_WIDE_INT
   17943                 :     6616526 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
   17944                 :             : {
   17945                 :     6616526 :   if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
   17946                 :             :       || TREE_CODE (exp) == INTEGER_CST)
   17947                 :             :     {
   17948                 :      359851 :       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   17949                 :      359851 :       HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
   17950                 :      359851 :       return MAX (mode_align, align);
   17951                 :             :     }
   17952                 :     6120951 :   else if (!optimize_size && TREE_CODE (exp) == STRING_CST
   17953                 :     9159915 :            && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
   17954                 :             :     return BITS_PER_WORD;
   17955                 :             : 
   17956                 :             :   return align;
   17957                 :             : }
   17958                 :             : 
   17959                 :             : /* Implement TARGET_EMPTY_RECORD_P.  */
   17960                 :             : 
   17961                 :             : static bool
   17962                 :  1321625723 : ix86_is_empty_record (const_tree type)
   17963                 :             : {
   17964                 :  1321625723 :   if (!TARGET_64BIT)
   17965                 :             :     return false;
   17966                 :  1290010548 :   return default_is_empty_record (type);
   17967                 :             : }
   17968                 :             : 
   17969                 :             : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI.  */
   17970                 :             : 
   17971                 :             : static void
   17972                 :    14261227 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
   17973                 :             : {
   17974                 :    14261227 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   17975                 :             : 
   17976                 :    14261227 :   if (!cum->warn_empty)
   17977                 :             :     return;
   17978                 :             : 
   17979                 :    14141047 :   if (!TYPE_EMPTY_P (type))
   17980                 :             :     return;
   17981                 :             : 
   17982                 :             :   /* Don't warn if the function isn't visible outside of the TU.  */
   17983                 :       14729 :   if (cum->decl && !TREE_PUBLIC (cum->decl))
   17984                 :             :     return;
   17985                 :             : 
   17986                 :       13124 :   const_tree ctx = get_ultimate_context (cum->decl);
   17987                 :       13124 :   if (ctx != NULL_TREE
   17988                 :       26197 :       && !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
   17989                 :             :     return;
   17990                 :             : 
   17991                 :             :   /* If the actual size of the type is zero, then there is no change
   17992                 :             :      in how objects of this size are passed.  */
   17993                 :         259 :   if (int_size_in_bytes (type) == 0)
   17994                 :             :     return;
   17995                 :             : 
   17996                 :         226 :   warning (OPT_Wabi, "empty class %qT parameter passing ABI "
   17997                 :             :            "changes in %<-fabi-version=12%> (GCC 8)", type);
   17998                 :             : 
   17999                 :             :   /* Only warn once.  */
   18000                 :         226 :   cum->warn_empty = false;
   18001                 :             : }
   18002                 :             : 
   18003                 :             : /* This hook returns name of multilib ABI.  */
   18004                 :             : 
   18005                 :             : static const char *
   18006                 :     3190755 : ix86_get_multilib_abi_name (void)
   18007                 :             : {
   18008                 :     3190755 :   if (!(TARGET_64BIT_P (ix86_isa_flags)))
   18009                 :             :     return "i386";
   18010                 :     3146799 :   else if (TARGET_X32_P (ix86_isa_flags))
   18011                 :             :     return "x32";
   18012                 :             :   else
   18013                 :     3146799 :     return "x86_64";
   18014                 :             : }
   18015                 :             : 
   18016                 :             : /* Compute the alignment for a variable for Intel MCU psABI.  TYPE is
   18017                 :             :    the data type, and ALIGN is the alignment that the object would
   18018                 :             :    ordinarily have.  */
   18019                 :             : 
   18020                 :             : static int
   18021                 :           0 : iamcu_alignment (tree type, int align)
   18022                 :             : {
   18023                 :           0 :   machine_mode mode;
   18024                 :             : 
   18025                 :           0 :   if (align < 32 || TYPE_USER_ALIGN (type))
   18026                 :             :     return align;
   18027                 :             : 
   18028                 :             :   /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
   18029                 :             :      bytes.  */
   18030                 :           0 :   type = strip_array_types (type);
   18031                 :           0 :   if (TYPE_ATOMIC (type))
   18032                 :             :     return align;
   18033                 :             : 
   18034                 :           0 :   mode = TYPE_MODE (type);
   18035                 :           0 :   switch (GET_MODE_CLASS (mode))
   18036                 :             :     {
   18037                 :             :     case MODE_INT:
   18038                 :             :     case MODE_COMPLEX_INT:
   18039                 :             :     case MODE_COMPLEX_FLOAT:
   18040                 :             :     case MODE_FLOAT:
   18041                 :             :     case MODE_DECIMAL_FLOAT:
   18042                 :             :       return 32;
   18043                 :             :     default:
   18044                 :             :       return align;
   18045                 :             :     }
   18046                 :             : }
   18047                 :             : 
   18048                 :             : /* Compute the alignment for a static variable.
   18049                 :             :    TYPE is the data type, and ALIGN is the alignment that
   18050                 :             :    the object would ordinarily have.  The value of this function is used
   18051                 :             :    instead of that alignment to align the object.  */
   18052                 :             : 
   18053                 :             : int
   18054                 :    11822977 : ix86_data_alignment (tree type, unsigned int align, bool opt)
   18055                 :             : {
   18056                 :             :   /* GCC 4.8 and earlier used to incorrectly assume this alignment even
   18057                 :             :      for symbols from other compilation units or symbols that don't need
   18058                 :             :      to bind locally.  In order to preserve some ABI compatibility with
   18059                 :             :      those compilers, ensure we don't decrease alignment from what we
   18060                 :             :      used to assume.  */
   18061                 :             : 
   18062                 :    11822977 :   unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
   18063                 :             : 
   18064                 :             :   /* A data structure, equal or greater than the size of a cache line
   18065                 :             :      (64 bytes in the Pentium 4 and other recent Intel processors, including
   18066                 :             :      processors based on Intel Core microarchitecture) should be aligned
   18067                 :             :      so that its base address is a multiple of a cache line size.  */
   18068                 :             : 
   18069                 :    23645954 :   unsigned int max_align
   18070                 :    11822977 :     = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
   18071                 :             : 
   18072                 :    14401107 :   if (max_align < BITS_PER_WORD)
   18073                 :           0 :     max_align = BITS_PER_WORD;
   18074                 :             : 
   18075                 :    11822977 :   switch (ix86_align_data_type)
   18076                 :             :     {
   18077                 :    11822977 :     case ix86_align_data_type_abi: opt = false; break;
   18078                 :    11822957 :     case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
   18079                 :             :     case ix86_align_data_type_cacheline: break;
   18080                 :             :     }
   18081                 :             : 
   18082                 :    11822977 :   if (TARGET_IAMCU)
   18083                 :           0 :     align = iamcu_alignment (type, align);
   18084                 :             : 
   18085                 :    11822977 :   if (opt
   18086                 :     5727604 :       && AGGREGATE_TYPE_P (type)
   18087                 :     3676179 :       && TYPE_SIZE (type)
   18088                 :    15499125 :       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
   18089                 :             :     {
   18090                 :     6664149 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
   18091                 :     3676148 :           && align < max_align_compat)
   18092                 :      688147 :         align = max_align_compat;
   18093                 :     7295118 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
   18094                 :     3676148 :           && align < max_align)
   18095                 :       57178 :         align = max_align;
   18096                 :             :     }
   18097                 :             : 
   18098                 :             :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18099                 :             :      to 16byte boundary.  */
   18100                 :    11822977 :   if (TARGET_64BIT)
   18101                 :             :     {
   18102                 :     4805676 :       if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
   18103                 :     3219763 :           && TYPE_SIZE (type)
   18104                 :     3219722 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18105                 :    10637975 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18106                 :    11235465 :           && align < 128)
   18107                 :      597490 :         return 128;
   18108                 :             :     }
   18109                 :             : 
   18110                 :    11225487 :   if (!opt)
   18111                 :     5912042 :     return align;
   18112                 :             : 
   18113                 :     5313445 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18114                 :             :     {
   18115                 :     1091550 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18116                 :             :         return 64;
   18117                 :     1091550 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18118                 :             :         return 128;
   18119                 :             :     }
   18120                 :     4221895 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18121                 :             :     {
   18122                 :             : 
   18123                 :       12474 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18124                 :             :         return 64;
   18125                 :       12474 :       if ((TYPE_MODE (type) == XCmode
   18126                 :       12474 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18127                 :             :         return 128;
   18128                 :             :     }
   18129                 :     4209421 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18130                 :     4209421 :            && TYPE_FIELDS (type))
   18131                 :             :     {
   18132                 :     2168832 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18133                 :             :         return 64;
   18134                 :     2168832 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18135                 :             :         return 128;
   18136                 :             :     }
   18137                 :     2040589 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18138                 :             :            || TREE_CODE (type) == INTEGER_TYPE)
   18139                 :             :     {
   18140                 :     1898840 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18141                 :             :         return 64;
   18142                 :     1898840 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18143                 :             :         return 128;
   18144                 :             :     }
   18145                 :             : 
   18146                 :     5313332 :   return align;
   18147                 :             : }
   18148                 :             : 
   18149                 :             : /* Implememnt TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
   18150                 :             : static void
   18151                 :    28269563 : ix86_lower_local_decl_alignment (tree decl)
   18152                 :             : {
   18153                 :    28269563 :   unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
   18154                 :    28269563 :                                                  DECL_ALIGN (decl), true);
   18155                 :    28269563 :   if (new_align < DECL_ALIGN (decl))
   18156                 :           0 :     SET_DECL_ALIGN (decl, new_align);
   18157                 :    28269563 : }
   18158                 :             : 
   18159                 :             : /* Compute the alignment for a local variable or a stack slot.  EXP is
   18160                 :             :    the data type or decl itself, MODE is the widest mode available and
   18161                 :             :    ALIGN is the alignment that the object would ordinarily have.  The
   18162                 :             :    value of this macro is used instead of that alignment to align the
   18163                 :             :    object.  */
   18164                 :             : 
   18165                 :             : unsigned int
   18166                 :    43575838 : ix86_local_alignment (tree exp, machine_mode mode,
   18167                 :             :                       unsigned int align, bool may_lower)
   18168                 :             : {
   18169                 :    43575838 :   tree type, decl;
   18170                 :             : 
   18171                 :    43575838 :   if (exp && DECL_P (exp))
   18172                 :             :     {
   18173                 :    41845230 :       type = TREE_TYPE (exp);
   18174                 :    41845230 :       decl = exp;
   18175                 :             :     }
   18176                 :             :   else
   18177                 :             :     {
   18178                 :             :       type = exp;
   18179                 :             :       decl = NULL;
   18180                 :             :     }
   18181                 :             : 
   18182                 :             :   /* Don't do dynamic stack realignment for long long objects with
   18183                 :             :      -mpreferred-stack-boundary=2.  */
   18184                 :    43575838 :   if (may_lower
   18185                 :    28269563 :       && !TARGET_64BIT
   18186                 :      239022 :       && align == 64
   18187                 :       39209 :       && ix86_preferred_stack_boundary < 64
   18188                 :           0 :       && (mode == DImode || (type && TYPE_MODE (type) == DImode))
   18189                 :           0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18190                 :           0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18191                 :    43575838 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18192                 :             :     align = 32;
   18193                 :             : 
   18194                 :             :   /* If TYPE is NULL, we are allocating a stack slot for caller-save
   18195                 :             :      register in MODE.  We will return the largest alignment of XF
   18196                 :             :      and DF.  */
   18197                 :    43575838 :   if (!type)
   18198                 :             :     {
   18199                 :     1057351 :       if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
   18200                 :        1502 :         align = GET_MODE_ALIGNMENT (DFmode);
   18201                 :     1057351 :       return align;
   18202                 :             :     }
   18203                 :             : 
   18204                 :             :   /* Don't increase alignment for Intel MCU psABI.  */
   18205                 :    42518487 :   if (TARGET_IAMCU)
   18206                 :             :     return align;
   18207                 :             : 
   18208                 :             :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18209                 :             :      to 16byte boundary.  Exact wording is:
   18210                 :             : 
   18211                 :             :      An array uses the same alignment as its elements, except that a local or
   18212                 :             :      global array variable of length at least 16 bytes or
   18213                 :             :      a C99 variable-length array variable always has alignment of at least 16 bytes.
   18214                 :             : 
   18215                 :             :      This was added to allow use of aligned SSE instructions at arrays.  This
   18216                 :             :      rule is meant for static storage (where compiler cannot do the analysis
   18217                 :             :      by itself).  We follow it for automatic variables only when convenient.
   18218                 :             :      We fully control everything in the function compiled and functions from
   18219                 :             :      other unit cannot rely on the alignment.
   18220                 :             : 
   18221                 :             :      Exclude va_list type.  It is the common case of local array where
   18222                 :             :      we cannot benefit from the alignment.  
   18223                 :             : 
   18224                 :             :      TODO: Probably one should optimize for size only when var is not escaping.  */
   18225                 :    39663523 :   if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
   18226                 :    81886930 :       && TARGET_SSE)
   18227                 :             :     {
   18228                 :    39329998 :       if (AGGREGATE_TYPE_P (type)
   18229                 :     7706035 :           && (va_list_type_node == NULL_TREE
   18230                 :     7706035 :               || (TYPE_MAIN_VARIANT (type)
   18231                 :     7706035 :                   != TYPE_MAIN_VARIANT (va_list_type_node)))
   18232                 :     7609910 :           && TYPE_SIZE (type)
   18233                 :     7609910 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18234                 :    40238232 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18235                 :    44999082 :           && align < 128)
   18236                 :     4760850 :         return 128;
   18237                 :             :     }
   18238                 :    37757637 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18239                 :             :     {
   18240                 :      735783 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18241                 :             :         return 64;
   18242                 :      735783 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18243                 :             :         return 128;
   18244                 :             :     }
   18245                 :    37021854 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18246                 :             :     {
   18247                 :      162369 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18248                 :             :         return 64;
   18249                 :      162369 :       if ((TYPE_MODE (type) == XCmode
   18250                 :      162369 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18251                 :             :         return 128;
   18252                 :             :     }
   18253                 :    36859485 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18254                 :    36859485 :            && TYPE_FIELDS (type))
   18255                 :             :     {
   18256                 :     4194518 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18257                 :             :         return 64;
   18258                 :     4191384 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18259                 :             :         return 128;
   18260                 :             :     }
   18261                 :    32664967 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18262                 :             :            || TREE_CODE (type) == INTEGER_TYPE)
   18263                 :             :     {
   18264                 :             : 
   18265                 :    27393119 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18266                 :             :         return 64;
   18267                 :    27393119 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18268                 :             :         return 128;
   18269                 :             :     }
   18270                 :             :   return align;
   18271                 :             : }
   18272                 :             : 
   18273                 :             : /* Compute the minimum required alignment for dynamic stack realignment
   18274                 :             :    purposes for a local variable, parameter or a stack slot.  EXP is
   18275                 :             :    the data type or decl itself, MODE is its mode and ALIGN is the
   18276                 :             :    alignment that the object would ordinarily have.  */
   18277                 :             : 
   18278                 :             : unsigned int
   18279                 :    43846649 : ix86_minimum_alignment (tree exp, machine_mode mode,
   18280                 :             :                         unsigned int align)
   18281                 :             : {
   18282                 :    43846649 :   tree type, decl;
   18283                 :             : 
   18284                 :    43846649 :   if (exp && DECL_P (exp))
   18285                 :             :     {
   18286                 :    14381108 :       type = TREE_TYPE (exp);
   18287                 :    14381108 :       decl = exp;
   18288                 :             :     }
   18289                 :             :   else
   18290                 :             :     {
   18291                 :             :       type = exp;
   18292                 :             :       decl = NULL;
   18293                 :             :     }
   18294                 :             : 
   18295                 :    43846649 :   if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
   18296                 :             :     return align;
   18297                 :             : 
   18298                 :             :   /* Don't do dynamic stack realignment for long long objects with
   18299                 :             :      -mpreferred-stack-boundary=2.  */
   18300                 :           0 :   if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
   18301                 :           0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18302                 :           0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18303                 :           0 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18304                 :             :     {
   18305                 :           0 :       gcc_checking_assert (!TARGET_STV);
   18306                 :             :       return 32;
   18307                 :             :     }
   18308                 :             : 
   18309                 :             :   return align;
   18310                 :             : }
   18311                 :             : 
   18312                 :             : /* Find a location for the static chain incoming to a nested function.
   18313                 :             :    This is a register, unless all free registers are used by arguments.  */
   18314                 :             : 
   18315                 :             : static rtx
   18316                 :      258372 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
   18317                 :             : {
   18318                 :      258372 :   unsigned regno;
   18319                 :             : 
   18320                 :      258372 :   if (TARGET_64BIT)
   18321                 :             :     {
   18322                 :             :       /* We always use R10 in 64-bit mode.  */
   18323                 :             :       regno = R10_REG;
   18324                 :             :     }
   18325                 :             :   else
   18326                 :             :     {
   18327                 :       88678 :       const_tree fntype, fndecl;
   18328                 :       88678 :       unsigned int ccvt;
   18329                 :             : 
   18330                 :             :       /* By default in 32-bit mode we use ECX to pass the static chain.  */
   18331                 :       88678 :       regno = CX_REG;
   18332                 :             : 
   18333                 :       88678 :       if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
   18334                 :             :         {
   18335                 :       78782 :           fntype = TREE_TYPE (fndecl_or_type);
   18336                 :       78782 :           fndecl = fndecl_or_type;
   18337                 :             :         }
   18338                 :             :       else
   18339                 :             :         {
   18340                 :             :           fntype = fndecl_or_type;
   18341                 :             :           fndecl = NULL;
   18342                 :             :         }
   18343                 :             : 
   18344                 :       88678 :       ccvt = ix86_get_callcvt (fntype);
   18345                 :       88678 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   18346                 :             :         {
   18347                 :             :           /* Fastcall functions use ecx/edx for arguments, which leaves
   18348                 :             :              us with EAX for the static chain.
   18349                 :             :              Thiscall functions use ecx for arguments, which also
   18350                 :             :              leaves us with EAX for the static chain.  */
   18351                 :             :           regno = AX_REG;
   18352                 :             :         }
   18353                 :       88678 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   18354                 :             :         {
   18355                 :             :           /* Thiscall functions use ecx for arguments, which leaves
   18356                 :             :              us with EAX and EDX for the static chain.
   18357                 :             :              We are using for abi-compatibility EAX.  */
   18358                 :             :           regno = AX_REG;
   18359                 :             :         }
   18360                 :       88678 :       else if (ix86_function_regparm (fntype, fndecl) == 3)
   18361                 :             :         {
   18362                 :             :           /* For regparm 3, we have no free call-clobbered registers in
   18363                 :             :              which to store the static chain.  In order to implement this,
   18364                 :             :              we have the trampoline push the static chain to the stack.
   18365                 :             :              However, we can't push a value below the return address when
   18366                 :             :              we call the nested function directly, so we have to use an
   18367                 :             :              alternate entry point.  For this we use ESI, and have the
   18368                 :             :              alternate entry point push ESI, so that things appear the
   18369                 :             :              same once we're executing the nested function.  */
   18370                 :           0 :           if (incoming_p)
   18371                 :             :             {
   18372                 :           0 :               if (fndecl == current_function_decl
   18373                 :           0 :                   && !ix86_static_chain_on_stack)
   18374                 :             :                 {
   18375                 :           0 :                   gcc_assert (!reload_completed);
   18376                 :           0 :                   ix86_static_chain_on_stack = true;
   18377                 :             :                 }
   18378                 :           0 :               return gen_frame_mem (SImode,
   18379                 :           0 :                                     plus_constant (Pmode,
   18380                 :           0 :                                                    arg_pointer_rtx, -8));
   18381                 :             :             }
   18382                 :             :           regno = SI_REG;
   18383                 :             :         }
   18384                 :             :     }
   18385                 :             : 
   18386                 :      258372 :   return gen_rtx_REG (Pmode, regno);
   18387                 :             : }
   18388                 :             : 
   18389                 :             : /* Emit RTL insns to initialize the variable parts of a trampoline.
   18390                 :             :    FNDECL is the decl of the target address; M_TRAMP is a MEM for
   18391                 :             :    the trampoline, and CHAIN_VALUE is an RTX for the static chain
   18392                 :             :    to be passed to the target function.  */
   18393                 :             : 
   18394                 :             : static void
   18395                 :         269 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   18396                 :             : {
   18397                 :         269 :   rtx mem, fnaddr;
   18398                 :         269 :   int opcode;
   18399                 :         269 :   int offset = 0;
   18400                 :         269 :   bool need_endbr = (flag_cf_protection & CF_BRANCH);
   18401                 :             : 
   18402                 :         269 :   fnaddr = XEXP (DECL_RTL (fndecl), 0);
   18403                 :             : 
   18404                 :         269 :   if (TARGET_64BIT)
   18405                 :             :     {
   18406                 :         269 :       int size;
   18407                 :             : 
   18408                 :         269 :       if (need_endbr)
   18409                 :             :         {
   18410                 :             :           /* Insert ENDBR64.  */
   18411                 :           1 :           mem = adjust_address (m_tramp, SImode, offset);
   18412                 :           1 :           emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
   18413                 :           1 :           offset += 4;
   18414                 :             :         }
   18415                 :             : 
   18416                 :             :       /* Load the function address to r11.  Try to load address using
   18417                 :             :          the shorter movl instead of movabs.  We may want to support
   18418                 :             :          movq for kernel mode, but kernel does not use trampolines at
   18419                 :             :          the moment.  FNADDR is a 32bit address and may not be in
   18420                 :             :          DImode when ptr_mode == SImode.  Always use movl in this
   18421                 :             :          case.  */
   18422                 :         269 :       if (ptr_mode == SImode
   18423                 :         269 :           || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
   18424                 :             :         {
   18425                 :         237 :           fnaddr = copy_addr_to_reg (fnaddr);
   18426                 :             : 
   18427                 :         237 :           mem = adjust_address (m_tramp, HImode, offset);
   18428                 :         237 :           emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
   18429                 :             : 
   18430                 :         237 :           mem = adjust_address (m_tramp, SImode, offset + 2);
   18431                 :         237 :           emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
   18432                 :         237 :           offset += 6;
   18433                 :             :         }
   18434                 :             :       else
   18435                 :             :         {
   18436                 :          32 :           mem = adjust_address (m_tramp, HImode, offset);
   18437                 :          32 :           emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
   18438                 :             : 
   18439                 :          32 :           mem = adjust_address (m_tramp, DImode, offset + 2);
   18440                 :          32 :           emit_move_insn (mem, fnaddr);
   18441                 :          32 :           offset += 10;
   18442                 :             :         }
   18443                 :             : 
   18444                 :             :       /* Load static chain using movabs to r10.  Use the shorter movl
   18445                 :             :          instead of movabs when ptr_mode == SImode.  */
   18446                 :         269 :       if (ptr_mode == SImode)
   18447                 :             :         {
   18448                 :             :           opcode = 0xba41;
   18449                 :             :           size = 6;
   18450                 :             :         }
   18451                 :             :       else
   18452                 :             :         {
   18453                 :         269 :           opcode = 0xba49;
   18454                 :         269 :           size = 10;
   18455                 :             :         }
   18456                 :             : 
   18457                 :         269 :       mem = adjust_address (m_tramp, HImode, offset);
   18458                 :         269 :       emit_move_insn (mem, gen_int_mode (opcode, HImode));
   18459                 :             : 
   18460                 :         269 :       mem = adjust_address (m_tramp, ptr_mode, offset + 2);
   18461                 :         269 :       emit_move_insn (mem, chain_value);
   18462                 :         269 :       offset += size;
   18463                 :             : 
   18464                 :             :       /* Jump to r11; the last (unused) byte is a nop, only there to
   18465                 :             :          pad the write out to a single 32-bit store.  */
   18466                 :         269 :       mem = adjust_address (m_tramp, SImode, offset);
   18467                 :         269 :       emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
   18468                 :         269 :       offset += 4;
   18469                 :             :     }
   18470                 :             :   else
   18471                 :             :     {
   18472                 :           0 :       rtx disp, chain;
   18473                 :             : 
   18474                 :             :       /* Depending on the static chain location, either load a register
   18475                 :             :          with a constant, or push the constant to the stack.  All of the
   18476                 :             :          instructions are the same size.  */
   18477                 :           0 :       chain = ix86_static_chain (fndecl, true);
   18478                 :           0 :       if (REG_P (chain))
   18479                 :             :         {
   18480                 :           0 :           switch (REGNO (chain))
   18481                 :             :             {
   18482                 :             :             case AX_REG:
   18483                 :             :               opcode = 0xb8; break;
   18484                 :           0 :             case CX_REG:
   18485                 :           0 :               opcode = 0xb9; break;
   18486                 :           0 :             default:
   18487                 :           0 :               gcc_unreachable ();
   18488                 :             :             }
   18489                 :             :         }
   18490                 :             :       else
   18491                 :             :         opcode = 0x68;
   18492                 :             : 
   18493                 :           0 :       if (need_endbr)
   18494                 :             :         {
   18495                 :             :           /* Insert ENDBR32.  */
   18496                 :           0 :           mem = adjust_address (m_tramp, SImode, offset);
   18497                 :           0 :           emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
   18498                 :           0 :           offset += 4;
   18499                 :             :         }
   18500                 :             : 
   18501                 :           0 :       mem = adjust_address (m_tramp, QImode, offset);
   18502                 :           0 :       emit_move_insn (mem, gen_int_mode (opcode, QImode));
   18503                 :             : 
   18504                 :           0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   18505                 :           0 :       emit_move_insn (mem, chain_value);
   18506                 :           0 :       offset += 5;
   18507                 :             : 
   18508                 :           0 :       mem = adjust_address (m_tramp, QImode, offset);
   18509                 :           0 :       emit_move_insn (mem, gen_int_mode (0xe9, QImode));
   18510                 :             : 
   18511                 :           0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   18512                 :             : 
   18513                 :             :       /* Compute offset from the end of the jmp to the target function.
   18514                 :             :          In the case in which the trampoline stores the static chain on
   18515                 :             :          the stack, we need to skip the first insn which pushes the
   18516                 :             :          (call-saved) register static chain; this push is 1 byte.  */
   18517                 :           0 :       offset += 5;
   18518                 :           0 :       int skip = MEM_P (chain) ? 1 : 0;
   18519                 :             :       /* Skip ENDBR32 at the entry of the target function.  */
   18520                 :           0 :       if (need_endbr
   18521                 :           0 :           && !cgraph_node::get (fndecl)->only_called_directly_p ())
   18522                 :           0 :         skip += 4;
   18523                 :           0 :       disp = expand_binop (SImode, sub_optab, fnaddr,
   18524                 :           0 :                            plus_constant (Pmode, XEXP (m_tramp, 0),
   18525                 :           0 :                                           offset - skip),
   18526                 :             :                            NULL_RTX, 1, OPTAB_DIRECT);
   18527                 :           0 :       emit_move_insn (mem, disp);
   18528                 :             :     }
   18529                 :             : 
   18530                 :         269 :   gcc_assert (offset <= TRAMPOLINE_SIZE);
   18531                 :             : 
   18532                 :             : #ifdef HAVE_ENABLE_EXECUTE_STACK
   18533                 :             : #ifdef CHECK_EXECUTE_STACK_ENABLED
   18534                 :             :   if (CHECK_EXECUTE_STACK_ENABLED)
   18535                 :             : #endif
   18536                 :             :   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
   18537                 :             :                      LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
   18538                 :             : #endif
   18539                 :         269 : }
   18540                 :             : 
   18541                 :             : static bool
   18542                 :    49234076 : ix86_allocate_stack_slots_for_args (void)
   18543                 :             : {
   18544                 :             :   /* Naked functions should not allocate stack slots for arguments.  */
   18545                 :    49234076 :   return !ix86_function_naked (current_function_decl);
   18546                 :             : }
   18547                 :             : 
   18548                 :             : static bool
   18549                 :    29449220 : ix86_warn_func_return (tree decl)
   18550                 :             : {
   18551                 :             :   /* Naked functions are implemented entirely in assembly, including the
   18552                 :             :      return sequence, so suppress warnings about this.  */
   18553                 :    29449220 :   return !ix86_function_naked (decl);
   18554                 :             : }
   18555                 :             : 
   18556                 :             : /* Return the shift count of a vector by scalar shift builtin second argument
   18557                 :             :    ARG1.  */
   18558                 :             : static tree
   18559                 :       13594 : ix86_vector_shift_count (tree arg1)
   18560                 :             : {
   18561                 :       13594 :   if (tree_fits_uhwi_p (arg1))
   18562                 :             :     return arg1;
   18563                 :        8271 :   else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
   18564                 :             :     {
   18565                 :             :       /* The count argument is weird, passed in as various 128-bit
   18566                 :             :          (or 64-bit) vectors, the low 64 bits from it are the count.  */
   18567                 :         162 :       unsigned char buf[16];
   18568                 :         162 :       int len = native_encode_expr (arg1, buf, 16);
   18569                 :         162 :       if (len == 0)
   18570                 :         162 :         return NULL_TREE;
   18571                 :         162 :       tree t = native_interpret_expr (uint64_type_node, buf, len);
   18572                 :         162 :       if (t && tree_fits_uhwi_p (t))
   18573                 :             :         return t;
   18574                 :             :     }
   18575                 :             :   return NULL_TREE;
   18576                 :             : }
   18577                 :             : 
   18578                 :             : /* Return true if arg_mask is all ones, ELEMS is elements number of
   18579                 :             :    corresponding vector.  */
   18580                 :             : static bool
   18581                 :       20949 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
   18582                 :             : {
   18583                 :       20949 :   if (TREE_CODE (arg_mask) != INTEGER_CST)
   18584                 :             :     return false;
   18585                 :             : 
   18586                 :        6332 :   unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
   18587                 :        6332 :   if (elems == HOST_BITS_PER_WIDE_INT)
   18588                 :          33 :     return  mask == HOST_WIDE_INT_M1U;
   18589                 :        6299 :   if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
   18590                 :        2233 :     return false;
   18591                 :             : 
   18592                 :             :   return true;
   18593                 :             : }
   18594                 :             : 
   18595                 :             : static tree
   18596                 :    58781605 : ix86_fold_builtin (tree fndecl, int n_args,
   18597                 :             :                    tree *args, bool ignore ATTRIBUTE_UNUSED)
   18598                 :             : {
   18599                 :    58781605 :   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
   18600                 :             :     {
   18601                 :    58781605 :       enum ix86_builtins fn_code
   18602                 :    58781605 :         = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   18603                 :    58781605 :       enum rtx_code rcode;
   18604                 :    58781605 :       bool is_vshift;
   18605                 :    58781605 :       unsigned HOST_WIDE_INT mask;
   18606                 :             : 
   18607                 :    58781605 :       switch (fn_code)
   18608                 :             :         {
   18609                 :        6374 :         case IX86_BUILTIN_CPU_IS:
   18610                 :        6374 :         case IX86_BUILTIN_CPU_SUPPORTS:
   18611                 :        6374 :           gcc_assert (n_args == 1);
   18612                 :        6374 :           return fold_builtin_cpu (fndecl, args);
   18613                 :             : 
   18614                 :       19699 :         case IX86_BUILTIN_NANQ:
   18615                 :       19699 :         case IX86_BUILTIN_NANSQ:
   18616                 :       19699 :           {
   18617                 :       19699 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18618                 :       19699 :             const char *str = c_getstr (*args);
   18619                 :       19699 :             int quiet = fn_code == IX86_BUILTIN_NANQ;
   18620                 :       19699 :             REAL_VALUE_TYPE real;
   18621                 :             : 
   18622                 :       19699 :             if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
   18623                 :       19699 :               return build_real (type, real);
   18624                 :           0 :             return NULL_TREE;
   18625                 :             :           }
   18626                 :             : 
   18627                 :         108 :         case IX86_BUILTIN_INFQ:
   18628                 :         108 :         case IX86_BUILTIN_HUGE_VALQ:
   18629                 :         108 :           {
   18630                 :         108 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18631                 :         108 :             REAL_VALUE_TYPE inf;
   18632                 :         108 :             real_inf (&inf);
   18633                 :         108 :             return build_real (type, inf);
   18634                 :             :           }
   18635                 :             : 
   18636                 :       60157 :         case IX86_BUILTIN_TZCNT16:
   18637                 :       60157 :         case IX86_BUILTIN_CTZS:
   18638                 :       60157 :         case IX86_BUILTIN_TZCNT32:
   18639                 :       60157 :         case IX86_BUILTIN_TZCNT64:
   18640                 :       60157 :           gcc_assert (n_args == 1);
   18641                 :       60157 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   18642                 :             :             {
   18643                 :          45 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18644                 :          45 :               tree arg = args[0];
   18645                 :          45 :               if (fn_code == IX86_BUILTIN_TZCNT16
   18646                 :          45 :                   || fn_code == IX86_BUILTIN_CTZS)
   18647                 :           3 :                 arg = fold_convert (short_unsigned_type_node, arg);
   18648                 :          45 :               if (integer_zerop (arg))
   18649                 :           6 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   18650                 :             :               else
   18651                 :          39 :                 return fold_const_call (CFN_CTZ, type, arg);
   18652                 :             :             }
   18653                 :             :           break;
   18654                 :             : 
   18655                 :       50078 :         case IX86_BUILTIN_LZCNT16:
   18656                 :       50078 :         case IX86_BUILTIN_CLZS:
   18657                 :       50078 :         case IX86_BUILTIN_LZCNT32:
   18658                 :       50078 :         case IX86_BUILTIN_LZCNT64:
   18659                 :       50078 :           gcc_assert (n_args == 1);
   18660                 :       50078 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   18661                 :             :             {
   18662                 :          54 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   18663                 :          54 :               tree arg = args[0];
   18664                 :          54 :               if (fn_code == IX86_BUILTIN_LZCNT16
   18665                 :          54 :                   || fn_code == IX86_BUILTIN_CLZS)
   18666                 :          18 :                 arg = fold_convert (short_unsigned_type_node, arg);
   18667                 :          54 :               if (integer_zerop (arg))
   18668                 :           3 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   18669                 :             :               else
   18670                 :          51 :                 return fold_const_call (CFN_CLZ, type, arg);
   18671                 :             :             }
   18672                 :             :           break;
   18673                 :             : 
   18674                 :       59133 :         case IX86_BUILTIN_BEXTR32:
   18675                 :       59133 :         case IX86_BUILTIN_BEXTR64:
   18676                 :       59133 :         case IX86_BUILTIN_BEXTRI32:
   18677                 :       59133 :         case IX86_BUILTIN_BEXTRI64:
   18678                 :       59133 :           gcc_assert (n_args == 2);
   18679                 :       59133 :           if (tree_fits_uhwi_p (args[1]))
   18680                 :             :             {
   18681                 :         144 :               unsigned HOST_WIDE_INT res = 0;
   18682                 :         144 :               unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
   18683                 :         144 :               unsigned int start = tree_to_uhwi (args[1]);
   18684                 :         144 :               unsigned int len = (start & 0xff00) >> 8;
   18685                 :         144 :               start &= 0xff;
   18686                 :         144 :               if (start >= prec || len == 0)
   18687                 :             :                 res = 0;
   18688                 :          41 :               else if (!tree_fits_uhwi_p (args[0]))
   18689                 :             :                 break;
   18690                 :             :               else
   18691                 :          24 :                 res = tree_to_uhwi (args[0]) >> start;
   18692                 :         127 :               if (len > prec)
   18693                 :             :                 len = prec;
   18694                 :         127 :               if (len < HOST_BITS_PER_WIDE_INT)
   18695                 :         118 :                 res &= (HOST_WIDE_INT_1U << len) - 1;
   18696                 :         127 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18697                 :             :             }
   18698                 :             :           break;
   18699                 :             : 
   18700                 :       20272 :         case IX86_BUILTIN_BZHI32:
   18701                 :       20272 :         case IX86_BUILTIN_BZHI64:
   18702                 :       20272 :           gcc_assert (n_args == 2);
   18703                 :       20272 :           if (tree_fits_uhwi_p (args[1]))
   18704                 :             :             {
   18705                 :         188 :               unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
   18706                 :         188 :               if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
   18707                 :             :                 return args[0];
   18708                 :         188 :               if (idx == 0)
   18709                 :          50 :                 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
   18710                 :         138 :               if (!tree_fits_uhwi_p (args[0]))
   18711                 :             :                 break;
   18712                 :          12 :               unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
   18713                 :          12 :               res &= ~(HOST_WIDE_INT_M1U << idx);
   18714                 :          12 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18715                 :             :             }
   18716                 :             :           break;
   18717                 :             : 
   18718                 :       20032 :         case IX86_BUILTIN_PDEP32:
   18719                 :       20032 :         case IX86_BUILTIN_PDEP64:
   18720                 :       20032 :           gcc_assert (n_args == 2);
   18721                 :       20032 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   18722                 :             :             {
   18723                 :          46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   18724                 :          46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   18725                 :          46 :               unsigned HOST_WIDE_INT res = 0;
   18726                 :          46 :               unsigned HOST_WIDE_INT m, k = 1;
   18727                 :        2990 :               for (m = 1; m; m <<= 1)
   18728                 :        2944 :                 if ((mask & m) != 0)
   18729                 :             :                   {
   18730                 :        1440 :                     if ((src & k) != 0)
   18731                 :         789 :                       res |= m;
   18732                 :        1440 :                     k <<= 1;
   18733                 :             :                   }
   18734                 :          46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18735                 :             :             }
   18736                 :             :           break;
   18737                 :             : 
   18738                 :       20034 :         case IX86_BUILTIN_PEXT32:
   18739                 :       20034 :         case IX86_BUILTIN_PEXT64:
   18740                 :       20034 :           gcc_assert (n_args == 2);
   18741                 :       20034 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   18742                 :             :             {
   18743                 :          46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   18744                 :          46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   18745                 :          46 :               unsigned HOST_WIDE_INT res = 0;
   18746                 :          46 :               unsigned HOST_WIDE_INT m, k = 1;
   18747                 :        2990 :               for (m = 1; m; m <<= 1)
   18748                 :        2944 :                 if ((mask & m) != 0)
   18749                 :             :                   {
   18750                 :        2016 :                     if ((src & m) != 0)
   18751                 :        1063 :                       res |= k;
   18752                 :        2016 :                     k <<= 1;
   18753                 :             :                   }
   18754                 :          46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18755                 :             :             }
   18756                 :             :           break;
   18757                 :             : 
   18758                 :       78521 :         case IX86_BUILTIN_MOVMSKPS:
   18759                 :       78521 :         case IX86_BUILTIN_PMOVMSKB:
   18760                 :       78521 :         case IX86_BUILTIN_MOVMSKPD:
   18761                 :       78521 :         case IX86_BUILTIN_PMOVMSKB128:
   18762                 :       78521 :         case IX86_BUILTIN_MOVMSKPD256:
   18763                 :       78521 :         case IX86_BUILTIN_MOVMSKPS256:
   18764                 :       78521 :         case IX86_BUILTIN_PMOVMSKB256:
   18765                 :       78521 :           gcc_assert (n_args == 1);
   18766                 :       78521 :           if (TREE_CODE (args[0]) == VECTOR_CST)
   18767                 :             :             {
   18768                 :             :               HOST_WIDE_INT res = 0;
   18769                 :         139 :               for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
   18770                 :             :                 {
   18771                 :         124 :                   tree e = VECTOR_CST_ELT (args[0], i);
   18772                 :         124 :                   if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
   18773                 :             :                     {
   18774                 :          80 :                       if (wi::neg_p (wi::to_wide (e)))
   18775                 :          31 :                         res |= HOST_WIDE_INT_1 << i;
   18776                 :             :                     }
   18777                 :          44 :                   else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
   18778                 :             :                     {
   18779                 :          44 :                       if (TREE_REAL_CST (e).sign)
   18780                 :          19 :                         res |= HOST_WIDE_INT_1 << i;
   18781                 :             :                     }
   18782                 :             :                   else
   18783                 :             :                     return NULL_TREE;
   18784                 :             :                 }
   18785                 :          15 :               return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
   18786                 :             :             }
   18787                 :             :           break;
   18788                 :             : 
   18789                 :      636099 :         case IX86_BUILTIN_PSLLD:
   18790                 :      636099 :         case IX86_BUILTIN_PSLLD128:
   18791                 :      636099 :         case IX86_BUILTIN_PSLLD128_MASK:
   18792                 :      636099 :         case IX86_BUILTIN_PSLLD256:
   18793                 :      636099 :         case IX86_BUILTIN_PSLLD256_MASK:
   18794                 :      636099 :         case IX86_BUILTIN_PSLLD512:
   18795                 :      636099 :         case IX86_BUILTIN_PSLLDI:
   18796                 :      636099 :         case IX86_BUILTIN_PSLLDI128:
   18797                 :      636099 :         case IX86_BUILTIN_PSLLDI128_MASK:
   18798                 :      636099 :         case IX86_BUILTIN_PSLLDI256:
   18799                 :      636099 :         case IX86_BUILTIN_PSLLDI256_MASK:
   18800                 :      636099 :         case IX86_BUILTIN_PSLLDI512:
   18801                 :      636099 :         case IX86_BUILTIN_PSLLQ:
   18802                 :      636099 :         case IX86_BUILTIN_PSLLQ128:
   18803                 :      636099 :         case IX86_BUILTIN_PSLLQ128_MASK:
   18804                 :      636099 :         case IX86_BUILTIN_PSLLQ256:
   18805                 :      636099 :         case IX86_BUILTIN_PSLLQ256_MASK:
   18806                 :      636099 :         case IX86_BUILTIN_PSLLQ512:
   18807                 :      636099 :         case IX86_BUILTIN_PSLLQI:
   18808                 :      636099 :         case IX86_BUILTIN_PSLLQI128:
   18809                 :      636099 :         case IX86_BUILTIN_PSLLQI128_MASK:
   18810                 :      636099 :         case IX86_BUILTIN_PSLLQI256:
   18811                 :      636099 :         case IX86_BUILTIN_PSLLQI256_MASK:
   18812                 :      636099 :         case IX86_BUILTIN_PSLLQI512:
   18813                 :      636099 :         case IX86_BUILTIN_PSLLW:
   18814                 :      636099 :         case IX86_BUILTIN_PSLLW128:
   18815                 :      636099 :         case IX86_BUILTIN_PSLLW128_MASK:
   18816                 :      636099 :         case IX86_BUILTIN_PSLLW256:
   18817                 :      636099 :         case IX86_BUILTIN_PSLLW256_MASK:
   18818                 :      636099 :         case IX86_BUILTIN_PSLLW512_MASK:
   18819                 :      636099 :         case IX86_BUILTIN_PSLLWI:
   18820                 :      636099 :         case IX86_BUILTIN_PSLLWI128:
   18821                 :      636099 :         case IX86_BUILTIN_PSLLWI128_MASK:
   18822                 :      636099 :         case IX86_BUILTIN_PSLLWI256:
   18823                 :      636099 :         case IX86_BUILTIN_PSLLWI256_MASK:
   18824                 :      636099 :         case IX86_BUILTIN_PSLLWI512_MASK:
   18825                 :      636099 :           rcode = ASHIFT;
   18826                 :      636099 :           is_vshift = false;
   18827                 :      636099 :           goto do_shift;
   18828                 :      582532 :         case IX86_BUILTIN_PSRAD:
   18829                 :      582532 :         case IX86_BUILTIN_PSRAD128:
   18830                 :      582532 :         case IX86_BUILTIN_PSRAD128_MASK:
   18831                 :      582532 :         case IX86_BUILTIN_PSRAD256:
   18832                 :      582532 :         case IX86_BUILTIN_PSRAD256_MASK:
   18833                 :      582532 :         case IX86_BUILTIN_PSRAD512:
   18834                 :      582532 :         case IX86_BUILTIN_PSRADI:
   18835                 :      582532 :         case IX86_BUILTIN_PSRADI128:
   18836                 :      582532 :         case IX86_BUILTIN_PSRADI128_MASK:
   18837                 :      582532 :         case IX86_BUILTIN_PSRADI256:
   18838                 :      582532 :         case IX86_BUILTIN_PSRADI256_MASK:
   18839                 :      582532 :         case IX86_BUILTIN_PSRADI512:
   18840                 :      582532 :         case IX86_BUILTIN_PSRAQ128_MASK:
   18841                 :      582532 :         case IX86_BUILTIN_PSRAQ256_MASK:
   18842                 :      582532 :         case IX86_BUILTIN_PSRAQ512:
   18843                 :      582532 :         case IX86_BUILTIN_PSRAQI128_MASK:
   18844                 :      582532 :         case IX86_BUILTIN_PSRAQI256_MASK:
   18845                 :      582532 :         case IX86_BUILTIN_PSRAQI512:
   18846                 :      582532 :         case IX86_BUILTIN_PSRAW:
   18847                 :      582532 :         case IX86_BUILTIN_PSRAW128:
   18848                 :      582532 :         case IX86_BUILTIN_PSRAW128_MASK:
   18849                 :      582532 :         case IX86_BUILTIN_PSRAW256:
   18850                 :      582532 :         case IX86_BUILTIN_PSRAW256_MASK:
   18851                 :      582532 :         case IX86_BUILTIN_PSRAW512:
   18852                 :      582532 :         case IX86_BUILTIN_PSRAWI:
   18853                 :      582532 :         case IX86_BUILTIN_PSRAWI128:
   18854                 :      582532 :         case IX86_BUILTIN_PSRAWI128_MASK:
   18855                 :      582532 :         case IX86_BUILTIN_PSRAWI256:
   18856                 :      582532 :         case IX86_BUILTIN_PSRAWI256_MASK:
   18857                 :      582532 :         case IX86_BUILTIN_PSRAWI512:
   18858                 :      582532 :           rcode = ASHIFTRT;
   18859                 :      582532 :           is_vshift = false;
   18860                 :      582532 :           goto do_shift;
   18861                 :      613948 :         case IX86_BUILTIN_PSRLD:
   18862                 :      613948 :         case IX86_BUILTIN_PSRLD128:
   18863                 :      613948 :         case IX86_BUILTIN_PSRLD128_MASK:
   18864                 :      613948 :         case IX86_BUILTIN_PSRLD256:
   18865                 :      613948 :         case IX86_BUILTIN_PSRLD256_MASK:
   18866                 :      613948 :         case IX86_BUILTIN_PSRLD512:
   18867                 :      613948 :         case IX86_BUILTIN_PSRLDI:
   18868                 :      613948 :         case IX86_BUILTIN_PSRLDI128:
   18869                 :      613948 :         case IX86_BUILTIN_PSRLDI128_MASK:
   18870                 :      613948 :         case IX86_BUILTIN_PSRLDI256:
   18871                 :      613948 :         case IX86_BUILTIN_PSRLDI256_MASK:
   18872                 :      613948 :         case IX86_BUILTIN_PSRLDI512:
   18873                 :      613948 :         case IX86_BUILTIN_PSRLQ:
   18874                 :      613948 :         case IX86_BUILTIN_PSRLQ128:
   18875                 :      613948 :         case IX86_BUILTIN_PSRLQ128_MASK:
   18876                 :      613948 :         case IX86_BUILTIN_PSRLQ256:
   18877                 :      613948 :         case IX86_BUILTIN_PSRLQ256_MASK:
   18878                 :      613948 :         case IX86_BUILTIN_PSRLQ512:
   18879                 :      613948 :         case IX86_BUILTIN_PSRLQI:
   18880                 :      613948 :         case IX86_BUILTIN_PSRLQI128:
   18881                 :      613948 :         case IX86_BUILTIN_PSRLQI128_MASK:
   18882                 :      613948 :         case IX86_BUILTIN_PSRLQI256:
   18883                 :      613948 :         case IX86_BUILTIN_PSRLQI256_MASK:
   18884                 :      613948 :         case IX86_BUILTIN_PSRLQI512:
   18885                 :      613948 :         case IX86_BUILTIN_PSRLW:
   18886                 :      613948 :         case IX86_BUILTIN_PSRLW128:
   18887                 :      613948 :         case IX86_BUILTIN_PSRLW128_MASK:
   18888                 :      613948 :         case IX86_BUILTIN_PSRLW256:
   18889                 :      613948 :         case IX86_BUILTIN_PSRLW256_MASK:
   18890                 :      613948 :         case IX86_BUILTIN_PSRLW512:
   18891                 :      613948 :         case IX86_BUILTIN_PSRLWI:
   18892                 :      613948 :         case IX86_BUILTIN_PSRLWI128:
   18893                 :      613948 :         case IX86_BUILTIN_PSRLWI128_MASK:
   18894                 :      613948 :         case IX86_BUILTIN_PSRLWI256:
   18895                 :      613948 :         case IX86_BUILTIN_PSRLWI256_MASK:
   18896                 :      613948 :         case IX86_BUILTIN_PSRLWI512:
   18897                 :      613948 :           rcode = LSHIFTRT;
   18898                 :      613948 :           is_vshift = false;
   18899                 :      613948 :           goto do_shift;
   18900                 :      266081 :         case IX86_BUILTIN_PSLLVV16HI:
   18901                 :      266081 :         case IX86_BUILTIN_PSLLVV16SI:
   18902                 :      266081 :         case IX86_BUILTIN_PSLLVV2DI:
   18903                 :      266081 :         case IX86_BUILTIN_PSLLVV2DI_MASK:
   18904                 :      266081 :         case IX86_BUILTIN_PSLLVV32HI:
   18905                 :      266081 :         case IX86_BUILTIN_PSLLVV4DI:
   18906                 :      266081 :         case IX86_BUILTIN_PSLLVV4DI_MASK:
   18907                 :      266081 :         case IX86_BUILTIN_PSLLVV4SI:
   18908                 :      266081 :         case IX86_BUILTIN_PSLLVV4SI_MASK:
   18909                 :      266081 :         case IX86_BUILTIN_PSLLVV8DI:
   18910                 :      266081 :         case IX86_BUILTIN_PSLLVV8HI:
   18911                 :      266081 :         case IX86_BUILTIN_PSLLVV8SI:
   18912                 :      266081 :         case IX86_BUILTIN_PSLLVV8SI_MASK:
   18913                 :      266081 :           rcode = ASHIFT;
   18914                 :      266081 :           is_vshift = true;
   18915                 :      266081 :           goto do_shift;
   18916                 :      265692 :         case IX86_BUILTIN_PSRAVQ128:
   18917                 :      265692 :         case IX86_BUILTIN_PSRAVQ256:
   18918                 :      265692 :         case IX86_BUILTIN_PSRAVV16HI:
   18919                 :      265692 :         case IX86_BUILTIN_PSRAVV16SI:
   18920                 :      265692 :         case IX86_BUILTIN_PSRAVV32HI:
   18921                 :      265692 :         case IX86_BUILTIN_PSRAVV4SI:
   18922                 :      265692 :         case IX86_BUILTIN_PSRAVV4SI_MASK:
   18923                 :      265692 :         case IX86_BUILTIN_PSRAVV8DI:
   18924                 :      265692 :         case IX86_BUILTIN_PSRAVV8HI:
   18925                 :      265692 :         case IX86_BUILTIN_PSRAVV8SI:
   18926                 :      265692 :         case IX86_BUILTIN_PSRAVV8SI_MASK:
   18927                 :      265692 :           rcode = ASHIFTRT;
   18928                 :      265692 :           is_vshift = true;
   18929                 :      265692 :           goto do_shift;
   18930                 :      266072 :         case IX86_BUILTIN_PSRLVV16HI:
   18931                 :      266072 :         case IX86_BUILTIN_PSRLVV16SI:
   18932                 :      266072 :         case IX86_BUILTIN_PSRLVV2DI:
   18933                 :      266072 :         case IX86_BUILTIN_PSRLVV2DI_MASK:
   18934                 :      266072 :         case IX86_BUILTIN_PSRLVV32HI:
   18935                 :      266072 :         case IX86_BUILTIN_PSRLVV4DI:
   18936                 :      266072 :         case IX86_BUILTIN_PSRLVV4DI_MASK:
   18937                 :      266072 :         case IX86_BUILTIN_PSRLVV4SI:
   18938                 :      266072 :         case IX86_BUILTIN_PSRLVV4SI_MASK:
   18939                 :      266072 :         case IX86_BUILTIN_PSRLVV8DI:
   18940                 :      266072 :         case IX86_BUILTIN_PSRLVV8HI:
   18941                 :      266072 :         case IX86_BUILTIN_PSRLVV8SI:
   18942                 :      266072 :         case IX86_BUILTIN_PSRLVV8SI_MASK:
   18943                 :      266072 :           rcode = LSHIFTRT;
   18944                 :      266072 :           is_vshift = true;
   18945                 :      266072 :           goto do_shift;
   18946                 :             : 
   18947                 :     2630424 :         do_shift:
   18948                 :     2630424 :           gcc_assert (n_args >= 2);
   18949                 :     2630424 :           if (TREE_CODE (args[0]) != VECTOR_CST)
   18950                 :             :             break;
   18951                 :         912 :           mask = HOST_WIDE_INT_M1U;
   18952                 :         912 :           if (n_args > 2)
   18953                 :             :             {
   18954                 :             :               /* This is masked shift.  */
   18955                 :         667 :               if (!tree_fits_uhwi_p (args[n_args - 1])
   18956                 :         667 :                   || TREE_SIDE_EFFECTS (args[n_args - 2]))
   18957                 :             :                 break;
   18958                 :         667 :               mask = tree_to_uhwi (args[n_args - 1]);
   18959                 :         667 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   18960                 :         667 :               mask |= HOST_WIDE_INT_M1U << elems;
   18961                 :         667 :               if (mask != HOST_WIDE_INT_M1U
   18962                 :         556 :                   && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
   18963                 :             :                 break;
   18964                 :         633 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   18965                 :             :                 return args[n_args - 2];
   18966                 :             :             }
   18967                 :         875 :           if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
   18968                 :             :             break;
   18969                 :         178 :           if (tree tem = (is_vshift ? integer_one_node
   18970                 :         875 :                           : ix86_vector_shift_count (args[1])))
   18971                 :             :             {
   18972                 :         554 :               unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
   18973                 :         554 :               unsigned HOST_WIDE_INT prec
   18974                 :         554 :                 = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
   18975                 :         554 :               if (count == 0 && mask == HOST_WIDE_INT_M1U)
   18976                 :             :                 return args[0];
   18977                 :         554 :               if (count >= prec)
   18978                 :             :                 {
   18979                 :          72 :                   if (rcode == ASHIFTRT)
   18980                 :          27 :                     count = prec - 1;
   18981                 :          45 :                   else if (mask == HOST_WIDE_INT_M1U)
   18982                 :           3 :                     return build_zero_cst (TREE_TYPE (args[0]));
   18983                 :             :                 }
   18984                 :         551 :               tree countt = NULL_TREE;
   18985                 :         551 :               if (!is_vshift)
   18986                 :             :                 {
   18987                 :         373 :                   if (count >= prec)
   18988                 :          42 :                     countt = integer_zero_node;
   18989                 :             :                   else
   18990                 :         331 :                     countt = build_int_cst (integer_type_node, count);
   18991                 :             :                 }
   18992                 :         551 :               tree_vector_builder builder;
   18993                 :         551 :               if (mask != HOST_WIDE_INT_M1U || is_vshift)
   18994                 :         392 :                 builder.new_vector (TREE_TYPE (args[0]),
   18995                 :         784 :                                     TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
   18996                 :             :                                     1);
   18997                 :             :               else
   18998                 :         159 :                 builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
   18999                 :             :                                              false);
   19000                 :         551 :               unsigned int cnt = builder.encoded_nelts ();
   19001                 :        5959 :               for (unsigned int i = 0; i < cnt; ++i)
   19002                 :             :                 {
   19003                 :        5408 :                   tree elt = VECTOR_CST_ELT (args[0], i);
   19004                 :        5408 :                   if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
   19005                 :           0 :                     return NULL_TREE;
   19006                 :        5408 :                   tree type = TREE_TYPE (elt);
   19007                 :        5408 :                   if (rcode == LSHIFTRT)
   19008                 :        2036 :                     elt = fold_convert (unsigned_type_for (type), elt);
   19009                 :        5408 :                   if (is_vshift)
   19010                 :             :                     {
   19011                 :        1846 :                       countt = VECTOR_CST_ELT (args[1], i);
   19012                 :        1846 :                       if (TREE_CODE (countt) != INTEGER_CST
   19013                 :        1846 :                           || TREE_OVERFLOW (countt))
   19014                 :             :                         return NULL_TREE;
   19015                 :        1846 :                       if (wi::neg_p (wi::to_wide (countt))
   19016                 :        3610 :                           || wi::to_widest (countt) >= prec)
   19017                 :             :                         {
   19018                 :         325 :                           if (rcode == ASHIFTRT)
   19019                 :         108 :                             countt = build_int_cst (TREE_TYPE (countt),
   19020                 :         108 :                                                     prec - 1);
   19021                 :             :                           else
   19022                 :             :                             {
   19023                 :         217 :                               elt = build_zero_cst (TREE_TYPE (elt));
   19024                 :         217 :                               countt = build_zero_cst (TREE_TYPE (countt));
   19025                 :             :                             }
   19026                 :             :                         }
   19027                 :             :                     }
   19028                 :        3562 :                   else if (count >= prec)
   19029                 :         504 :                     elt = build_zero_cst (TREE_TYPE (elt));
   19030                 :        8942 :                   elt = const_binop (rcode == ASHIFT
   19031                 :             :                                      ? LSHIFT_EXPR : RSHIFT_EXPR,
   19032                 :        5408 :                                      TREE_TYPE (elt), elt, countt);
   19033                 :        5408 :                   if (!elt || TREE_CODE (elt) != INTEGER_CST)
   19034                 :             :                     return NULL_TREE;
   19035                 :        5408 :                   if (rcode == LSHIFTRT)
   19036                 :        2036 :                     elt = fold_convert (type, elt);
   19037                 :        5408 :                   if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
   19038                 :             :                     {
   19039                 :        1566 :                       elt = VECTOR_CST_ELT (args[n_args - 2], i);
   19040                 :        1566 :                       if (TREE_CODE (elt) != INTEGER_CST
   19041                 :        1566 :                           || TREE_OVERFLOW (elt))
   19042                 :             :                         return NULL_TREE;
   19043                 :             :                     }
   19044                 :        5408 :                   builder.quick_push (elt);
   19045                 :             :                 }
   19046                 :         551 :               return builder.build ();
   19047                 :         551 :             }
   19048                 :             :           break;
   19049                 :             : 
   19050                 :             :         default:
   19051                 :             :           break;
   19052                 :             :         }
   19053                 :             :     }
   19054                 :             : 
   19055                 :             : #ifdef SUBTARGET_FOLD_BUILTIN
   19056                 :             :   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
   19057                 :             : #endif
   19058                 :             : 
   19059                 :             :   return NULL_TREE;
   19060                 :             : }
   19061                 :             : 
   19062                 :             : /* Fold a MD builtin (use ix86_fold_builtin for folding into
   19063                 :             :    constant) in GIMPLE.  */
   19064                 :             : 
   19065                 :             : bool
   19066                 :     1034475 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   19067                 :             : {
   19068                 :     1034475 :   gimple *stmt = gsi_stmt (*gsi), *g;
   19069                 :     1034475 :   gimple_seq stmts = NULL;
   19070                 :     1034475 :   tree fndecl = gimple_call_fndecl (stmt);
   19071                 :     1034475 :   gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
   19072                 :     1034475 :   int n_args = gimple_call_num_args (stmt);
   19073                 :     1034475 :   enum ix86_builtins fn_code
   19074                 :     1034475 :     = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19075                 :     1034475 :   tree decl = NULL_TREE;
   19076                 :     1034475 :   tree arg0, arg1, arg2;
   19077                 :     1034475 :   enum rtx_code rcode;
   19078                 :     1034475 :   enum tree_code tcode;
   19079                 :     1034475 :   unsigned HOST_WIDE_INT count;
   19080                 :     1034475 :   bool is_vshift;
   19081                 :     1034475 :   unsigned HOST_WIDE_INT elems;
   19082                 :     1034475 :   location_t loc;
   19083                 :             : 
   19084                 :             :   /* Don't fold when there's isa mismatch.  */
   19085                 :     1034475 :   if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
   19086                 :             :     return false;
   19087                 :             : 
   19088                 :     1034364 :   switch (fn_code)
   19089                 :             :     {
   19090                 :         284 :     case IX86_BUILTIN_TZCNT32:
   19091                 :         284 :       decl = builtin_decl_implicit (BUILT_IN_CTZ);
   19092                 :         284 :       goto fold_tzcnt_lzcnt;
   19093                 :             : 
   19094                 :         237 :     case IX86_BUILTIN_TZCNT64:
   19095                 :         237 :       decl = builtin_decl_implicit (BUILT_IN_CTZLL);
   19096                 :         237 :       goto fold_tzcnt_lzcnt;
   19097                 :             : 
   19098                 :         215 :     case IX86_BUILTIN_LZCNT32:
   19099                 :         215 :       decl = builtin_decl_implicit (BUILT_IN_CLZ);
   19100                 :         215 :       goto fold_tzcnt_lzcnt;
   19101                 :             : 
   19102                 :         224 :     case IX86_BUILTIN_LZCNT64:
   19103                 :         224 :       decl = builtin_decl_implicit (BUILT_IN_CLZLL);
   19104                 :         224 :       goto fold_tzcnt_lzcnt;
   19105                 :             : 
   19106                 :         960 :     fold_tzcnt_lzcnt:
   19107                 :         960 :       gcc_assert (n_args == 1);
   19108                 :         960 :       arg0 = gimple_call_arg (stmt, 0);
   19109                 :         960 :       if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
   19110                 :             :         {
   19111                 :         796 :           int prec = TYPE_PRECISION (TREE_TYPE (arg0));
   19112                 :             :           /* If arg0 is provably non-zero, optimize into generic
   19113                 :             :              __builtin_c[tl]z{,ll} function the middle-end handles
   19114                 :             :              better.  */
   19115                 :         796 :           if (!expr_not_equal_to (arg0, wi::zero (prec)))
   19116                 :             :             return false;
   19117                 :             : 
   19118                 :           9 :           loc = gimple_location (stmt);
   19119                 :           9 :           g = gimple_build_call (decl, 1, arg0);
   19120                 :           9 :           gimple_set_location (g, loc);
   19121                 :           9 :           tree lhs = make_ssa_name (integer_type_node);
   19122                 :           9 :           gimple_call_set_lhs (g, lhs);
   19123                 :           9 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
   19124                 :           9 :           g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
   19125                 :           9 :           gimple_set_location (g, loc);
   19126                 :           9 :           gsi_replace (gsi, g, false);
   19127                 :           9 :           return true;
   19128                 :             :         }
   19129                 :             :       break;
   19130                 :             : 
   19131                 :         491 :     case IX86_BUILTIN_BZHI32:
   19132                 :         491 :     case IX86_BUILTIN_BZHI64:
   19133                 :         491 :       gcc_assert (n_args == 2);
   19134                 :         491 :       arg1 = gimple_call_arg (stmt, 1);
   19135                 :         491 :       if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
   19136                 :             :         {
   19137                 :         195 :           unsigned int idx = tree_to_uhwi (arg1) & 0xff;
   19138                 :         195 :           arg0 = gimple_call_arg (stmt, 0);
   19139                 :         195 :           if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
   19140                 :             :             break;
   19141                 :          31 :           loc = gimple_location (stmt);
   19142                 :          31 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19143                 :          31 :           gimple_set_location (g, loc);
   19144                 :          31 :           gsi_replace (gsi, g, false);
   19145                 :          31 :           return true;
   19146                 :             :         }
   19147                 :             :       break;
   19148                 :             : 
   19149                 :         502 :     case IX86_BUILTIN_PDEP32:
   19150                 :         502 :     case IX86_BUILTIN_PDEP64:
   19151                 :         502 :     case IX86_BUILTIN_PEXT32:
   19152                 :         502 :     case IX86_BUILTIN_PEXT64:
   19153                 :         502 :       gcc_assert (n_args == 2);
   19154                 :         502 :       arg1 = gimple_call_arg (stmt, 1);
   19155                 :         502 :       if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
   19156                 :             :         {
   19157                 :           4 :           loc = gimple_location (stmt);
   19158                 :           4 :           arg0 = gimple_call_arg (stmt, 0);
   19159                 :           4 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19160                 :           4 :           gimple_set_location (g, loc);
   19161                 :           4 :           gsi_replace (gsi, g, false);
   19162                 :           4 :           return true;
   19163                 :             :         }
   19164                 :             :       break;
   19165                 :             : 
   19166                 :         145 :     case IX86_BUILTIN_PBLENDVB256:
   19167                 :         145 :     case IX86_BUILTIN_BLENDVPS256:
   19168                 :         145 :     case IX86_BUILTIN_BLENDVPD256:
   19169                 :             :       /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
   19170                 :             :          to scalar operations and not combined back.  */
   19171                 :         145 :       if (!TARGET_AVX2)
   19172                 :             :         break;
   19173                 :             : 
   19174                 :             :       /* FALLTHRU.  */
   19175                 :         112 :     case IX86_BUILTIN_BLENDVPD:
   19176                 :             :       /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
   19177                 :             :          w/o sse4.2, it's veclowered to scalar operations and
   19178                 :             :          not combined back.  */
   19179                 :         112 :       if (!TARGET_SSE4_2)
   19180                 :             :         break;
   19181                 :             :       /* FALLTHRU.  */
   19182                 :         149 :     case IX86_BUILTIN_PBLENDVB128:
   19183                 :         149 :     case IX86_BUILTIN_BLENDVPS:
   19184                 :         149 :       gcc_assert (n_args == 3);
   19185                 :         149 :       arg0 = gimple_call_arg (stmt, 0);
   19186                 :         149 :       arg1 = gimple_call_arg (stmt, 1);
   19187                 :         149 :       arg2 = gimple_call_arg (stmt, 2);
   19188                 :         149 :       if (gimple_call_lhs (stmt))
   19189                 :             :         {
   19190                 :         149 :           loc = gimple_location (stmt);
   19191                 :         149 :           tree type = TREE_TYPE (arg2);
   19192                 :         149 :           if (VECTOR_FLOAT_TYPE_P (type))
   19193                 :             :             {
   19194                 :          71 :               tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
   19195                 :          71 :                 ? intSI_type_node : intDI_type_node;
   19196                 :          71 :               type = get_same_sized_vectype (itype, type);
   19197                 :             :             }
   19198                 :             :           else
   19199                 :          78 :             type = signed_type_for (type);
   19200                 :         149 :           arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
   19201                 :         149 :           tree zero_vec = build_zero_cst (type);
   19202                 :         149 :           tree cmp_type = truth_type_for (type);
   19203                 :         149 :           tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
   19204                 :         149 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19205                 :         149 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19206                 :             :                                    VEC_COND_EXPR, cmp,
   19207                 :             :                                    arg1, arg0);
   19208                 :         149 :           gimple_set_location (g, loc);
   19209                 :         149 :           gsi_replace (gsi, g, false);
   19210                 :             :         }
   19211                 :             :       else
   19212                 :           0 :         gsi_replace (gsi, gimple_build_nop (), false);
   19213                 :             :       return true;
   19214                 :             : 
   19215                 :             : 
   19216                 :          16 :     case IX86_BUILTIN_PCMPEQB128:
   19217                 :          16 :     case IX86_BUILTIN_PCMPEQW128:
   19218                 :          16 :     case IX86_BUILTIN_PCMPEQD128:
   19219                 :          16 :     case IX86_BUILTIN_PCMPEQQ:
   19220                 :          16 :     case IX86_BUILTIN_PCMPEQB256:
   19221                 :          16 :     case IX86_BUILTIN_PCMPEQW256:
   19222                 :          16 :     case IX86_BUILTIN_PCMPEQD256:
   19223                 :          16 :     case IX86_BUILTIN_PCMPEQQ256:
   19224                 :          16 :       tcode = EQ_EXPR;
   19225                 :          16 :       goto do_cmp;
   19226                 :             : 
   19227                 :             :     case IX86_BUILTIN_PCMPGTB128:
   19228                 :             :     case IX86_BUILTIN_PCMPGTW128:
   19229                 :             :     case IX86_BUILTIN_PCMPGTD128:
   19230                 :             :     case IX86_BUILTIN_PCMPGTQ:
   19231                 :             :     case IX86_BUILTIN_PCMPGTB256:
   19232                 :             :     case IX86_BUILTIN_PCMPGTW256:
   19233                 :             :     case IX86_BUILTIN_PCMPGTD256:
   19234                 :             :     case IX86_BUILTIN_PCMPGTQ256:
   19235                 :             :       tcode = GT_EXPR;
   19236                 :             : 
   19237                 :          33 :     do_cmp:
   19238                 :          33 :       gcc_assert (n_args == 2);
   19239                 :          33 :       arg0 = gimple_call_arg (stmt, 0);
   19240                 :          33 :       arg1 = gimple_call_arg (stmt, 1);
   19241                 :          33 :       if (gimple_call_lhs (stmt))
   19242                 :             :         {
   19243                 :          32 :           loc = gimple_location (stmt);
   19244                 :          32 :           tree type = TREE_TYPE (arg0);
   19245                 :          32 :           tree zero_vec = build_zero_cst (type);
   19246                 :          32 :           tree minus_one_vec = build_minus_one_cst (type);
   19247                 :          32 :           tree cmp_type = truth_type_for (type);
   19248                 :          32 :           tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
   19249                 :          32 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19250                 :          32 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19251                 :             :                                    VEC_COND_EXPR, cmp,
   19252                 :             :                                    minus_one_vec, zero_vec);
   19253                 :          32 :           gimple_set_location (g, loc);
   19254                 :          32 :           gsi_replace (gsi, g, false);
   19255                 :             :         }
   19256                 :             :       else
   19257                 :           1 :         gsi_replace (gsi, gimple_build_nop (), false);
   19258                 :             :       return true;
   19259                 :             : 
   19260                 :        8591 :     case IX86_BUILTIN_PSLLD:
   19261                 :        8591 :     case IX86_BUILTIN_PSLLD128:
   19262                 :        8591 :     case IX86_BUILTIN_PSLLD128_MASK:
   19263                 :        8591 :     case IX86_BUILTIN_PSLLD256:
   19264                 :        8591 :     case IX86_BUILTIN_PSLLD256_MASK:
   19265                 :        8591 :     case IX86_BUILTIN_PSLLD512:
   19266                 :        8591 :     case IX86_BUILTIN_PSLLDI:
   19267                 :        8591 :     case IX86_BUILTIN_PSLLDI128:
   19268                 :        8591 :     case IX86_BUILTIN_PSLLDI128_MASK:
   19269                 :        8591 :     case IX86_BUILTIN_PSLLDI256:
   19270                 :        8591 :     case IX86_BUILTIN_PSLLDI256_MASK:
   19271                 :        8591 :     case IX86_BUILTIN_PSLLDI512:
   19272                 :        8591 :     case IX86_BUILTIN_PSLLQ:
   19273                 :        8591 :     case IX86_BUILTIN_PSLLQ128:
   19274                 :        8591 :     case IX86_BUILTIN_PSLLQ128_MASK:
   19275                 :        8591 :     case IX86_BUILTIN_PSLLQ256:
   19276                 :        8591 :     case IX86_BUILTIN_PSLLQ256_MASK:
   19277                 :        8591 :     case IX86_BUILTIN_PSLLQ512:
   19278                 :        8591 :     case IX86_BUILTIN_PSLLQI:
   19279                 :        8591 :     case IX86_BUILTIN_PSLLQI128:
   19280                 :        8591 :     case IX86_BUILTIN_PSLLQI128_MASK:
   19281                 :        8591 :     case IX86_BUILTIN_PSLLQI256:
   19282                 :        8591 :     case IX86_BUILTIN_PSLLQI256_MASK:
   19283                 :        8591 :     case IX86_BUILTIN_PSLLQI512:
   19284                 :        8591 :     case IX86_BUILTIN_PSLLW:
   19285                 :        8591 :     case IX86_BUILTIN_PSLLW128:
   19286                 :        8591 :     case IX86_BUILTIN_PSLLW128_MASK:
   19287                 :        8591 :     case IX86_BUILTIN_PSLLW256:
   19288                 :        8591 :     case IX86_BUILTIN_PSLLW256_MASK:
   19289                 :        8591 :     case IX86_BUILTIN_PSLLW512_MASK:
   19290                 :        8591 :     case IX86_BUILTIN_PSLLWI:
   19291                 :        8591 :     case IX86_BUILTIN_PSLLWI128:
   19292                 :        8591 :     case IX86_BUILTIN_PSLLWI128_MASK:
   19293                 :        8591 :     case IX86_BUILTIN_PSLLWI256:
   19294                 :        8591 :     case IX86_BUILTIN_PSLLWI256_MASK:
   19295                 :        8591 :     case IX86_BUILTIN_PSLLWI512_MASK:
   19296                 :        8591 :       rcode = ASHIFT;
   19297                 :        8591 :       is_vshift = false;
   19298                 :        8591 :       goto do_shift;
   19299                 :        6510 :     case IX86_BUILTIN_PSRAD:
   19300                 :        6510 :     case IX86_BUILTIN_PSRAD128:
   19301                 :        6510 :     case IX86_BUILTIN_PSRAD128_MASK:
   19302                 :        6510 :     case IX86_BUILTIN_PSRAD256:
   19303                 :        6510 :     case IX86_BUILTIN_PSRAD256_MASK:
   19304                 :        6510 :     case IX86_BUILTIN_PSRAD512:
   19305                 :        6510 :     case IX86_BUILTIN_PSRADI:
   19306                 :        6510 :     case IX86_BUILTIN_PSRADI128:
   19307                 :        6510 :     case IX86_BUILTIN_PSRADI128_MASK:
   19308                 :        6510 :     case IX86_BUILTIN_PSRADI256:
   19309                 :        6510 :     case IX86_BUILTIN_PSRADI256_MASK:
   19310                 :        6510 :     case IX86_BUILTIN_PSRADI512:
   19311                 :        6510 :     case IX86_BUILTIN_PSRAQ128_MASK:
   19312                 :        6510 :     case IX86_BUILTIN_PSRAQ256_MASK:
   19313                 :        6510 :     case IX86_BUILTIN_PSRAQ512:
   19314                 :        6510 :     case IX86_BUILTIN_PSRAQI128_MASK:
   19315                 :        6510 :     case IX86_BUILTIN_PSRAQI256_MASK:
   19316                 :        6510 :     case IX86_BUILTIN_PSRAQI512:
   19317                 :        6510 :     case IX86_BUILTIN_PSRAW:
   19318                 :        6510 :     case IX86_BUILTIN_PSRAW128:
   19319                 :        6510 :     case IX86_BUILTIN_PSRAW128_MASK:
   19320                 :        6510 :     case IX86_BUILTIN_PSRAW256:
   19321                 :        6510 :     case IX86_BUILTIN_PSRAW256_MASK:
   19322                 :        6510 :     case IX86_BUILTIN_PSRAW512:
   19323                 :        6510 :     case IX86_BUILTIN_PSRAWI:
   19324                 :        6510 :     case IX86_BUILTIN_PSRAWI128:
   19325                 :        6510 :     case IX86_BUILTIN_PSRAWI128_MASK:
   19326                 :        6510 :     case IX86_BUILTIN_PSRAWI256:
   19327                 :        6510 :     case IX86_BUILTIN_PSRAWI256_MASK:
   19328                 :        6510 :     case IX86_BUILTIN_PSRAWI512:
   19329                 :        6510 :       rcode = ASHIFTRT;
   19330                 :        6510 :       is_vshift = false;
   19331                 :        6510 :       goto do_shift;
   19332                 :        7898 :     case IX86_BUILTIN_PSRLD:
   19333                 :        7898 :     case IX86_BUILTIN_PSRLD128:
   19334                 :        7898 :     case IX86_BUILTIN_PSRLD128_MASK:
   19335                 :        7898 :     case IX86_BUILTIN_PSRLD256:
   19336                 :        7898 :     case IX86_BUILTIN_PSRLD256_MASK:
   19337                 :        7898 :     case IX86_BUILTIN_PSRLD512:
   19338                 :        7898 :     case IX86_BUILTIN_PSRLDI:
   19339                 :        7898 :     case IX86_BUILTIN_PSRLDI128:
   19340                 :        7898 :     case IX86_BUILTIN_PSRLDI128_MASK:
   19341                 :        7898 :     case IX86_BUILTIN_PSRLDI256:
   19342                 :        7898 :     case IX86_BUILTIN_PSRLDI256_MASK:
   19343                 :        7898 :     case IX86_BUILTIN_PSRLDI512:
   19344                 :        7898 :     case IX86_BUILTIN_PSRLQ:
   19345                 :        7898 :     case IX86_BUILTIN_PSRLQ128:
   19346                 :        7898 :     case IX86_BUILTIN_PSRLQ128_MASK:
   19347                 :        7898 :     case IX86_BUILTIN_PSRLQ256:
   19348                 :        7898 :     case IX86_BUILTIN_PSRLQ256_MASK:
   19349                 :        7898 :     case IX86_BUILTIN_PSRLQ512:
   19350                 :        7898 :     case IX86_BUILTIN_PSRLQI:
   19351                 :        7898 :     case IX86_BUILTIN_PSRLQI128:
   19352                 :        7898 :     case IX86_BUILTIN_PSRLQI128_MASK:
   19353                 :        7898 :     case IX86_BUILTIN_PSRLQI256:
   19354                 :        7898 :     case IX86_BUILTIN_PSRLQI256_MASK:
   19355                 :        7898 :     case IX86_BUILTIN_PSRLQI512:
   19356                 :        7898 :     case IX86_BUILTIN_PSRLW:
   19357                 :        7898 :     case IX86_BUILTIN_PSRLW128:
   19358                 :        7898 :     case IX86_BUILTIN_PSRLW128_MASK:
   19359                 :        7898 :     case IX86_BUILTIN_PSRLW256:
   19360                 :        7898 :     case IX86_BUILTIN_PSRLW256_MASK:
   19361                 :        7898 :     case IX86_BUILTIN_PSRLW512:
   19362                 :        7898 :     case IX86_BUILTIN_PSRLWI:
   19363                 :        7898 :     case IX86_BUILTIN_PSRLWI128:
   19364                 :        7898 :     case IX86_BUILTIN_PSRLWI128_MASK:
   19365                 :        7898 :     case IX86_BUILTIN_PSRLWI256:
   19366                 :        7898 :     case IX86_BUILTIN_PSRLWI256_MASK:
   19367                 :        7898 :     case IX86_BUILTIN_PSRLWI512:
   19368                 :        7898 :       rcode = LSHIFTRT;
   19369                 :        7898 :       is_vshift = false;
   19370                 :        7898 :       goto do_shift;
   19371                 :        2385 :     case IX86_BUILTIN_PSLLVV16HI:
   19372                 :        2385 :     case IX86_BUILTIN_PSLLVV16SI:
   19373                 :        2385 :     case IX86_BUILTIN_PSLLVV2DI:
   19374                 :        2385 :     case IX86_BUILTIN_PSLLVV2DI_MASK:
   19375                 :        2385 :     case IX86_BUILTIN_PSLLVV32HI:
   19376                 :        2385 :     case IX86_BUILTIN_PSLLVV4DI:
   19377                 :        2385 :     case IX86_BUILTIN_PSLLVV4DI_MASK:
   19378                 :        2385 :     case IX86_BUILTIN_PSLLVV4SI:
   19379                 :        2385 :     case IX86_BUILTIN_PSLLVV4SI_MASK:
   19380                 :        2385 :     case IX86_BUILTIN_PSLLVV8DI:
   19381                 :        2385 :     case IX86_BUILTIN_PSLLVV8HI:
   19382                 :        2385 :     case IX86_BUILTIN_PSLLVV8SI:
   19383                 :        2385 :     case IX86_BUILTIN_PSLLVV8SI_MASK:
   19384                 :        2385 :       rcode = ASHIFT;
   19385                 :        2385 :       is_vshift = true;
   19386                 :        2385 :       goto do_shift;
   19387                 :        2341 :     case IX86_BUILTIN_PSRAVQ128:
   19388                 :        2341 :     case IX86_BUILTIN_PSRAVQ256:
   19389                 :        2341 :     case IX86_BUILTIN_PSRAVV16HI:
   19390                 :        2341 :     case IX86_BUILTIN_PSRAVV16SI:
   19391                 :        2341 :     case IX86_BUILTIN_PSRAVV32HI:
   19392                 :        2341 :     case IX86_BUILTIN_PSRAVV4SI:
   19393                 :        2341 :     case IX86_BUILTIN_PSRAVV4SI_MASK:
   19394                 :        2341 :     case IX86_BUILTIN_PSRAVV8DI:
   19395                 :        2341 :     case IX86_BUILTIN_PSRAVV8HI:
   19396                 :        2341 :     case IX86_BUILTIN_PSRAVV8SI:
   19397                 :        2341 :     case IX86_BUILTIN_PSRAVV8SI_MASK:
   19398                 :        2341 :       rcode = ASHIFTRT;
   19399                 :        2341 :       is_vshift = true;
   19400                 :        2341 :       goto do_shift;
   19401                 :        2381 :     case IX86_BUILTIN_PSRLVV16HI:
   19402                 :        2381 :     case IX86_BUILTIN_PSRLVV16SI:
   19403                 :        2381 :     case IX86_BUILTIN_PSRLVV2DI:
   19404                 :        2381 :     case IX86_BUILTIN_PSRLVV2DI_MASK:
   19405                 :        2381 :     case IX86_BUILTIN_PSRLVV32HI:
   19406                 :        2381 :     case IX86_BUILTIN_PSRLVV4DI:
   19407                 :        2381 :     case IX86_BUILTIN_PSRLVV4DI_MASK:
   19408                 :        2381 :     case IX86_BUILTIN_PSRLVV4SI:
   19409                 :        2381 :     case IX86_BUILTIN_PSRLVV4SI_MASK:
   19410                 :        2381 :     case IX86_BUILTIN_PSRLVV8DI:
   19411                 :        2381 :     case IX86_BUILTIN_PSRLVV8HI:
   19412                 :        2381 :     case IX86_BUILTIN_PSRLVV8SI:
   19413                 :        2381 :     case IX86_BUILTIN_PSRLVV8SI_MASK:
   19414                 :        2381 :       rcode = LSHIFTRT;
   19415                 :        2381 :       is_vshift = true;
   19416                 :        2381 :       goto do_shift;
   19417                 :             : 
   19418                 :       30106 :     do_shift:
   19419                 :       30106 :       gcc_assert (n_args >= 2);
   19420                 :       30106 :       if (!gimple_call_lhs (stmt))
   19421                 :             :         {
   19422                 :           1 :           gsi_replace (gsi, gimple_build_nop (), false);
   19423                 :           1 :           return true;
   19424                 :             :         }
   19425                 :       30105 :       arg0 = gimple_call_arg (stmt, 0);
   19426                 :       30105 :       arg1 = gimple_call_arg (stmt, 1);
   19427                 :       30105 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19428                 :             :       /* For masked shift, only optimize if the mask is all ones.  */
   19429                 :       30105 :       if (n_args > 2
   19430                 :       30105 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   19431                 :             :         break;
   19432                 :       15539 :       if (is_vshift)
   19433                 :             :         {
   19434                 :        2642 :           if (TREE_CODE (arg1) != VECTOR_CST)
   19435                 :             :             break;
   19436                 :          69 :           count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
   19437                 :          69 :           if (integer_zerop (arg1))
   19438                 :          27 :             count = 0;
   19439                 :          42 :           else if (rcode == ASHIFTRT)
   19440                 :             :             break;
   19441                 :             :           else
   19442                 :         230 :             for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
   19443                 :             :               {
   19444                 :         212 :                 tree elt = VECTOR_CST_ELT (arg1, i);
   19445                 :         212 :                 if (!wi::neg_p (wi::to_wide (elt))
   19446                 :         375 :                     && wi::to_widest (elt) < count)
   19447                 :          16 :                   return false;
   19448                 :             :               }
   19449                 :             :         }
   19450                 :             :       else
   19451                 :             :         {
   19452                 :       12897 :           arg1 = ix86_vector_shift_count (arg1);
   19453                 :       12897 :           if (!arg1)
   19454                 :             :             break;
   19455                 :        5109 :           count = tree_to_uhwi (arg1);
   19456                 :             :         }
   19457                 :        5154 :       if (count == 0)
   19458                 :             :         {
   19459                 :             :           /* Just return the first argument for shift by 0.  */
   19460                 :          93 :           loc = gimple_location (stmt);
   19461                 :          93 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19462                 :          93 :           gimple_set_location (g, loc);
   19463                 :          93 :           gsi_replace (gsi, g, false);
   19464                 :          93 :           return true;
   19465                 :             :         }
   19466                 :        5061 :       if (rcode != ASHIFTRT
   19467                 :        5061 :           && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
   19468                 :             :         {
   19469                 :             :           /* For shift counts equal or greater than precision, except for
   19470                 :             :              arithmetic right shift the result is zero.  */
   19471                 :          78 :           loc = gimple_location (stmt);
   19472                 :          78 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19473                 :          78 :                                    build_zero_cst (TREE_TYPE (arg0)));
   19474                 :          78 :           gimple_set_location (g, loc);
   19475                 :          78 :           gsi_replace (gsi, g, false);
   19476                 :          78 :           return true;
   19477                 :             :         }
   19478                 :             :       break;
   19479                 :             : 
   19480                 :         535 :     case IX86_BUILTIN_SHUFPD512:
   19481                 :         535 :     case IX86_BUILTIN_SHUFPS512:
   19482                 :         535 :     case IX86_BUILTIN_SHUFPD:
   19483                 :         535 :     case IX86_BUILTIN_SHUFPD256:
   19484                 :         535 :     case IX86_BUILTIN_SHUFPS:
   19485                 :         535 :     case IX86_BUILTIN_SHUFPS256:
   19486                 :         535 :       arg0 = gimple_call_arg (stmt, 0);
   19487                 :         535 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19488                 :             :       /* This is masked shuffle.  Only optimize if the mask is all ones.  */
   19489                 :         535 :       if (n_args > 3
   19490                 :         903 :           && !ix86_masked_all_ones (elems,
   19491                 :         368 :                                     gimple_call_arg (stmt, n_args - 1)))
   19492                 :             :         break;
   19493                 :         203 :       arg2 = gimple_call_arg (stmt, 2);
   19494                 :         203 :       if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
   19495                 :             :         {
   19496                 :         146 :           unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
   19497                 :             :           /* Check valid imm, refer to gcc.target/i386/testimm-10.c.  */
   19498                 :         146 :           if (shuffle_mask > 255)
   19499                 :             :             return false;
   19500                 :             : 
   19501                 :         144 :           machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
   19502                 :         144 :           loc = gimple_location (stmt);
   19503                 :         288 :           tree itype = (imode == E_DFmode
   19504                 :         144 :                         ? long_long_integer_type_node : integer_type_node);
   19505                 :         144 :           tree vtype = build_vector_type (itype, elems);
   19506                 :         144 :           tree_vector_builder elts (vtype, elems, 1);
   19507                 :             : 
   19508                 :             : 
   19509                 :             :           /* Transform integer shuffle_mask to vector perm_mask which
   19510                 :             :              is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md.  */
   19511                 :         840 :           for (unsigned i = 0; i != elems; i++)
   19512                 :             :             {
   19513                 :         696 :               unsigned sel_idx;
   19514                 :             :               /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
   19515                 :             :                  provide 2 select constrols for each element of the
   19516                 :             :                  destination.  */
   19517                 :         696 :               if (imode == E_DFmode)
   19518                 :         240 :                 sel_idx = (i & 1) * elems + (i & ~1)
   19519                 :         240 :                           + ((shuffle_mask >> i) & 1);
   19520                 :             :               else
   19521                 :             :                 {
   19522                 :             :                   /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
   19523                 :             :                      controls for each element of the destination.  */
   19524                 :         456 :                   unsigned j = i % 4;
   19525                 :         456 :                   sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
   19526                 :         456 :                             + ((shuffle_mask >> 2 * j) & 3);
   19527                 :             :                 }
   19528                 :         696 :               elts.quick_push (build_int_cst (itype, sel_idx));
   19529                 :             :             }
   19530                 :             : 
   19531                 :         144 :           tree perm_mask = elts.build ();
   19532                 :         144 :           arg1 = gimple_call_arg (stmt, 1);
   19533                 :         144 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19534                 :             :                                    VEC_PERM_EXPR,
   19535                 :             :                                    arg0, arg1, perm_mask);
   19536                 :         144 :           gimple_set_location (g, loc);
   19537                 :         144 :           gsi_replace (gsi, g, false);
   19538                 :         144 :           return true;
   19539                 :         144 :         }
   19540                 :             :       // Do not error yet, the constant could be propagated later?
   19541                 :             :       break;
   19542                 :             : 
   19543                 :          48 :     case IX86_BUILTIN_PABSB:
   19544                 :          48 :     case IX86_BUILTIN_PABSW:
   19545                 :          48 :     case IX86_BUILTIN_PABSD:
   19546                 :             :       /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE.  */
   19547                 :          48 :       if (!TARGET_MMX_WITH_SSE)
   19548                 :             :         break;
   19549                 :             :       /* FALLTHRU.  */
   19550                 :        2203 :     case IX86_BUILTIN_PABSB128:
   19551                 :        2203 :     case IX86_BUILTIN_PABSB256:
   19552                 :        2203 :     case IX86_BUILTIN_PABSB512:
   19553                 :        2203 :     case IX86_BUILTIN_PABSW128:
   19554                 :        2203 :     case IX86_BUILTIN_PABSW256:
   19555                 :        2203 :     case IX86_BUILTIN_PABSW512:
   19556                 :        2203 :     case IX86_BUILTIN_PABSD128:
   19557                 :        2203 :     case IX86_BUILTIN_PABSD256:
   19558                 :        2203 :     case IX86_BUILTIN_PABSD512:
   19559                 :        2203 :     case IX86_BUILTIN_PABSQ128:
   19560                 :        2203 :     case IX86_BUILTIN_PABSQ256:
   19561                 :        2203 :     case IX86_BUILTIN_PABSQ512:
   19562                 :        2203 :     case IX86_BUILTIN_PABSB128_MASK:
   19563                 :        2203 :     case IX86_BUILTIN_PABSB256_MASK:
   19564                 :        2203 :     case IX86_BUILTIN_PABSW128_MASK:
   19565                 :        2203 :     case IX86_BUILTIN_PABSW256_MASK:
   19566                 :        2203 :     case IX86_BUILTIN_PABSD128_MASK:
   19567                 :        2203 :     case IX86_BUILTIN_PABSD256_MASK:
   19568                 :        2203 :       gcc_assert (n_args >= 1);
   19569                 :        2203 :       if (!gimple_call_lhs (stmt))
   19570                 :             :         {
   19571                 :           1 :           gsi_replace (gsi, gimple_build_nop (), false);
   19572                 :           1 :           return true;
   19573                 :             :         }
   19574                 :        2202 :       arg0 = gimple_call_arg (stmt, 0);
   19575                 :        2202 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19576                 :             :       /* For masked ABS, only optimize if the mask is all ones.  */
   19577                 :        2202 :       if (n_args > 1
   19578                 :        2202 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   19579                 :             :         break;
   19580                 :         230 :       {
   19581                 :         230 :         tree utype, ures, vce;
   19582                 :         230 :         utype = unsigned_type_for (TREE_TYPE (arg0));
   19583                 :             :         /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
   19584                 :             :            instead of ABS_EXPR to hanlde overflow case(TYPE_MIN).  */
   19585                 :         230 :         ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
   19586                 :         230 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19587                 :         230 :         loc = gimple_location (stmt);
   19588                 :         230 :         vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
   19589                 :         230 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   19590                 :             :                                  VIEW_CONVERT_EXPR, vce);
   19591                 :         230 :         gsi_replace (gsi, g, false);
   19592                 :             :       }
   19593                 :         230 :       return true;
   19594                 :             : 
   19595                 :             :     default:
   19596                 :             :       break;
   19597                 :             :     }
   19598                 :             : 
   19599                 :             :   return false;
   19600                 :             : }
   19601                 :             : 
   19602                 :             : /* Handler for an SVML-style interface to
   19603                 :             :    a library with vectorized intrinsics.  */
   19604                 :             : 
   19605                 :             : tree
   19606                 :          11 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
   19607                 :             : {
   19608                 :          11 :   char name[20];
   19609                 :          11 :   tree fntype, new_fndecl, args;
   19610                 :          11 :   unsigned arity;
   19611                 :          11 :   const char *bname;
   19612                 :          11 :   machine_mode el_mode, in_mode;
   19613                 :          11 :   int n, in_n;
   19614                 :             : 
   19615                 :             :   /* The SVML is suitable for unsafe math only.  */
   19616                 :          11 :   if (!flag_unsafe_math_optimizations)
   19617                 :             :     return NULL_TREE;
   19618                 :             : 
   19619                 :          11 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   19620                 :          11 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   19621                 :          11 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   19622                 :          11 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   19623                 :          11 :   if (el_mode != in_mode
   19624                 :          11 :       || n != in_n)
   19625                 :             :     return NULL_TREE;
   19626                 :             : 
   19627                 :          11 :   switch (fn)
   19628                 :             :     {
   19629                 :          11 :     CASE_CFN_EXP:
   19630                 :          11 :     CASE_CFN_LOG:
   19631                 :          11 :     CASE_CFN_LOG10:
   19632                 :          11 :     CASE_CFN_POW:
   19633                 :          11 :     CASE_CFN_TANH:
   19634                 :          11 :     CASE_CFN_TAN:
   19635                 :          11 :     CASE_CFN_ATAN:
   19636                 :          11 :     CASE_CFN_ATAN2:
   19637                 :          11 :     CASE_CFN_ATANH:
   19638                 :          11 :     CASE_CFN_CBRT:
   19639                 :          11 :     CASE_CFN_SINH:
   19640                 :          11 :     CASE_CFN_SIN:
   19641                 :          11 :     CASE_CFN_ASINH:
   19642                 :          11 :     CASE_CFN_ASIN:
   19643                 :          11 :     CASE_CFN_COSH:
   19644                 :          11 :     CASE_CFN_COS:
   19645                 :          11 :     CASE_CFN_ACOSH:
   19646                 :          11 :     CASE_CFN_ACOS:
   19647                 :          11 :       if ((el_mode != DFmode || n != 2)
   19648                 :           9 :           && (el_mode != SFmode || n != 4))
   19649                 :             :         return NULL_TREE;
   19650                 :           6 :       break;
   19651                 :             : 
   19652                 :             :     default:
   19653                 :             :       return NULL_TREE;
   19654                 :             :     }
   19655                 :             : 
   19656                 :           6 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   19657                 :             :                                  ? double_type_node : float_type_node, fn);
   19658                 :           6 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   19659                 :             : 
   19660                 :           6 :   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
   19661                 :           2 :     strcpy (name, "vmlsLn4");
   19662                 :           4 :   else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
   19663                 :           0 :     strcpy (name, "vmldLn2");
   19664                 :           4 :   else if (n == 4)
   19665                 :             :     {
   19666                 :           2 :       sprintf (name, "vmls%s", bname+10);
   19667                 :           2 :       name[strlen (name)-1] = '4';
   19668                 :             :     }
   19669                 :             :   else
   19670                 :           2 :     sprintf (name, "vmld%s2", bname+10);
   19671                 :             : 
   19672                 :             :   /* Convert to uppercase. */
   19673                 :           6 :   name[4] &= ~0x20;
   19674                 :             : 
   19675                 :           6 :   arity = 0;
   19676                 :           6 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   19677                 :           0 :     arity++;
   19678                 :             : 
   19679                 :           6 :   if (arity == 1)
   19680                 :           0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   19681                 :             :   else
   19682                 :           6 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   19683                 :             : 
   19684                 :             :   /* Build a function declaration for the vectorized function.  */
   19685                 :           6 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   19686                 :             :                            FUNCTION_DECL, get_identifier (name), fntype);
   19687                 :           6 :   TREE_PUBLIC (new_fndecl) = 1;
   19688                 :           6 :   DECL_EXTERNAL (new_fndecl) = 1;
   19689                 :           6 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   19690                 :           6 :   TREE_READONLY (new_fndecl) = 1;
   19691                 :             : 
   19692                 :           6 :   return new_fndecl;
   19693                 :             : }
   19694                 :             : 
   19695                 :             : /* Handler for an ACML-style interface to
   19696                 :             :    a library with vectorized intrinsics.  */
   19697                 :             : 
   19698                 :             : tree
   19699                 :           3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
   19700                 :             : {
   19701                 :           3 :   char name[20] = "__vr.._";
   19702                 :           3 :   tree fntype, new_fndecl, args;
   19703                 :           3 :   unsigned arity;
   19704                 :           3 :   const char *bname;
   19705                 :           3 :   machine_mode el_mode, in_mode;
   19706                 :           3 :   int n, in_n;
   19707                 :             : 
   19708                 :             :   /* The ACML is 64bits only and suitable for unsafe math only as
   19709                 :             :      it does not correctly support parts of IEEE with the required
   19710                 :             :      precision such as denormals.  */
   19711                 :           3 :   if (!TARGET_64BIT
   19712                 :           3 :       || !flag_unsafe_math_optimizations)
   19713                 :             :     return NULL_TREE;
   19714                 :             : 
   19715                 :           3 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   19716                 :           3 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   19717                 :           3 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   19718                 :           3 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   19719                 :           3 :   if (el_mode != in_mode
   19720                 :           3 :       || n != in_n)
   19721                 :             :     return NULL_TREE;
   19722                 :             : 
   19723                 :           3 :   switch (fn)
   19724                 :             :     {
   19725                 :           3 :     CASE_CFN_SIN:
   19726                 :           3 :     CASE_CFN_COS:
   19727                 :           3 :     CASE_CFN_EXP:
   19728                 :           3 :     CASE_CFN_LOG:
   19729                 :           3 :     CASE_CFN_LOG2:
   19730                 :           3 :     CASE_CFN_LOG10:
   19731                 :           3 :       if (el_mode == DFmode && n == 2)
   19732                 :             :         {
   19733                 :           3 :           name[4] = 'd';
   19734                 :           3 :           name[5] = '2';
   19735                 :             :         }
   19736                 :           0 :       else if (el_mode == SFmode && n == 4)
   19737                 :             :         {
   19738                 :           0 :           name[4] = 's';
   19739                 :           0 :           name[5] = '4';
   19740                 :             :         }
   19741                 :             :       else
   19742                 :             :         return NULL_TREE;
   19743                 :           3 :       break;
   19744                 :             : 
   19745                 :             :     default:
   19746                 :             :       return NULL_TREE;
   19747                 :             :     }
   19748                 :             : 
   19749                 :           3 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   19750                 :             :                                  ? double_type_node : float_type_node, fn);
   19751                 :           3 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   19752                 :           3 :   sprintf (name + 7, "%s", bname+10);
   19753                 :             : 
   19754                 :           3 :   arity = 0;
   19755                 :           3 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   19756                 :           0 :     arity++;
   19757                 :             : 
   19758                 :           3 :   if (arity == 1)
   19759                 :           0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   19760                 :             :   else
   19761                 :           3 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   19762                 :             : 
   19763                 :             :   /* Build a function declaration for the vectorized function.  */
   19764                 :           3 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   19765                 :             :                            FUNCTION_DECL, get_identifier (name), fntype);
   19766                 :           3 :   TREE_PUBLIC (new_fndecl) = 1;
   19767                 :           3 :   DECL_EXTERNAL (new_fndecl) = 1;
   19768                 :           3 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   19769                 :           3 :   TREE_READONLY (new_fndecl) = 1;
   19770                 :             : 
   19771                 :           3 :   return new_fndecl;
   19772                 :             : }
   19773                 :             : 
   19774                 :             : /* Returns a decl of a function that implements scatter store with
   19775                 :             :    register type VECTYPE and index type INDEX_TYPE and SCALE.
   19776                 :             :    Return NULL_TREE if it is not available.  */
   19777                 :             : 
   19778                 :             : static tree
   19779                 :       71050 : ix86_vectorize_builtin_scatter (const_tree vectype,
   19780                 :             :                                 const_tree index_type, int scale)
   19781                 :             : {
   19782                 :       71050 :   bool si;
   19783                 :       71050 :   enum ix86_builtins code;
   19784                 :       71050 :   const machine_mode mode = TYPE_MODE (TREE_TYPE (vectype));
   19785                 :             : 
   19786                 :       71050 :   if (!TARGET_AVX512F)
   19787                 :             :     return NULL_TREE;
   19788                 :             : 
   19789                 :        2932 :   if (!TARGET_EVEX512 && GET_MODE_SIZE (mode) == 64)
   19790                 :             :     return NULL_TREE;
   19791                 :             : 
   19792                 :        2932 :   if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
   19793                 :        5343 :       ? !TARGET_USE_SCATTER_2PARTS
   19794                 :        5343 :       : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
   19795                 :        2411 :          ? !TARGET_USE_SCATTER_4PARTS
   19796                 :        1681 :          : !TARGET_USE_SCATTER_8PARTS))
   19797                 :             :     return NULL_TREE;
   19798                 :             : 
   19799                 :        2932 :   if ((TREE_CODE (index_type) != INTEGER_TYPE
   19800                 :         335 :        && !POINTER_TYPE_P (index_type))
   19801                 :        3267 :       || (TYPE_MODE (index_type) != SImode
   19802                 :        1093 :           && TYPE_MODE (index_type) != DImode))
   19803                 :           0 :     return NULL_TREE;
   19804                 :             : 
   19805                 :        3064 :   if (TYPE_PRECISION (index_type) > POINTER_SIZE)
   19806                 :             :     return NULL_TREE;
   19807                 :             : 
   19808                 :             :   /* v*scatter* insn sign extends index to pointer mode.  */
   19809                 :        2932 :   if (TYPE_PRECISION (index_type) < POINTER_SIZE
   19810                 :        2932 :       && TYPE_UNSIGNED (index_type))
   19811                 :             :     return NULL_TREE;
   19812                 :             : 
   19813                 :             :   /* Scale can be 1, 2, 4 or 8.  */
   19814                 :        2932 :   if (scale <= 0
   19815                 :        2932 :       || scale > 8
   19816                 :        2922 :       || (scale & (scale - 1)) != 0)
   19817                 :             :     return NULL_TREE;
   19818                 :             : 
   19819                 :        2922 :   si = TYPE_MODE (index_type) == SImode;
   19820                 :        2922 :   switch (TYPE_MODE (vectype))
   19821                 :             :     {
   19822                 :         201 :     case E_V8DFmode:
   19823                 :         201 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
   19824                 :             :       break;
   19825                 :         131 :     case E_V8DImode:
   19826                 :         131 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
   19827                 :             :       break;
   19828                 :         202 :     case E_V16SFmode:
   19829                 :         202 :       code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
   19830                 :             :       break;
   19831                 :         240 :     case E_V16SImode:
   19832                 :         240 :       code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
   19833                 :             :       break;
   19834                 :         128 :     case E_V4DFmode:
   19835                 :         128 :       if (TARGET_AVX512VL)
   19836                 :          60 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
   19837                 :             :       else
   19838                 :             :         return NULL_TREE;
   19839                 :             :       break;
   19840                 :         112 :     case E_V4DImode:
   19841                 :         112 :       if (TARGET_AVX512VL)
   19842                 :          60 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
   19843                 :             :       else
   19844                 :             :         return NULL_TREE;
   19845                 :             :       break;
   19846                 :         126 :     case E_V8SFmode:
   19847                 :         126 :       if (TARGET_AVX512VL)
   19848                 :          66 :         code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
   19849                 :             :       else
   19850                 :             :         return NULL_TREE;
   19851                 :             :       break;
   19852                 :         242 :     case E_V8SImode:
   19853                 :         242 :       if (TARGET_AVX512VL)
   19854                 :         156 :         code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
   19855                 :             :       else
   19856                 :             :         return NULL_TREE;
   19857                 :             :       break;
   19858                 :         156 :     case E_V2DFmode:
   19859                 :         156 :       if (TARGET_AVX512VL)
   19860                 :          90 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
   19861                 :             :       else
   19862                 :             :         return NULL_TREE;
   19863                 :             :       break;
   19864                 :         134 :     case E_V2DImode:
   19865                 :         134 :       if (TARGET_AVX512VL)
   19866                 :          88 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
   19867                 :             :       else
   19868                 :             :         return NULL_TREE;
   19869                 :             :       break;
   19870                 :         152 :     case E_V4SFmode:
   19871                 :         152 :       if (TARGET_AVX512VL)
   19872                 :          96 :         code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
   19873                 :             :       else
   19874                 :             :         return NULL_TREE;
   19875                 :             :       break;
   19876                 :         234 :     case E_V4SImode:
   19877                 :         234 :       if (TARGET_AVX512VL)
   19878                 :         146 :         code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
   19879                 :             :       else
   19880                 :             :         return NULL_TREE;
   19881                 :             :       break;
   19882                 :             :     default:
   19883                 :             :       return NULL_TREE;
   19884                 :             :     }
   19885                 :             : 
   19886                 :        1536 :   return get_ix86_builtin (code);
   19887                 :             : }
   19888                 :             : 
   19889                 :             : /* Return true if it is safe to use the rsqrt optabs to optimize
   19890                 :             :    1.0/sqrt.  */
   19891                 :             : 
   19892                 :             : static bool
   19893                 :          86 : use_rsqrt_p (machine_mode mode)
   19894                 :             : {
   19895                 :          86 :   return ((mode == HFmode
   19896                 :          38 :            || (TARGET_SSE && TARGET_SSE_MATH))
   19897                 :          86 :           && flag_finite_math_only
   19898                 :          85 :           && !flag_trapping_math
   19899                 :         153 :           && flag_unsafe_math_optimizations);
   19900                 :             : }
   19901                 :             : 
   19902                 :             : /* Helper for avx_vpermilps256_operand et al.  This is also used by
   19903                 :             :    the expansion functions to turn the parallel back into a mask.
   19904                 :             :    The return value is 0 for no match and the imm8+1 for a match.  */
   19905                 :             : 
   19906                 :             : int
   19907                 :       49953 : avx_vpermilp_parallel (rtx par, machine_mode mode)
   19908                 :             : {
   19909                 :       49953 :   unsigned i, nelt = GET_MODE_NUNITS (mode);
   19910                 :       49953 :   unsigned mask = 0;
   19911                 :       49953 :   unsigned char ipar[16] = {};  /* Silence -Wuninitialized warning.  */
   19912                 :             : 
   19913                 :       49953 :   if (XVECLEN (par, 0) != (int) nelt)
   19914                 :             :     return 0;
   19915                 :             : 
   19916                 :             :   /* Validate that all of the elements are constants, and not totally
   19917                 :             :      out of range.  Copy the data into an integral array to make the
   19918                 :             :      subsequent checks easier.  */
   19919                 :      297177 :   for (i = 0; i < nelt; ++i)
   19920                 :             :     {
   19921                 :      247224 :       rtx er = XVECEXP (par, 0, i);
   19922                 :      247224 :       unsigned HOST_WIDE_INT ei;
   19923                 :             : 
   19924                 :      247224 :       if (!CONST_INT_P (er))
   19925                 :             :         return 0;
   19926                 :      247224 :       ei = INTVAL (er);
   19927                 :      247224 :       if (ei >= nelt)
   19928                 :             :         return 0;
   19929                 :      247224 :       ipar[i] = ei;
   19930                 :             :     }
   19931                 :             : 
   19932                 :       49953 :   switch (mode)
   19933                 :             :     {
   19934                 :             :     case E_V8DFmode:
   19935                 :             :       /* In the 512-bit DFmode case, we can only move elements within
   19936                 :             :          a 128-bit lane.  First fill the second part of the mask,
   19937                 :             :          then fallthru.  */
   19938                 :        5600 :       for (i = 4; i < 6; ++i)
   19939                 :             :         {
   19940                 :        3773 :           if (ipar[i] < 4 || ipar[i] >= 6)
   19941                 :             :             return 0;
   19942                 :        3699 :           mask |= (ipar[i] - 4) << i;
   19943                 :             :         }
   19944                 :        5139 :       for (i = 6; i < 8; ++i)
   19945                 :             :         {
   19946                 :        3483 :           if (ipar[i] < 6)
   19947                 :             :             return 0;
   19948                 :        3312 :           mask |= (ipar[i] - 6) << i;
   19949                 :             :         }
   19950                 :             :       /* FALLTHRU */
   19951                 :             : 
   19952                 :             :     case E_V4DFmode:
   19953                 :             :       /* In the 256-bit DFmode case, we can only move elements within
   19954                 :             :          a 128-bit lane.  */
   19955                 :       36350 :       for (i = 0; i < 2; ++i)
   19956                 :             :         {
   19957                 :       25613 :           if (ipar[i] >= 2)
   19958                 :             :             return 0;
   19959                 :       23453 :           mask |= ipar[i] << i;
   19960                 :             :         }
   19961                 :       31239 :       for (i = 2; i < 4; ++i)
   19962                 :             :         {
   19963                 :       20988 :           if (ipar[i] < 2)
   19964                 :             :             return 0;
   19965                 :       20502 :           mask |= (ipar[i] - 2) << i;
   19966                 :             :         }
   19967                 :             :       break;
   19968                 :             : 
   19969                 :             :     case E_V16SFmode:
   19970                 :             :       /* In 512 bit SFmode case, permutation in the upper 256 bits
   19971                 :             :          must mirror the permutation in the lower 256-bits.  */
   19972                 :       14080 :       for (i = 0; i < 8; ++i)
   19973                 :       12517 :         if (ipar[i] + 8 != ipar[i + 8])
   19974                 :             :           return 0;
   19975                 :             :       /* FALLTHRU */
   19976                 :             : 
   19977                 :             :     case E_V8SFmode:
   19978                 :             :       /* In 256 bit SFmode case, we have full freedom of
   19979                 :             :          movement within the low 128-bit lane, but the high 128-bit
   19980                 :             :          lane must mirror the exact same pattern.  */
   19981                 :       58292 :       for (i = 0; i < 4; ++i)
   19982                 :       48295 :         if (ipar[i] + 4 != ipar[i + 4])
   19983                 :             :           return 0;
   19984                 :             :       nelt = 4;
   19985                 :             :       /* FALLTHRU */
   19986                 :             : 
   19987                 :       32734 :     case E_V2DFmode:
   19988                 :       32734 :     case E_V4SFmode:
   19989                 :             :       /* In the 128-bit case, we've full freedom in the placement of
   19990                 :             :          the elements from the source operand.  */
   19991                 :      134574 :       for (i = 0; i < nelt; ++i)
   19992                 :      101840 :         mask |= ipar[i] << (i * (nelt / 2));
   19993                 :             :       break;
   19994                 :             : 
   19995                 :           0 :     default:
   19996                 :           0 :       gcc_unreachable ();
   19997                 :             :     }
   19998                 :             : 
   19999                 :             :   /* Make sure success has a non-zero value by adding one.  */
   20000                 :       42985 :   return mask + 1;
   20001                 :             : }
   20002                 :             : 
   20003                 :             : /* Helper for avx_vperm2f128_v4df_operand et al.  This is also used by
   20004                 :             :    the expansion functions to turn the parallel back into a mask.
   20005                 :             :    The return value is 0 for no match and the imm8+1 for a match.  */
   20006                 :             : 
   20007                 :             : int
   20008                 :       33392 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
   20009                 :             : {
   20010                 :       33392 :   unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
   20011                 :       33392 :   unsigned mask = 0;
   20012                 :       33392 :   unsigned char ipar[8] = {};  /* Silence -Wuninitialized warning.  */
   20013                 :             : 
   20014                 :       33392 :   if (XVECLEN (par, 0) != (int) nelt)
   20015                 :             :     return 0;
   20016                 :             : 
   20017                 :             :   /* Validate that all of the elements are constants, and not totally
   20018                 :             :      out of range.  Copy the data into an integral array to make the
   20019                 :             :      subsequent checks easier.  */
   20020                 :      271004 :   for (i = 0; i < nelt; ++i)
   20021                 :             :     {
   20022                 :      237612 :       rtx er = XVECEXP (par, 0, i);
   20023                 :      237612 :       unsigned HOST_WIDE_INT ei;
   20024                 :             : 
   20025                 :      237612 :       if (!CONST_INT_P (er))
   20026                 :             :         return 0;
   20027                 :      237612 :       ei = INTVAL (er);
   20028                 :      237612 :       if (ei >= 2 * nelt)
   20029                 :             :         return 0;
   20030                 :      237612 :       ipar[i] = ei;
   20031                 :             :     }
   20032                 :             : 
   20033                 :             :   /* Validate that the halves of the permute are halves.  */
   20034                 :       53365 :   for (i = 0; i < nelt2 - 1; ++i)
   20035                 :       46147 :     if (ipar[i] + 1 != ipar[i + 1])
   20036                 :             :       return 0;
   20037                 :       20685 :   for (i = nelt2; i < nelt - 1; ++i)
   20038                 :       14605 :     if (ipar[i] + 1 != ipar[i + 1])
   20039                 :             :       return 0;
   20040                 :             : 
   20041                 :             :   /* Reconstruct the mask.  */
   20042                 :       18198 :   for (i = 0; i < 2; ++i)
   20043                 :             :     {
   20044                 :       12141 :       unsigned e = ipar[i * nelt2];
   20045                 :       12141 :       if (e % nelt2)
   20046                 :             :         return 0;
   20047                 :       12118 :       e /= nelt2;
   20048                 :       12118 :       mask |= e << (i * 4);
   20049                 :             :     }
   20050                 :             : 
   20051                 :             :   /* Make sure success has a non-zero value by adding one.  */
   20052                 :        6057 :   return mask + 1;
   20053                 :             : }
   20054                 :             : 
   20055                 :             : /* Return a mask of VPTERNLOG operands that do not affect output.  */
   20056                 :             : 
   20057                 :             : int
   20058                 :         492 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
   20059                 :             : {
   20060                 :         492 :   int mask = 0;
   20061                 :         492 :   int imm8 = INTVAL (pternlog_imm);
   20062                 :             : 
   20063                 :         492 :   if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
   20064                 :           9 :     mask |= 1;
   20065                 :         492 :   if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
   20066                 :          33 :     mask |= 2;
   20067                 :         492 :   if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
   20068                 :          29 :     mask |= 4;
   20069                 :             : 
   20070                 :         492 :   return mask;
   20071                 :             : }
   20072                 :             : 
   20073                 :             : /* Eliminate false dependencies on operands that do not affect output
   20074                 :             :    by substituting other operands of a VPTERNLOG.  */
   20075                 :             : 
   20076                 :             : void
   20077                 :          19 : substitute_vpternlog_operands (rtx *operands)
   20078                 :             : {
   20079                 :          19 :   int mask = vpternlog_redundant_operand_mask (operands[4]);
   20080                 :             : 
   20081                 :          19 :   if (mask & 1) /* The first operand is redundant.  */
   20082                 :           3 :     operands[1] = operands[2];
   20083                 :             : 
   20084                 :          19 :   if (mask & 2) /* The second operand is redundant.  */
   20085                 :          15 :     operands[2] = operands[1];
   20086                 :             : 
   20087                 :          19 :   if (mask & 4) /* The third operand is redundant.  */
   20088                 :          14 :     operands[3] = operands[1];
   20089                 :           5 :   else if (REG_P (operands[3]))
   20090                 :             :     {
   20091                 :           1 :       if (mask & 1)
   20092                 :           1 :         operands[1] = operands[3];
   20093                 :           1 :       if (mask & 2)
   20094                 :           1 :         operands[2] = operands[3];
   20095                 :             :     }
   20096                 :          19 : }
   20097                 :             : 
   20098                 :             : /* Return a register priority for hard reg REGNO.  */
   20099                 :             : static int
   20100                 :    45613263 : ix86_register_priority (int hard_regno)
   20101                 :             : {
   20102                 :             :   /* ebp and r13 as the base always wants a displacement, r12 as the
   20103                 :             :      base always wants an index.  So discourage their usage in an
   20104                 :             :      address.  */
   20105                 :    45613263 :   if (hard_regno == R12_REG || hard_regno == R13_REG)
   20106                 :             :     return 0;
   20107                 :    42690516 :   if (hard_regno == BP_REG)
   20108                 :             :     return 1;
   20109                 :             :   /* New x86-64 int registers result in bigger code size.  Discourage them.  */
   20110                 :    41377520 :   if (REX_INT_REGNO_P (hard_regno))
   20111                 :             :     return 2;
   20112                 :    29463574 :   if (REX2_INT_REGNO_P (hard_regno))
   20113                 :             :     return 2;
   20114                 :             :   /* New x86-64 SSE registers result in bigger code size.  Discourage them.  */
   20115                 :    29461417 :   if (REX_SSE_REGNO_P (hard_regno))
   20116                 :             :     return 2;
   20117                 :    24134151 :   if (EXT_REX_SSE_REGNO_P (hard_regno))
   20118                 :             :     return 1;
   20119                 :             :   /* Usage of AX register results in smaller code.  Prefer it.  */
   20120                 :    23953915 :   if (hard_regno == AX_REG)
   20121                 :     2981495 :     return 4;
   20122                 :             :   return 3;
   20123                 :             : }
   20124                 :             : 
   20125                 :             : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
   20126                 :             : 
   20127                 :             :    Put float CONST_DOUBLE in the constant pool instead of fp regs.
   20128                 :             :    QImode must go into class Q_REGS.
   20129                 :             :    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
   20130                 :             :    movdf to do mem-to-mem moves through integer regs.  */
   20131                 :             : 
   20132                 :             : static reg_class_t
   20133                 :   466309011 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
   20134                 :             : {
   20135                 :   466309011 :   machine_mode mode = GET_MODE (x);
   20136                 :             : 
   20137                 :             :   /* We're only allowed to return a subclass of CLASS.  Many of the
   20138                 :             :      following checks fail for NO_REGS, so eliminate that early.  */
   20139                 :   466309011 :   if (regclass == NO_REGS)
   20140                 :             :     return NO_REGS;
   20141                 :             : 
   20142                 :             :   /* All classes can load zeros.  */
   20143                 :   465521524 :   if (x == CONST0_RTX (mode))
   20144                 :             :     return regclass;
   20145                 :             : 
   20146                 :             :   /* Force constants into memory if we are loading a (nonzero) constant into
   20147                 :             :      an MMX, SSE or MASK register.  This is because there are no MMX/SSE/MASK
   20148                 :             :      instructions to load from a constant.  */
   20149                 :   442239859 :   if (CONSTANT_P (x)
   20150                 :   442239859 :       && (MAYBE_MMX_CLASS_P (regclass)
   20151                 :   117935389 :           || MAYBE_SSE_CLASS_P (regclass)
   20152                 :    90582787 :           || MAYBE_MASK_CLASS_P (regclass)))
   20153                 :    27477674 :     return NO_REGS;
   20154                 :             : 
   20155                 :             :   /* Floating-point constants need more complex checks.  */
   20156                 :   414762185 :   if (CONST_DOUBLE_P (x))
   20157                 :             :     {
   20158                 :             :       /* General regs can load everything.  */
   20159                 :      276529 :       if (INTEGER_CLASS_P (regclass))
   20160                 :             :         return regclass;
   20161                 :             : 
   20162                 :             :       /* Floats can load 0 and 1 plus some others.  Note that we eliminated
   20163                 :             :          zero above.  We only want to wind up preferring 80387 registers if
   20164                 :             :          we plan on doing computation with them.  */
   20165                 :      172958 :       if (IS_STACK_MODE (mode)
   20166                 :      230675 :           && standard_80387_constant_p (x) > 0)
   20167                 :             :         {
   20168                 :             :           /* Limit class to FP regs.  */
   20169                 :       40489 :           if (FLOAT_CLASS_P (regclass))
   20170                 :             :             return FLOAT_REGS;
   20171                 :             :         }
   20172                 :             : 
   20173                 :      132469 :       return NO_REGS;
   20174                 :             :     }
   20175                 :             : 
   20176                 :             :   /* Prefer SSE if we can use them for math.  Also allow integer regs
   20177                 :             :      when moves between register units are cheap.  */
   20178                 :   414485656 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   20179                 :             :     {
   20180                 :    30509660 :       if (TARGET_INTER_UNIT_MOVES_FROM_VEC
   20181                 :    30494130 :           && TARGET_INTER_UNIT_MOVES_TO_VEC
   20182                 :    91485814 :           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
   20183                 :    30352574 :         return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   20184                 :             :       else
   20185                 :      157086 :         return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   20186                 :             :     }
   20187                 :             : 
   20188                 :             :   /* Generally when we see PLUS here, it's the function invariant
   20189                 :             :      (plus soft-fp const_int).  Which can only be computed into general
   20190                 :             :      regs.  */
   20191                 :   383975996 :   if (GET_CODE (x) == PLUS)
   20192                 :      708804 :     return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
   20193                 :             : 
   20194                 :             :   /* QImode constants are easy to load, but non-constant QImode data
   20195                 :             :      must go into Q_REGS or ALL_MASK_REGS.  */
   20196                 :   383267192 :   if (GET_MODE (x) == QImode && !CONSTANT_P (x))
   20197                 :             :     {
   20198                 :    21111602 :       if (Q_CLASS_P (regclass))
   20199                 :             :         return regclass;
   20200                 :    16766381 :       else if (reg_class_subset_p (Q_REGS, regclass))
   20201                 :             :         return Q_REGS;
   20202                 :       27457 :       else if (MASK_CLASS_P (regclass))
   20203                 :             :         return regclass;
   20204                 :             :       else
   20205                 :             :         return NO_REGS;
   20206                 :             :     }
   20207                 :             : 
   20208                 :             :   return regclass;
   20209                 :             : }
   20210                 :             : 
   20211                 :             : /* Discourage putting floating-point values in SSE registers unless
   20212                 :             :    SSE math is being used, and likewise for the 387 registers.  */
   20213                 :             : static reg_class_t
   20214                 :    62945092 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
   20215                 :             : {
   20216                 :             :   /* Restrict the output reload class to the register bank that we are doing
   20217                 :             :      math on.  If we would like not to return a subset of CLASS, reject this
   20218                 :             :      alternative: if reload cannot do this, it will still use its choice.  */
   20219                 :    62945092 :   machine_mode mode = GET_MODE (x);
   20220                 :    62945092 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   20221                 :     7041209 :     return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
   20222                 :             : 
   20223                 :    55903883 :   if (IS_STACK_MODE (mode))
   20224                 :      200793 :     return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
   20225                 :             : 
   20226                 :             :   return regclass;
   20227                 :             : }
   20228                 :             : 
   20229                 :             : static reg_class_t
   20230                 :   338532039 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
   20231                 :             :                        machine_mode mode, secondary_reload_info *sri)
   20232                 :             : {
   20233                 :             :   /* Double-word spills from general registers to non-offsettable memory
   20234                 :             :      references (zero-extended addresses) require special handling.  */
   20235                 :   338532039 :   if (TARGET_64BIT
   20236                 :   290417130 :       && MEM_P (x)
   20237                 :   162273047 :       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
   20238                 :    16437518 :       && INTEGER_CLASS_P (rclass)
   20239                 :   341176736 :       && !offsettable_memref_p (x))
   20240                 :             :     {
   20241                 :     2447112 :       sri->icode = (in_p
   20242                 :     1223556 :                     ? CODE_FOR_reload_noff_load
   20243                 :             :                     : CODE_FOR_reload_noff_store);
   20244                 :             :       /* Add the cost of moving address to a temporary.  */
   20245                 :     1223556 :       sri->extra_cost = 1;
   20246                 :             : 
   20247                 :     1223556 :       return NO_REGS;
   20248                 :             :     }
   20249                 :             : 
   20250                 :             :   /* QImode spills from non-QI registers require
   20251                 :             :      intermediate register on 32bit targets.  */
   20252                 :   337308483 :   if (mode == QImode
   20253                 :   337308483 :       && ((!TARGET_64BIT && !in_p
   20254                 :      544346 :            && INTEGER_CLASS_P (rclass)
   20255                 :      544314 :            && MAYBE_NON_Q_CLASS_P (rclass))
   20256                 :    20719521 :           || (!TARGET_AVX512DQ
   20257                 :    20593620 :               && MAYBE_MASK_CLASS_P (rclass))))
   20258                 :             :     {
   20259                 :        6629 :       int regno = true_regnum (x);
   20260                 :             : 
   20261                 :             :       /* Return Q_REGS if the operand is in memory.  */
   20262                 :        6629 :       if (regno == -1)
   20263                 :             :         return Q_REGS;
   20264                 :             : 
   20265                 :             :       return NO_REGS;
   20266                 :             :     }
   20267                 :             : 
   20268                 :             :   /* Require movement to gpr, and then store to memory.  */
   20269                 :   337301854 :   if ((mode == HFmode || mode == HImode || mode == V2QImode
   20270                 :             :        || mode == BFmode)
   20271                 :     3272418 :       && !TARGET_SSE4_1
   20272                 :     2738374 :       && SSE_CLASS_P (rclass)
   20273                 :      177483 :       && !in_p && MEM_P (x))
   20274                 :             :     {
   20275                 :       83140 :       sri->extra_cost = 1;
   20276                 :       83140 :       return GENERAL_REGS;
   20277                 :             :     }
   20278                 :             : 
   20279                 :             :   /* This condition handles corner case where an expression involving
   20280                 :             :      pointers gets vectorized.  We're trying to use the address of a
   20281                 :             :      stack slot as a vector initializer.
   20282                 :             : 
   20283                 :             :      (set (reg:V2DI 74 [ vect_cst_.2 ])
   20284                 :             :           (vec_duplicate:V2DI (reg/f:DI 20 frame)))
   20285                 :             : 
   20286                 :             :      Eventually frame gets turned into sp+offset like this:
   20287                 :             : 
   20288                 :             :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20289                 :             :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   20290                 :             :                                        (const_int 392 [0x188]))))
   20291                 :             : 
   20292                 :             :      That later gets turned into:
   20293                 :             : 
   20294                 :             :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20295                 :             :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   20296                 :             :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
   20297                 :             : 
   20298                 :             :      We'll have the following reload recorded:
   20299                 :             : 
   20300                 :             :      Reload 0: reload_in (DI) =
   20301                 :             :            (plus:DI (reg/f:DI 7 sp)
   20302                 :             :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
   20303                 :             :      reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20304                 :             :      SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
   20305                 :             :      reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
   20306                 :             :      reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   20307                 :             :      reload_reg_rtx: (reg:V2DI 22 xmm1)
   20308                 :             : 
   20309                 :             :      Which isn't going to work since SSE instructions can't handle scalar
   20310                 :             :      additions.  Returning GENERAL_REGS forces the addition into integer
   20311                 :             :      register and reload can handle subsequent reloads without problems.  */
   20312                 :             : 
   20313                 :   192633258 :   if (in_p && GET_CODE (x) == PLUS
   20314                 :           2 :       && SSE_CLASS_P (rclass)
   20315                 :   337218714 :       && SCALAR_INT_MODE_P (mode))
   20316                 :             :     return GENERAL_REGS;
   20317                 :             : 
   20318                 :             :   return NO_REGS;
   20319                 :             : }
   20320                 :             : 
   20321                 :             : /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
   20322                 :             : 
   20323                 :             : static bool
   20324                 :   505672676 : ix86_class_likely_spilled_p (reg_class_t rclass)
   20325                 :             : {
   20326                 :   497063320 :   switch (rclass)
   20327                 :             :     {
   20328                 :             :       case AREG:
   20329                 :             :       case DREG:
   20330                 :             :       case CREG:
   20331                 :             :       case BREG:
   20332                 :             :       case AD_REGS:
   20333                 :             :       case SIREG:
   20334                 :             :       case DIREG:
   20335                 :             :       case SSE_FIRST_REG:
   20336                 :             :       case FP_TOP_REG:
   20337                 :             :       case FP_SECOND_REG:
   20338                 :             :         return true;
   20339                 :             : 
   20340                 :   477242138 :       default:
   20341                 :   477242138 :         break;
   20342                 :             :     }
   20343                 :             : 
   20344                 :   477242138 :   return false;
   20345                 :             : }
   20346                 :             : 
   20347                 :             : /* Return true if a set of DST by the expression SRC should be allowed.
   20348                 :             :    This prevents complex sets of likely_spilled hard regs before reload.  */
   20349                 :             : 
   20350                 :             : bool
   20351                 :   391805826 : ix86_hardreg_mov_ok (rtx dst, rtx src)
   20352                 :             : {
   20353                 :             :   /* Avoid complex sets of likely_spilled hard registers before reload.  */
   20354                 :   325988544 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   20355                 :   225302427 :       && !REG_P (src) && !MEM_P (src)
   20356                 :    45280311 :       && !(VECTOR_MODE_P (GET_MODE (dst))
   20357                 :    45280311 :            ? standard_sse_constant_p (src, GET_MODE (dst))
   20358                 :    22425316 :            : x86_64_immediate_operand (src, GET_MODE (dst)))
   20359                 :     8609356 :       && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
   20360                 :   399264047 :       && !reload_completed)
   20361                 :             :     return false;
   20362                 :             :   return true;
   20363                 :             : }
   20364                 :             : 
   20365                 :             : /* If we are copying between registers from different register sets
   20366                 :             :    (e.g. FP and integer), we may need a memory location.
   20367                 :             : 
   20368                 :             :    The function can't work reliably when one of the CLASSES is a class
   20369                 :             :    containing registers from multiple sets.  We avoid this by never combining
   20370                 :             :    different sets in a single alternative in the machine description.
   20371                 :             :    Ensure that this constraint holds to avoid unexpected surprises.
   20372                 :             : 
   20373                 :             :    When STRICT is false, we are being called from REGISTER_MOVE_COST,
   20374                 :             :    so do not enforce these sanity checks.
   20375                 :             : 
   20376                 :             :    To optimize register_move_cost performance, define inline variant.  */
   20377                 :             : 
   20378                 :             : static inline bool
   20379                 :  5436407639 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   20380                 :             :                                 reg_class_t class2, int strict)
   20381                 :             : {
   20382                 :  5436407639 :   if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
   20383                 :             :     return false;
   20384                 :             : 
   20385                 :  5407907016 :   if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
   20386                 :  4607749030 :       || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
   20387                 :  3934056680 :       || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
   20388                 :  3753272770 :       || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
   20389                 :  3582185506 :       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
   20390                 :  3582185506 :       || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
   20391                 :  3582185506 :       || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
   20392                 :  8827061552 :       || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
   20393                 :             :     {
   20394                 :  2144102590 :       gcc_assert (!strict || lra_in_progress);
   20395                 :             :       return true;
   20396                 :             :     }
   20397                 :             : 
   20398                 :  3263804426 :   if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
   20399                 :             :     return true;
   20400                 :             : 
   20401                 :             :   /* ??? This is a lie.  We do have moves between mmx/general, and for
   20402                 :             :      mmx/sse2.  But by saying we need secondary memory we discourage the
   20403                 :             :      register allocator from using the mmx registers unless needed.  */
   20404                 :  3120769793 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   20405                 :             :     return true;
   20406                 :             : 
   20407                 :             :   /* Between mask and general, we have moves no larger than word size.  */
   20408                 :  3029387618 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   20409                 :             :     {
   20410                 :     2375800 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
   20411                 :     2994092 :           || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   20412                 :      206510 :         return true;
   20413                 :             :     }
   20414                 :             : 
   20415                 :  3029181108 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   20416                 :             :     {
   20417                 :             :       /* SSE1 doesn't have any direct moves from other classes.  */
   20418                 :   658327933 :       if (!TARGET_SSE2)
   20419                 :             :         return true;
   20420                 :             : 
   20421                 :   655884745 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
   20422                 :             :         return true;
   20423                 :             : 
   20424                 :   655884745 :       int msize = GET_MODE_SIZE (mode);
   20425                 :             : 
   20426                 :             :       /* Between SSE and general, we have moves no larger than word size.  */
   20427                 :   672006045 :       if (msize > UNITS_PER_WORD)
   20428                 :             :         return true;
   20429                 :             : 
   20430                 :             :       /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
   20431                 :             :          Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16.  */
   20432                 :   565366987 :       int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
   20433                 :             : 
   20434                 :   565366987 :       if (msize < minsize)
   20435                 :             :         return true;
   20436                 :             : 
   20437                 :             :       /* If the target says that inter-unit moves are more expensive
   20438                 :             :          than moving through memory, then don't generate them.  */
   20439                 :   846254701 :       if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
   20440                 :   845770285 :           || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
   20441                 :     1292627 :         return true;
   20442                 :             :     }
   20443                 :             : 
   20444                 :             :   return false;
   20445                 :             : }
   20446                 :             : 
   20447                 :             : /* Implement TARGET_SECONDARY_MEMORY_NEEDED.  */
   20448                 :             : 
   20449                 :             : static bool
   20450                 :    59849946 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   20451                 :             :                               reg_class_t class2)
   20452                 :             : {
   20453                 :    59849946 :   return inline_secondary_memory_needed (mode, class1, class2, true);
   20454                 :             : }
   20455                 :             : 
   20456                 :             : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
   20457                 :             : 
   20458                 :             :    get_secondary_mem widens integral modes to BITS_PER_WORD.
   20459                 :             :    There is no need to emit full 64 bit move on 64 bit targets
   20460                 :             :    for integral modes that can be moved using 32 bit move.  */
   20461                 :             : 
   20462                 :             : static machine_mode
   20463                 :       12703 : ix86_secondary_memory_needed_mode (machine_mode mode)
   20464                 :             : {
   20465                 :       25406 :   if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
   20466                 :           8 :     return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
   20467                 :             :   return mode;
   20468                 :             : }
   20469                 :             : 
   20470                 :             : /* Implement the TARGET_CLASS_MAX_NREGS hook.
   20471                 :             : 
   20472                 :             :    On the 80386, this is the size of MODE in words,
   20473                 :             :    except in the FP regs, where a single reg is always enough.  */
   20474                 :             : 
   20475                 :             : static unsigned char
   20476                 :  6016622750 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
   20477                 :             : {
   20478                 :  6016622750 :   if (MAYBE_INTEGER_CLASS_P (rclass))
   20479                 :             :     {
   20480                 :  4037557215 :       if (mode == XFmode)
   20481                 :   140355029 :         return (TARGET_64BIT ? 2 : 3);
   20482                 :  3897202186 :       else if (mode == XCmode)
   20483                 :   140354676 :         return (TARGET_64BIT ? 4 : 6);
   20484                 :             :       else
   20485                 :  7618930412 :         return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   20486                 :             :     }
   20487                 :             :   else
   20488                 :             :     {
   20489                 :  1979065535 :       if (COMPLEX_MODE_P (mode))
   20490                 :             :         return 2;
   20491                 :             :       else
   20492                 :  1701770503 :         return 1;
   20493                 :             :     }
   20494                 :             : }
   20495                 :             : 
   20496                 :             : /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   20497                 :             : 
   20498                 :             : static bool
   20499                 :    35937356 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
   20500                 :             :                             reg_class_t regclass)
   20501                 :             : {
   20502                 :    35937356 :   if (from == to)
   20503                 :             :     return true;
   20504                 :             : 
   20505                 :             :   /* x87 registers can't do subreg at all, as all values are reformatted
   20506                 :             :      to extended precision.  */
   20507                 :    34424343 :   if (MAYBE_FLOAT_CLASS_P (regclass))
   20508                 :             :     return false;
   20509                 :             : 
   20510                 :    30803695 :   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
   20511                 :             :     {
   20512                 :             :       /* Vector registers do not support QI or HImode loads.  If we don't
   20513                 :             :          disallow a change to these modes, reload will assume it's ok to
   20514                 :             :          drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
   20515                 :             :          the vec_dupv4hi pattern.
   20516                 :             :          NB: SSE2 can load 16bit data to sse register via pinsrw.  */
   20517                 :    14470260 :       int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
   20518                 :    14470260 :       if (GET_MODE_SIZE (from) < mov_size
   20519                 :    28940449 :           || GET_MODE_SIZE (to) < mov_size)
   20520                 :     2227100 :         return false;
   20521                 :             :     }
   20522                 :             : 
   20523                 :             :   return true;
   20524                 :             : }
   20525                 :             : 
   20526                 :             : /* Return index of MODE in the sse load/store tables.  */
   20527                 :             : 
   20528                 :             : static inline int
   20529                 :   752055052 : sse_store_index (machine_mode mode)
   20530                 :             : {
   20531                 :             :   /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
   20532                 :             :      costs to processor_costs, which requires changes to all entries in
   20533                 :             :      processor cost table.  */
   20534                 :   752055052 :   if (mode == E_HFmode)
   20535                 :   131408729 :     mode = E_SFmode;
   20536                 :             : 
   20537                 :  1504110104 :   switch (GET_MODE_SIZE (mode))
   20538                 :             :     {
   20539                 :             :     case 4:
   20540                 :             :       return 0;
   20541                 :   145644684 :     case 8:
   20542                 :   145644684 :       return 1;
   20543                 :   205415273 :     case 16:
   20544                 :   205415273 :       return 2;
   20545                 :    27904026 :     case 32:
   20546                 :    27904026 :       return 3;
   20547                 :    23269971 :     case 64:
   20548                 :    23269971 :       return 4;
   20549                 :    90586990 :     default:
   20550                 :    90586990 :       return -1;
   20551                 :             :     }
   20552                 :             : }
   20553                 :             : 
   20554                 :             : /* Return the cost of moving data of mode M between a
   20555                 :             :    register and memory.  A value of 2 is the default; this cost is
   20556                 :             :    relative to those in `REGISTER_MOVE_COST'.
   20557                 :             : 
   20558                 :             :    This function is used extensively by register_move_cost that is used to
   20559                 :             :    build tables at startup.  Make it inline in this case.
   20560                 :             :    When IN is 2, return maximum of in and out move cost.
   20561                 :             : 
   20562                 :             :    If moving between registers and memory is more expensive than
   20563                 :             :    between two registers, you should define this macro to express the
   20564                 :             :    relative cost.
   20565                 :             : 
   20566                 :             :    Model also increased moving costs of QImode registers in non
   20567                 :             :    Q_REGS classes.
   20568                 :             :  */
   20569                 :             : static inline int
   20570                 :  6711149735 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
   20571                 :             : {
   20572                 :  6711149735 :   int cost;
   20573                 :             : 
   20574                 :  6711149735 :   if (FLOAT_CLASS_P (regclass))
   20575                 :             :     {
   20576                 :   345863186 :       int index;
   20577                 :   345863186 :       switch (mode)
   20578                 :             :         {
   20579                 :             :           case E_SFmode:
   20580                 :             :             index = 0;
   20581                 :             :             break;
   20582                 :             :           case E_DFmode:
   20583                 :             :             index = 1;
   20584                 :             :             break;
   20585                 :             :           case E_XFmode:
   20586                 :             :             index = 2;
   20587                 :             :             break;
   20588                 :             :           default:
   20589                 :             :             return 100;
   20590                 :             :         }
   20591                 :   101148324 :       if (in == 2)
   20592                 :    97371619 :         return MAX (ix86_cost->hard_register.fp_load [index],
   20593                 :             :                     ix86_cost->hard_register.fp_store [index]);
   20594                 :     3776705 :       return in ? ix86_cost->hard_register.fp_load [index]
   20595                 :     3776705 :                 : ix86_cost->hard_register.fp_store [index];
   20596                 :             :     }
   20597                 :  6365286549 :   if (SSE_CLASS_P (regclass))
   20598                 :             :     {
   20599                 :   629415986 :       int index = sse_store_index (mode);
   20600                 :   629415986 :       if (index == -1)
   20601                 :             :         return 100;
   20602                 :   539017178 :       if (in == 2)
   20603                 :   382476369 :         return MAX (ix86_cost->hard_register.sse_load [index],
   20604                 :             :                     ix86_cost->hard_register.sse_store [index]);
   20605                 :   156540809 :       return in ? ix86_cost->hard_register.sse_load [index]
   20606                 :   156540809 :                 : ix86_cost->hard_register.sse_store [index];
   20607                 :             :     }
   20608                 :  5735870563 :   if (MASK_CLASS_P (regclass))
   20609                 :             :     {
   20610                 :   108741512 :       int index;
   20611                 :   217483024 :       switch (GET_MODE_SIZE (mode))
   20612                 :             :         {
   20613                 :             :         case 1:
   20614                 :             :           index = 0;
   20615                 :             :           break;
   20616                 :     8561702 :         case 2:
   20617                 :     8561702 :           index = 1;
   20618                 :     8561702 :           break;
   20619                 :             :         /* DImode loads and stores assumed to cost the same as SImode.  */
   20620                 :    38496026 :         case 4:
   20621                 :    38496026 :         case 8:
   20622                 :    38496026 :           index = 2;
   20623                 :    38496026 :           break;
   20624                 :             :         default:
   20625                 :             :           return 100;
   20626                 :             :         }
   20627                 :             : 
   20628                 :    50486392 :       if (in == 2)
   20629                 :      553397 :         return MAX (ix86_cost->hard_register.mask_load[index],
   20630                 :             :                     ix86_cost->hard_register.mask_store[index]);
   20631                 :    49932995 :       return in ? ix86_cost->hard_register.mask_load[2]
   20632                 :    49932995 :                 : ix86_cost->hard_register.mask_store[2];
   20633                 :             :     }
   20634                 :  5627129051 :   if (MMX_CLASS_P (regclass))
   20635                 :             :     {
   20636                 :   167707515 :       int index;
   20637                 :   335415030 :       switch (GET_MODE_SIZE (mode))
   20638                 :             :         {
   20639                 :             :           case 4:
   20640                 :             :             index = 0;
   20641                 :             :             break;
   20642                 :    96961239 :           case 8:
   20643                 :    96961239 :             index = 1;
   20644                 :    96961239 :             break;
   20645                 :             :           default:
   20646                 :             :             return 100;
   20647                 :             :         }
   20648                 :   132754443 :       if (in == 2)
   20649                 :   113613453 :         return MAX (ix86_cost->hard_register.mmx_load [index],
   20650                 :             :                     ix86_cost->hard_register.mmx_store [index]);
   20651                 :    19140990 :       return in ? ix86_cost->hard_register.mmx_load [index]
   20652                 :    19140990 :                 : ix86_cost->hard_register.mmx_store [index];
   20653                 :             :     }
   20654                 : 10918843072 :   switch (GET_MODE_SIZE (mode))
   20655                 :             :     {
   20656                 :   119544945 :       case 1:
   20657                 :   119544945 :         if (Q_CLASS_P (regclass) || TARGET_64BIT)
   20658                 :             :           {
   20659                 :   117013061 :             if (!in)
   20660                 :    18771592 :               return ix86_cost->hard_register.int_store[0];
   20661                 :    98241469 :             if (TARGET_PARTIAL_REG_DEPENDENCY
   20662                 :    98241469 :                 && optimize_function_for_speed_p (cfun))
   20663                 :    91786074 :               cost = ix86_cost->hard_register.movzbl_load;
   20664                 :             :             else
   20665                 :     6455395 :               cost = ix86_cost->hard_register.int_load[0];
   20666                 :    98241469 :             if (in == 2)
   20667                 :    79447800 :               return MAX (cost, ix86_cost->hard_register.int_store[0]);
   20668                 :             :             return cost;
   20669                 :             :           }
   20670                 :             :         else
   20671                 :             :           {
   20672                 :     2531884 :            if (in == 2)
   20673                 :     1793060 :              return MAX (ix86_cost->hard_register.movzbl_load,
   20674                 :             :                          ix86_cost->hard_register.int_store[0] + 4);
   20675                 :      738824 :            if (in)
   20676                 :      369448 :              return ix86_cost->hard_register.movzbl_load;
   20677                 :             :            else
   20678                 :      369376 :              return ix86_cost->hard_register.int_store[0] + 4;
   20679                 :             :           }
   20680                 :   616918800 :         break;
   20681                 :   616918800 :       case 2:
   20682                 :   616918800 :         {
   20683                 :   616918800 :           int cost;
   20684                 :   616918800 :           if (in == 2)
   20685                 :   521191627 :             cost = MAX (ix86_cost->hard_register.int_load[1],
   20686                 :             :                         ix86_cost->hard_register.int_store[1]);
   20687                 :             :           else
   20688                 :    95727173 :             cost = in ? ix86_cost->hard_register.int_load[1]
   20689                 :             :                       : ix86_cost->hard_register.int_store[1];
   20690                 :             : 
   20691                 :   616918800 :           if (mode == E_HFmode)
   20692                 :             :             {
   20693                 :             :               /* Prefer SSE over GPR for HFmode.  */
   20694                 :   119589224 :               int sse_cost;
   20695                 :   119589224 :               int index = sse_store_index (mode);
   20696                 :   119589224 :               if (in == 2)
   20697                 :   110018704 :                 sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
   20698                 :             :                                 ix86_cost->hard_register.sse_store[index]);
   20699                 :             :               else
   20700                 :     9570520 :                 sse_cost = (in
   20701                 :     9570520 :                             ? ix86_cost->hard_register.sse_load [index]
   20702                 :             :                             : ix86_cost->hard_register.sse_store [index]);
   20703                 :   119589224 :               if (sse_cost >= cost)
   20704                 :   119589224 :                 cost = sse_cost + 1;
   20705                 :             :             }
   20706                 :             :           return cost;
   20707                 :             :         }
   20708                 :  4722957791 :       default:
   20709                 :  4722957791 :         if (in == 2)
   20710                 :  3612457606 :           cost = MAX (ix86_cost->hard_register.int_load[2],
   20711                 :             :                       ix86_cost->hard_register.int_store[2]);
   20712                 :  1110500185 :         else if (in)
   20713                 :   555412113 :           cost = ix86_cost->hard_register.int_load[2];
   20714                 :             :         else
   20715                 :   555088072 :           cost = ix86_cost->hard_register.int_store[2];
   20716                 :             :         /* Multiply with the number of GPR moves needed.  */
   20717                 :  9562005254 :         return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
   20718                 :             :     }
   20719                 :             : }
   20720                 :             : 
   20721                 :             : static int
   20722                 :  1785675697 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
   20723                 :             : {
   20724                 :  2678227357 :   return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
   20725                 :             : }
   20726                 :             : 
   20727                 :             : 
   20728                 :             : /* Return the cost of moving data from a register in class CLASS1 to
   20729                 :             :    one in class CLASS2.
   20730                 :             : 
   20731                 :             :    It is not required that the cost always equal 2 when FROM is the same as TO;
   20732                 :             :    on some machines it is expensive to move between registers if they are not
   20733                 :             :    general registers.  */
   20734                 :             : 
   20735                 :             : static int
   20736                 :  5376557693 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
   20737                 :             :                          reg_class_t class2_i)
   20738                 :             : {
   20739                 :  5376557693 :   enum reg_class class1 = (enum reg_class) class1_i;
   20740                 :  5376557693 :   enum reg_class class2 = (enum reg_class) class2_i;
   20741                 :             : 
   20742                 :             :   /* In case we require secondary memory, compute cost of the store followed
   20743                 :             :      by load.  In order to avoid bad register allocation choices, we need
   20744                 :             :      for this to be *at least* as high as the symmetric MEMORY_MOVE_COST.  */
   20745                 :             : 
   20746                 :  5376557693 :   if (inline_secondary_memory_needed (mode, class1, class2, false))
   20747                 :             :     {
   20748                 :  2462737019 :       int cost = 1;
   20749                 :             : 
   20750                 :  2462737019 :       cost += inline_memory_move_cost (mode, class1, 2);
   20751                 :  2462737019 :       cost += inline_memory_move_cost (mode, class2, 2);
   20752                 :             : 
   20753                 :             :       /* In case of copying from general_purpose_register we may emit multiple
   20754                 :             :          stores followed by single load causing memory size mismatch stall.
   20755                 :             :          Count this as arbitrarily high cost of 20.  */
   20756                 :  4925474038 :       if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
   20757                 :   738429215 :           && TARGET_MEMORY_MISMATCH_STALL
   20758                 :  3939595449 :           && targetm.class_max_nregs (class1, mode)
   20759                 :   738429215 :              > targetm.class_max_nregs (class2, mode))
   20760                 :   140978549 :         cost += 20;
   20761                 :             : 
   20762                 :             :       /* In the case of FP/MMX moves, the registers actually overlap, and we
   20763                 :             :          have to switch modes in order to treat them differently.  */
   20764                 :    56806763 :       if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
   20765                 :  2510597460 :           || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
   20766                 :    17892644 :         cost += 20;
   20767                 :             : 
   20768                 :  2462737019 :       return cost;
   20769                 :             :     }
   20770                 :             : 
   20771                 :             :   /* Moves between MMX and non-MMX units require secondary memory.  */
   20772                 :  2913820674 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   20773                 :           0 :     gcc_unreachable ();
   20774                 :             : 
   20775                 :  2913820674 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   20776                 :   556266003 :     return (SSE_CLASS_P (class1)
   20777                 :   556266003 :             ? ix86_cost->hard_register.sse_to_integer
   20778                 :             :             : ix86_cost->hard_register.integer_to_sse);
   20779                 :             : 
   20780                 :             :   /* Moves between mask register and GPR.  */
   20781                 :  2357554671 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   20782                 :             :     {
   20783                 :      979584 :       return (MASK_CLASS_P (class1)
   20784                 :      979584 :               ? ix86_cost->hard_register.mask_to_integer
   20785                 :             :               : ix86_cost->hard_register.integer_to_mask);
   20786                 :             :     }
   20787                 :             :   /* Moving between mask registers.  */
   20788                 :  2356575087 :   if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
   20789                 :       96705 :     return ix86_cost->hard_register.mask_move;
   20790                 :             : 
   20791                 :  2356478382 :   if (MAYBE_FLOAT_CLASS_P (class1))
   20792                 :    11313471 :     return ix86_cost->hard_register.fp_move;
   20793                 :  2345164911 :   if (MAYBE_SSE_CLASS_P (class1))
   20794                 :             :     {
   20795                 :   220054876 :       if (GET_MODE_BITSIZE (mode) <= 128)
   20796                 :   107666816 :         return ix86_cost->hard_register.xmm_move;
   20797                 :     4721244 :       if (GET_MODE_BITSIZE (mode) <= 256)
   20798                 :     1508899 :         return ix86_cost->hard_register.ymm_move;
   20799                 :      851723 :       return ix86_cost->hard_register.zmm_move;
   20800                 :             :     }
   20801                 :  2235137473 :   if (MAYBE_MMX_CLASS_P (class1))
   20802                 :     2080543 :     return ix86_cost->hard_register.mmx_move;
   20803                 :             :   return 2;
   20804                 :             : }
   20805                 :             : 
   20806                 :             : /* Implement TARGET_HARD_REGNO_NREGS.  This is ordinarily the length in
   20807                 :             :    words of a value of mode MODE but can be less for certain modes in
   20808                 :             :    special long registers.
   20809                 :             : 
   20810                 :             :    Actually there are no two word move instructions for consecutive
   20811                 :             :    registers.  And only registers 0-3 may have mov byte instructions
   20812                 :             :    applied to them.  */
   20813                 :             : 
   20814                 :             : static unsigned int
   20815                 :  9251119800 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
   20816                 :             : {
   20817                 :  9251119800 :   if (GENERAL_REGNO_P (regno))
   20818                 :             :     {
   20819                 :  3217780800 :       if (mode == XFmode)
   20820                 :    25226944 :         return TARGET_64BIT ? 2 : 3;
   20821                 :  3193028640 :       if (mode == XCmode)
   20822                 :    25226944 :         return TARGET_64BIT ? 4 : 6;
   20823                 :  6397325312 :       return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   20824                 :             :     }
   20825                 :  6033339000 :   if (COMPLEX_MODE_P (mode))
   20826                 :             :     return 2;
   20827                 :             :   /* Register pair for mask registers.  */
   20828                 :  5290774200 :   if (mode == P2QImode || mode == P2HImode)
   20829                 :             :     return 2;
   20830                 :  5197953600 :   if (mode == V64SFmode || mode == V64SImode)
   20831                 :    92820600 :     return 4;
   20832                 :             :   return 1;
   20833                 :             : }
   20834                 :             : 
   20835                 :             : /* Implement REGMODE_NATURAL_SIZE(MODE).  */
   20836                 :             : unsigned int
   20837                 :    96837765 : ix86_regmode_natural_size (machine_mode mode)
   20838                 :             : {
   20839                 :    96837765 :   if (mode == P2HImode || mode == P2QImode)
   20840                 :        2456 :     return GET_MODE_SIZE (mode) / 2;
   20841                 :    96836537 :   return UNITS_PER_WORD;
   20842                 :             : }
   20843                 :             : 
   20844                 :             : /* Implement TARGET_HARD_REGNO_MODE_OK.  */
   20845                 :             : 
   20846                 :             : static bool
   20847                 : 55400461973 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   20848                 :             : {
   20849                 :             :   /* Flags and only flags can only hold CCmode values.  */
   20850                 : 55400461973 :   if (CC_REGNO_P (regno))
   20851                 :   443146893 :     return GET_MODE_CLASS (mode) == MODE_CC;
   20852                 : 54957315080 :   if (GET_MODE_CLASS (mode) == MODE_CC
   20853                 :             :       || GET_MODE_CLASS (mode) == MODE_RANDOM)
   20854                 :             :     return false;
   20855                 : 49539588558 :   if (STACK_REGNO_P (regno))
   20856                 :  4840872871 :     return VALID_FP_MODE_P (mode);
   20857                 : 44698715687 :   if (MASK_REGNO_P (regno))
   20858                 :             :     {
   20859                 :             :       /* Register pair only starts at even register number.  */
   20860                 :  3804719174 :       if ((mode == P2QImode || mode == P2HImode))
   20861                 :    50651196 :         return MASK_PAIR_REGNO_P(regno);
   20862                 :             : 
   20863                 :  1128877362 :       return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
   20864                 :  4861338004 :               || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
   20865                 :             :     }
   20866                 :             : 
   20867                 : 40893996513 :   if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
   20868                 :             :     return false;
   20869                 :             : 
   20870                 : 39935943478 :   if (SSE_REGNO_P (regno))
   20871                 :             :     {
   20872                 :             :       /* We implement the move patterns for all vector modes into and
   20873                 :             :          out of SSE registers, even when no operation instructions
   20874                 :             :          are available.  */
   20875                 :             : 
   20876                 :             :       /* For AVX-512 we allow, regardless of regno:
   20877                 :             :           - XI mode
   20878                 :             :           - any of 512-bit wide vector mode
   20879                 :             :           - any scalar mode.  */
   20880                 : 17360428370 :       if (TARGET_AVX512F
   20881                 :  4507565946 :           && ((VALID_AVX512F_REG_OR_XI_MODE (mode) && TARGET_EVEX512)
   20882                 :  4206514702 :               || VALID_AVX512F_SCALAR_MODE (mode)))
   20883                 :             :         return true;
   20884                 :             : 
   20885                 :             :       /* For AVX-5124FMAPS or AVX-5124VNNIW
   20886                 :             :          allow V64SF and V64SI modes for special regnos.  */
   20887                 : 16759311357 :       if ((TARGET_AVX5124FMAPS || TARGET_AVX5124VNNIW)
   20888                 :   147318838 :           && (mode == V64SFmode || mode == V64SImode)
   20889                 :     2674752 :           && MOD4_SSE_REGNO_P (regno))
   20890                 :             :         return true;
   20891                 :             : 
   20892                 :             :       /* TODO check for QI/HI scalars.  */
   20893                 :             :       /* AVX512VL allows sse regs16+ for 128/256 bit modes.  */
   20894                 : 16758642105 :       if (TARGET_AVX512VL
   20895                 :  1876513759 :           && (VALID_AVX256_REG_OR_OI_MODE (mode)
   20896                 :  1674838176 :               || VALID_AVX512VL_128_REG_MODE (mode)))
   20897                 :             :         return true;
   20898                 :             : 
   20899                 :             :       /* xmm16-xmm31 are only available for AVX-512.  */
   20900                 : 16334303833 :       if (EXT_REX_SSE_REGNO_P (regno))
   20901                 :             :         return false;
   20902                 :             : 
   20903                 :             :       /* Use pinsrw/pextrw to mov 16-bit data from/to sse to/from integer.  */
   20904                 :  9393439687 :       if (TARGET_SSE2 && mode == HImode)
   20905                 :             :         return true;
   20906                 :             : 
   20907                 :             :       /* OImode and AVX modes are available only when AVX is enabled.  */
   20908                 :  9335699182 :       return ((TARGET_AVX
   20909                 :  2187439144 :                && VALID_AVX256_REG_OR_OI_MODE (mode))
   20910                 :             :               || VALID_SSE_REG_MODE (mode)
   20911                 :             :               || VALID_SSE2_REG_MODE (mode)
   20912                 :             :               || VALID_MMX_REG_MODE (mode)
   20913                 :  9335699182 :               || VALID_MMX_REG_MODE_3DNOW (mode));
   20914                 :             :     }
   20915                 : 22575515108 :   if (MMX_REGNO_P (regno))
   20916                 :             :     {
   20917                 :             :       /* We implement the move patterns for 3DNOW modes even in MMX mode,
   20918                 :             :          so if the register is available at all, then we can move data of
   20919                 :             :          the given mode into or out of it.  */
   20920                 :  4055852802 :       return (VALID_MMX_REG_MODE (mode)
   20921                 :             :               || VALID_MMX_REG_MODE_3DNOW (mode));
   20922                 :             :     }
   20923                 :             : 
   20924                 : 18519662306 :   if (mode == QImode)
   20925                 :             :     {
   20926                 :             :       /* Take care for QImode values - they can be in non-QI regs,
   20927                 :             :          but then they do cause partial register stalls.  */
   20928                 :   196418863 :       if (ANY_QI_REGNO_P (regno))
   20929                 :             :         return true;
   20930                 :    13347316 :       if (!TARGET_PARTIAL_REG_STALL)
   20931                 :             :         return true;
   20932                 :             :       /* LRA checks if the hard register is OK for the given mode.
   20933                 :             :          QImode values can live in non-QI regs, so we allow all
   20934                 :             :          registers here.  */
   20935                 :           0 :       if (lra_in_progress)
   20936                 :             :        return true;
   20937                 :           0 :       return !can_create_pseudo_p ();
   20938                 :             :     }
   20939                 :             :   /* We handle both integer and floats in the general purpose registers.  */
   20940                 : 18323243443 :   else if (VALID_INT_MODE_P (mode)
   20941                 : 13734577266 :            || VALID_FP_MODE_P (mode))
   20942                 :             :     return true;
   20943                 :             :   /* Lots of MMX code casts 8 byte vector modes to DImode.  If we then go
   20944                 :             :      on to use that value in smaller contexts, this can easily force a
   20945                 :             :      pseudo to be allocated to GENERAL_REGS.  Since this is no worse than
   20946                 :             :      supporting DImode, allow it.  */
   20947                 : 12715099496 :   else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
   20948                 :             :     return true;
   20949                 :             : 
   20950                 :             :   return false;
   20951                 :             : }
   20952                 :             : 
   20953                 :             : /* Implement TARGET_INSN_CALLEE_ABI.  */
   20954                 :             : 
   20955                 :             : const predefined_function_abi &
   20956                 :   243722291 : ix86_insn_callee_abi (const rtx_insn *insn)
   20957                 :             : {
   20958                 :   243722291 :   unsigned int abi_id = 0;
   20959                 :   243722291 :   rtx pat = PATTERN (insn);
   20960                 :   243722291 :   if (vzeroupper_pattern (pat, VOIDmode))
   20961                 :      227536 :     abi_id = ABI_VZEROUPPER;
   20962                 :             : 
   20963                 :   243722291 :   return function_abis[abi_id];
   20964                 :             : }
   20965                 :             : 
   20966                 :             : /* Initialize function_abis with corresponding abi_id,
   20967                 :             :    currently only handle vzeroupper.  */
   20968                 :             : void
   20969                 :       17334 : ix86_initialize_callee_abi (unsigned int abi_id)
   20970                 :             : {
   20971                 :       17334 :   gcc_assert (abi_id == ABI_VZEROUPPER);
   20972                 :       17334 :   predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
   20973                 :       17334 :   if (!vzeroupper_abi.initialized_p ())
   20974                 :             :     {
   20975                 :             :       HARD_REG_SET full_reg_clobbers;
   20976                 :        3997 :       CLEAR_HARD_REG_SET (full_reg_clobbers);
   20977                 :        3997 :       vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
   20978                 :             :     }
   20979                 :       17334 : }
   20980                 :             : 
   20981                 :             : void
   20982                 :       17334 : ix86_expand_avx_vzeroupper (void)
   20983                 :             : {
   20984                 :             :   /* Initialize vzeroupper_abi here.  */
   20985                 :       17334 :   ix86_initialize_callee_abi (ABI_VZEROUPPER);
   20986                 :       17334 :   rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
   20987                 :             :   /* Return false for non-local goto in can_nonlocal_goto.  */
   20988                 :       17334 :   make_reg_eh_region_note (insn, 0, INT_MIN);
   20989                 :             :   /* Flag used for call_insn indicates it's a fake call.  */
   20990                 :       17334 :   RTX_FLAG (insn, used) = 1;
   20991                 :       17334 : }
   20992                 :             : 
   20993                 :             : 
   20994                 :             : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The only ABI that
   20995                 :             :    saves SSE registers across calls is Win64 (thus no need to check the
   20996                 :             :    current ABI here), and with AVX enabled Win64 only guarantees that
   20997                 :             :    the low 16 bytes are saved.  */
   20998                 :             : 
   20999                 :             : static bool
   21000                 :  1994421818 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
   21001                 :             :                                      machine_mode mode)
   21002                 :             : {
   21003                 :             :   /* Special ABI for vzeroupper which only clobber higher part of sse regs.  */
   21004                 :  1994421818 :   if (abi_id == ABI_VZEROUPPER)
   21005                 :    28816397 :       return (GET_MODE_SIZE (mode) > 16
   21006                 :    28816397 :               && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
   21007                 :     4388762 :                   || LEGACY_SSE_REGNO_P (regno)));
   21008                 :             : 
   21009                 :  2573477497 :   return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
   21010                 :             : }
   21011                 :             : 
   21012                 :             : /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a
   21013                 :             :    tieable integer mode.  */
   21014                 :             : 
   21015                 :             : static bool
   21016                 :    48647052 : ix86_tieable_integer_mode_p (machine_mode mode)
   21017                 :             : {
   21018                 :    48647052 :   switch (mode)
   21019                 :             :     {
   21020                 :             :     case E_HImode:
   21021                 :             :     case E_SImode:
   21022                 :             :       return true;
   21023                 :             : 
   21024                 :     5286699 :     case E_QImode:
   21025                 :     5286699 :       return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
   21026                 :             : 
   21027                 :     9218295 :     case E_DImode:
   21028                 :     9218295 :       return TARGET_64BIT;
   21029                 :             : 
   21030                 :             :     default:
   21031                 :             :       return false;
   21032                 :             :     }
   21033                 :             : }
   21034                 :             : 
   21035                 :             : /* Implement TARGET_MODES_TIEABLE_P.
   21036                 :             : 
   21037                 :             :    Return true if MODE1 is accessible in a register that can hold MODE2
   21038                 :             :    without copying.  That is, all register classes that can hold MODE2
   21039                 :             :    can also hold MODE1.  */
   21040                 :             : 
   21041                 :             : static bool
   21042                 :    31385905 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   21043                 :             : {
   21044                 :    31385905 :   if (mode1 == mode2)
   21045                 :             :     return true;
   21046                 :             : 
   21047                 :    31290858 :   if (ix86_tieable_integer_mode_p (mode1)
   21048                 :    31290858 :       && ix86_tieable_integer_mode_p (mode2))
   21049                 :             :     return true;
   21050                 :             : 
   21051                 :             :   /* MODE2 being XFmode implies fp stack or general regs, which means we
   21052                 :             :      can tie any smaller floating point modes to it.  Note that we do not
   21053                 :             :      tie this with TFmode.  */
   21054                 :    22829764 :   if (mode2 == XFmode)
   21055                 :        4319 :     return mode1 == SFmode || mode1 == DFmode;
   21056                 :             : 
   21057                 :             :   /* MODE2 being DFmode implies fp stack, general or sse regs, which means
   21058                 :             :      that we can tie it with SFmode.  */
   21059                 :    22825445 :   if (mode2 == DFmode)
   21060                 :      259277 :     return mode1 == SFmode;
   21061                 :             : 
   21062                 :             :   /* If MODE2 is only appropriate for an SSE register, then tie with
   21063                 :             :      any other mode acceptable to SSE registers.  */
   21064                 :    22566168 :   if (GET_MODE_SIZE (mode2) == 64
   21065                 :    22566168 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21066                 :      307123 :     return (GET_MODE_SIZE (mode1) == 64
   21067                 :      307123 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21068                 :    22259045 :   if (GET_MODE_SIZE (mode2) == 32
   21069                 :    22259045 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21070                 :      439717 :     return (GET_MODE_SIZE (mode1) == 32
   21071                 :      439717 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21072                 :    21819328 :   if (GET_MODE_SIZE (mode2) == 16
   21073                 :    21819328 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   21074                 :     8926030 :     return (GET_MODE_SIZE (mode1) == 16
   21075                 :     8926030 :             && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
   21076                 :             : 
   21077                 :             :   /* If MODE2 is appropriate for an MMX register, then tie
   21078                 :             :      with any other mode acceptable to MMX registers.  */
   21079                 :    12893298 :   if (GET_MODE_SIZE (mode2) == 8
   21080                 :    12893298 :       && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
   21081                 :     3362187 :     return (GET_MODE_SIZE (mode1) == 8
   21082                 :     3362187 :             && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
   21083                 :             : 
   21084                 :             :   /* SCmode and DImode can be tied.  */
   21085                 :     9531111 :   if ((mode1 == E_SCmode && mode2 == E_DImode)
   21086                 :     9531111 :       || (mode1 == E_DImode && mode2 == E_SCmode))
   21087                 :         108 :     return TARGET_64BIT;
   21088                 :             : 
   21089                 :             :   /* [SD]Cmode and V2[SD]Fmode modes can be tied.  */
   21090                 :     9531003 :   if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
   21091                 :     9531003 :       || (mode1 == E_V2SFmode && mode2 == E_SCmode)
   21092                 :     9531003 :       || (mode1 == E_DCmode && mode2 == E_V2DFmode)
   21093                 :     9531003 :       || (mode1 == E_V2DFmode && mode2 == E_DCmode))
   21094                 :             :     return true;
   21095                 :             : 
   21096                 :             :   return false;
   21097                 :             : }
   21098                 :             : 
   21099                 :             : /* Return the cost of moving between two registers of mode MODE.  */
   21100                 :             : 
   21101                 :             : static int
   21102                 :    30498449 : ix86_set_reg_reg_cost (machine_mode mode)
   21103                 :             : {
   21104                 :    30498449 :   unsigned int units = UNITS_PER_WORD;
   21105                 :             : 
   21106                 :    30498449 :   switch (GET_MODE_CLASS (mode))
   21107                 :             :     {
   21108                 :             :     default:
   21109                 :             :       break;
   21110                 :             : 
   21111                 :           0 :     case MODE_CC:
   21112                 :           0 :       units = GET_MODE_SIZE (CCmode);
   21113                 :           0 :       break;
   21114                 :             : 
   21115                 :     1124843 :     case MODE_FLOAT:
   21116                 :     1124843 :       if ((TARGET_SSE && mode == TFmode)
   21117                 :      660951 :           || (TARGET_80387 && mode == XFmode)
   21118                 :      204938 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
   21119                 :      142917 :           || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
   21120                 :     2220380 :         units = GET_MODE_SIZE (mode);
   21121                 :             :       break;
   21122                 :             : 
   21123                 :     1252750 :     case MODE_COMPLEX_FLOAT:
   21124                 :     1252750 :       if ((TARGET_SSE && mode == TCmode)
   21125                 :      839920 :           || (TARGET_80387 && mode == XCmode)
   21126                 :      426984 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
   21127                 :       14034 :           || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
   21128                 :     2499160 :         units = GET_MODE_SIZE (mode);
   21129                 :             :       break;
   21130                 :             : 
   21131                 :    20415788 :     case MODE_VECTOR_INT:
   21132                 :    20415788 :     case MODE_VECTOR_FLOAT:
   21133                 :    20415788 :       if ((TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
   21134                 :    20323829 :           || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   21135                 :    20153894 :           || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   21136                 :    17634805 :           || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   21137                 :    16382581 :           || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   21138                 :    16331507 :               && VALID_MMX_REG_MODE (mode)))
   21139                 :     8167934 :         units = GET_MODE_SIZE (mode);
   21140                 :             :     }
   21141                 :             : 
   21142                 :             :   /* Return the cost of moving between two registers of mode MODE,
   21143                 :             :      assuming that the move will be in pieces of at most UNITS bytes.  */
   21144                 :    30498449 :   return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
   21145                 :             : }
   21146                 :             : 
   21147                 :             : /* Return cost of vector operation in MODE given that scalar version has
   21148                 :             :    COST.  */
   21149                 :             : 
   21150                 :             : static int
   21151                 :  2803969236 : ix86_vec_cost (machine_mode mode, int cost)
   21152                 :             : {
   21153                 :  2803969236 :   if (!VECTOR_MODE_P (mode))
   21154                 :             :     return cost;
   21155                 :             : 
   21156                 :  2802949302 :   if (GET_MODE_BITSIZE (mode) == 128
   21157                 :  2802949302 :       && TARGET_SSE_SPLIT_REGS)
   21158                 :     3085568 :     return cost * GET_MODE_BITSIZE (mode) / 64;
   21159                 :  2801406518 :   else if (GET_MODE_BITSIZE (mode) > 128
   21160                 :  2801406518 :       && TARGET_AVX256_SPLIT_REGS)
   21161                 :     1659712 :     return cost * GET_MODE_BITSIZE (mode) / 128;
   21162                 :  2800576662 :   else if (GET_MODE_BITSIZE (mode) > 256
   21163                 :  2800576662 :       && TARGET_AVX512_SPLIT_REGS)
   21164                 :       99248 :     return cost * GET_MODE_BITSIZE (mode) / 256;
   21165                 :             :   return cost;
   21166                 :             : }
   21167                 :             : 
   21168                 :             : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
   21169                 :             :    vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2.  */
   21170                 :             : static int
   21171                 :        1460 : ix86_widen_mult_cost (const struct processor_costs *cost,
   21172                 :             :                       enum machine_mode mode, bool uns_p)
   21173                 :             : {
   21174                 :        1460 :   gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
   21175                 :        1460 :   int extra_cost = 0;
   21176                 :        1460 :   int basic_cost = 0;
   21177                 :        1460 :   switch (mode)
   21178                 :             :     {
   21179                 :         225 :     case V8HImode:
   21180                 :         225 :     case V16HImode:
   21181                 :         225 :       if (!uns_p || mode == V16HImode)
   21182                 :          47 :         extra_cost = cost->sse_op * 2;
   21183                 :         225 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   21184                 :         225 :       break;
   21185                 :         319 :     case V4SImode:
   21186                 :         319 :     case V8SImode:
   21187                 :             :       /* pmulhw/pmullw can be used.  */
   21188                 :         319 :       basic_cost = cost->mulss * 2 + cost->sse_op * 2;
   21189                 :         319 :       break;
   21190                 :         843 :     case V2DImode:
   21191                 :             :       /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
   21192                 :             :          require extra 4 mul, 4 add, 4 cmp and 2 shift.  */
   21193                 :         843 :       if (!TARGET_SSE4_1 && !uns_p)
   21194                 :         438 :         extra_cost = (cost->mulss + cost->addss + cost->sse_op) * 4
   21195                 :         438 :                       + cost->sse_op * 2;
   21196                 :             :       /* Fallthru.  */
   21197                 :         913 :     case V4DImode:
   21198                 :         913 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   21199                 :         913 :       break;
   21200                 :             :     default:
   21201                 :             :       /* Not implemented.  */
   21202                 :             :       return 100;
   21203                 :             :     }
   21204                 :        1457 :   return ix86_vec_cost (mode, basic_cost + extra_cost);
   21205                 :             : }
   21206                 :             : 
   21207                 :             : /* Return cost of multiplication in MODE.  */
   21208                 :             : 
   21209                 :             : static int
   21210                 :  1196841745 : ix86_multiplication_cost (const struct processor_costs *cost,
   21211                 :             :                           enum machine_mode mode)
   21212                 :             : {
   21213                 :  1196841745 :   machine_mode inner_mode = mode;
   21214                 :  1196841745 :   if (VECTOR_MODE_P (mode))
   21215                 :  1195912910 :     inner_mode = GET_MODE_INNER (mode);
   21216                 :             : 
   21217                 :  1196841745 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   21218                 :      694425 :     return inner_mode == DFmode ? cost->mulsd : cost->mulss;
   21219                 :  1196147320 :   else if (X87_FLOAT_MODE_P (mode))
   21220                 :      166002 :     return cost->fmul;
   21221                 :  1195981318 :   else if (FLOAT_MODE_P (mode))
   21222                 :      183921 :     return  ix86_vec_cost (mode,
   21223                 :      183921 :                            inner_mode == DFmode ? cost->mulsd : cost->mulss);
   21224                 :  1195797397 :   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21225                 :             :     {
   21226                 :  1195753029 :       int nmults, nops;
   21227                 :             :       /* Cost of reading the memory.  */
   21228                 :  1195753029 :       int extra;
   21229                 :             : 
   21230                 :  1195753029 :       switch (mode)
   21231                 :             :         {
   21232                 :    18216139 :         case V4QImode:
   21233                 :    18216139 :         case V8QImode:
   21234                 :             :           /* Partial V*QImode is emulated with 4-6 insns.  */
   21235                 :    18216139 :           nmults = 1;
   21236                 :    18216139 :           nops = 3;
   21237                 :    18216139 :           extra = 0;
   21238                 :             : 
   21239                 :    18216139 :           if (TARGET_AVX512BW && TARGET_AVX512VL)
   21240                 :             :             ;
   21241                 :    18122566 :           else if (TARGET_AVX2)
   21242                 :             :             nops += 2;
   21243                 :    17630996 :           else if (TARGET_XOP)
   21244                 :       10472 :             extra += cost->sse_load[2];
   21245                 :             :           else
   21246                 :             :             {
   21247                 :    17620524 :               nops += 1;
   21248                 :    17620524 :               extra += cost->sse_load[2];
   21249                 :             :             }
   21250                 :    18216139 :           goto do_qimode;
   21251                 :             : 
   21252                 :     9109281 :         case V16QImode:
   21253                 :             :           /* V*QImode is emulated with 4-11 insns.  */
   21254                 :     9109281 :           nmults = 1;
   21255                 :     9109281 :           nops = 3;
   21256                 :     9109281 :           extra = 0;
   21257                 :             : 
   21258                 :     9109281 :           if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
   21259                 :             :             {
   21260                 :      291020 :               if (!(TARGET_AVX512BW && TARGET_AVX512VL))
   21261                 :      244416 :                 nops += 3;
   21262                 :             :             }
   21263                 :     8818261 :           else if (TARGET_XOP)
   21264                 :             :             {
   21265                 :        5728 :               nmults += 1;
   21266                 :        5728 :               nops += 2;
   21267                 :        5728 :               extra += cost->sse_load[2];
   21268                 :             :             }
   21269                 :             :           else
   21270                 :             :             {
   21271                 :     8812533 :               nmults += 1;
   21272                 :     8812533 :               nops += 4;
   21273                 :     8812533 :               extra += cost->sse_load[2];
   21274                 :             :             }
   21275                 :     9109281 :           goto do_qimode;
   21276                 :             : 
   21277                 :     9108090 :         case V32QImode:
   21278                 :     9108090 :           nmults = 1;
   21279                 :     9108090 :           nops = 3;
   21280                 :     9108090 :           extra = 0;
   21281                 :             : 
   21282                 :     9108090 :           if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
   21283                 :             :             {
   21284                 :     9033973 :               nmults += 1;
   21285                 :     9033973 :               nops += 4;
   21286                 :     9033973 :               extra += cost->sse_load[3] * 2;
   21287                 :             :             }
   21288                 :     9108090 :           goto do_qimode;
   21289                 :             : 
   21290                 :     9107568 :         case V64QImode:
   21291                 :     9107568 :           nmults = 2;
   21292                 :     9107568 :           nops = 9;
   21293                 :     9107568 :           extra = cost->sse_load[3] * 2 + cost->sse_load[4] * 2;
   21294                 :             : 
   21295                 :    45541078 :         do_qimode:
   21296                 :    45541078 :           return ix86_vec_cost (mode, cost->mulss * nmults
   21297                 :    45541078 :                                 + cost->sse_op * nops) + extra;
   21298                 :             : 
   21299                 :    38942617 :         case V4SImode:
   21300                 :             :           /* pmulld is used in this case. No emulation is needed.  */
   21301                 :    38942617 :           if (TARGET_SSE4_1)
   21302                 :     1870644 :             goto do_native;
   21303                 :             :           /* V4SImode is emulated with 7 insns.  */
   21304                 :             :           else
   21305                 :    37071973 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
   21306                 :             : 
   21307                 :   157402773 :         case V2DImode:
   21308                 :   157402773 :         case V4DImode:
   21309                 :             :           /* vpmullq is used in this case. No emulation is needed.  */
   21310                 :   157402773 :           if (TARGET_AVX512DQ && TARGET_AVX512VL)
   21311                 :      428921 :             goto do_native;
   21312                 :             :           /* V*DImode is emulated with 6-8 insns.  */
   21313                 :   156973852 :           else if (TARGET_XOP && mode == V2DImode)
   21314                 :       57883 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
   21315                 :             :           /* FALLTHRU */
   21316                 :   235573299 :         case V8DImode:
   21317                 :             :           /* vpmullq is used in this case. No emulation is needed.  */
   21318                 :   235573299 :           if (TARGET_AVX512DQ && mode == V8DImode)
   21319                 :      304815 :             goto do_native;
   21320                 :             :           else
   21321                 :   235268484 :             return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
   21322                 :             : 
   21323                 :   877813611 :         default:
   21324                 :   877813611 :         do_native:
   21325                 :   877813611 :           return ix86_vec_cost (mode, cost->mulss);
   21326                 :             :         }
   21327                 :             :     }
   21328                 :             :   else
   21329                 :       88736 :     return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
   21330                 :             : }
   21331                 :             : 
   21332                 :             : /* Return cost of multiplication in MODE.  */
   21333                 :             : 
   21334                 :             : static int
   21335                 :    71024058 : ix86_division_cost (const struct processor_costs *cost,
   21336                 :             :                           enum machine_mode mode)
   21337                 :             : {
   21338                 :    71024058 :   machine_mode inner_mode = mode;
   21339                 :    71024058 :   if (VECTOR_MODE_P (mode))
   21340                 :    52998542 :     inner_mode = GET_MODE_INNER (mode);
   21341                 :             : 
   21342                 :    71024058 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   21343                 :      222320 :     return inner_mode == DFmode ? cost->divsd : cost->divss;
   21344                 :    70801738 :   else if (X87_FLOAT_MODE_P (mode))
   21345                 :       47032 :     return cost->fdiv;
   21346                 :    70754706 :   else if (FLOAT_MODE_P (mode))
   21347                 :       13008 :     return ix86_vec_cost (mode,
   21348                 :       13008 :                           inner_mode == DFmode ? cost->divsd : cost->divss);
   21349                 :             :   else
   21350                 :   141483396 :     return cost->divide[MODE_INDEX (mode)];
   21351                 :             : }
   21352                 :             : 
   21353                 :             : /* Return cost of shift in MODE.
   21354                 :             :    If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
   21355                 :             :    AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
   21356                 :             :    if op1 is a result of subreg.
   21357                 :             : 
   21358                 :             :    SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored.  */
   21359                 :             : 
   21360                 :             : static int
   21361                 :   756072024 : ix86_shift_rotate_cost (const struct processor_costs *cost,
   21362                 :             :                         enum rtx_code code,
   21363                 :             :                         enum machine_mode mode, bool constant_op1,
   21364                 :             :                         HOST_WIDE_INT op1_val,
   21365                 :             :                         bool and_in_op1,
   21366                 :             :                         bool shift_and_truncate,
   21367                 :             :                         bool *skip_op0, bool *skip_op1)
   21368                 :             : {
   21369                 :   756072024 :   if (skip_op0)
   21370                 :   756034310 :     *skip_op0 = *skip_op1 = false;
   21371                 :             : 
   21372                 :   756072024 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21373                 :             :     {
   21374                 :   394484997 :       int count;
   21375                 :             :       /* Cost of reading the memory.  */
   21376                 :   394484997 :       int extra;
   21377                 :             : 
   21378                 :   394484997 :       switch (mode)
   21379                 :             :         {
   21380                 :     5795642 :         case V4QImode:
   21381                 :     5795642 :         case V8QImode:
   21382                 :     5795642 :           if (TARGET_AVX2)
   21383                 :             :             /* Use vpbroadcast.  */
   21384                 :      186156 :             extra = cost->sse_op;
   21385                 :             :           else
   21386                 :     5609486 :             extra = cost->sse_load[2];
   21387                 :             : 
   21388                 :     5795642 :           if (constant_op1)
   21389                 :             :             {
   21390                 :     5795630 :               if (code == ASHIFTRT)
   21391                 :             :                 {
   21392                 :          38 :                   count = 4;
   21393                 :          38 :                   extra *= 2;
   21394                 :             :                 }
   21395                 :             :               else
   21396                 :             :                 count = 2;
   21397                 :             :             }
   21398                 :          12 :           else if (TARGET_AVX512BW && TARGET_AVX512VL)
   21399                 :          12 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   21400                 :           0 :           else if (TARGET_SSE4_1)
   21401                 :             :             count = 5;
   21402                 :           0 :           else if (code == ASHIFTRT)
   21403                 :             :             count = 6;
   21404                 :             :           else
   21405                 :           0 :             count = 5;
   21406                 :     5795630 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   21407                 :             : 
   21408                 :     2900090 :         case V16QImode:
   21409                 :     2900090 :           if (TARGET_XOP)
   21410                 :             :             {
   21411                 :             :               /* For XOP we use vpshab, which requires a broadcast of the
   21412                 :             :                  value to the variable shift insn.  For constants this
   21413                 :             :                  means a V16Q const in mem; even when we can perform the
   21414                 :             :                  shift with one insn set the cost to prefer paddb.  */
   21415                 :        4002 :               if (constant_op1)
   21416                 :             :                 {
   21417                 :        3044 :                   extra = cost->sse_load[2];
   21418                 :        3044 :                   return ix86_vec_cost (mode, cost->sse_op) + extra;
   21419                 :             :                 }
   21420                 :             :               else
   21421                 :             :                 {
   21422                 :         958 :                   count = (code == ASHIFT) ? 3 : 4;
   21423                 :         958 :                   return ix86_vec_cost (mode, cost->sse_op * count);
   21424                 :             :                 }
   21425                 :             :             }
   21426                 :             :           /* FALLTHRU */
   21427                 :     5793864 :         case V32QImode:
   21428                 :     5793864 :           if (TARGET_AVX2)
   21429                 :             :             /* Use vpbroadcast.  */
   21430                 :      185099 :             extra = cost->sse_op;
   21431                 :             :           else
   21432                 :     5608765 :             extra = (mode == V16QImode) ? cost->sse_load[2] : cost->sse_load[3];
   21433                 :             : 
   21434                 :     5793864 :           if (constant_op1)
   21435                 :             :             {
   21436                 :     5793812 :               if (code == ASHIFTRT)
   21437                 :             :                 {
   21438                 :          66 :                   count = 4;
   21439                 :          66 :                   extra *= 2;
   21440                 :             :                 }
   21441                 :             :               else
   21442                 :             :                 count = 2;
   21443                 :             :             }
   21444                 :          52 :           else if (TARGET_AVX512BW
   21445                 :          36 :                    && ((mode == V32QImode && !TARGET_PREFER_AVX256)
   21446                 :          18 :                        || (mode == V16QImode && TARGET_AVX512VL
   21447                 :          18 :                            && !TARGET_PREFER_AVX128)))
   21448                 :          36 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   21449                 :          16 :           else if (TARGET_AVX2
   21450                 :           0 :                    && mode == V16QImode && !TARGET_PREFER_AVX128)
   21451                 :             :             count = 6;
   21452                 :          16 :           else if (TARGET_SSE4_1)
   21453                 :             :             count = 9;
   21454                 :          16 :           else if (code == ASHIFTRT)
   21455                 :             :             count = 10;
   21456                 :             :           else
   21457                 :          16 :             count = 9;
   21458                 :     5793828 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   21459                 :             : 
   21460                 :    52239119 :         case V2DImode:
   21461                 :    52239119 :         case V4DImode:
   21462                 :             :           /* V*DImode arithmetic right shift is emulated.  */
   21463                 :    52239119 :           if (code == ASHIFTRT && !TARGET_AVX512VL)
   21464                 :             :             {
   21465                 :        1315 :               if (constant_op1)
   21466                 :             :                 {
   21467                 :         492 :                   if (op1_val == 63)
   21468                 :          14 :                     count = TARGET_SSE4_2 ? 1 : 2;
   21469                 :         478 :                   else if (TARGET_XOP)
   21470                 :             :                     count = 2;
   21471                 :          81 :                   else if (TARGET_SSE4_1)
   21472                 :             :                     count = 3;
   21473                 :             :                   else
   21474                 :          80 :                     count = 4;
   21475                 :             :                 }
   21476                 :         823 :               else if (TARGET_XOP)
   21477                 :             :                 count = 3;
   21478                 :          10 :               else if (TARGET_SSE4_2)
   21479                 :             :                 count = 4;
   21480                 :             :               else
   21481                 :        1315 :                 count = 5;
   21482                 :             : 
   21483                 :        1315 :               return ix86_vec_cost (mode, cost->sse_op * count);
   21484                 :             :             }
   21485                 :             :           /* FALLTHRU */
   21486                 :   382890174 :         default:
   21487                 :   382890174 :           return ix86_vec_cost (mode, cost->sse_op);
   21488                 :             :         }
   21489                 :             :     }
   21490                 :             : 
   21491                 :   731487234 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21492                 :             :     {
   21493                 :   186006312 :       if (constant_op1)
   21494                 :             :         {
   21495                 :   185971731 :           if (op1_val > 32)
   21496                 :   132403842 :             return cost->shift_const + COSTS_N_INSNS (2);
   21497                 :             :           else
   21498                 :    53567889 :             return cost->shift_const * 2;
   21499                 :             :         }
   21500                 :             :       else
   21501                 :             :         {
   21502                 :       34581 :           if (and_in_op1)
   21503                 :          63 :             return cost->shift_var * 2;
   21504                 :             :           else
   21505                 :       34518 :             return cost->shift_var * 6 + COSTS_N_INSNS (2);
   21506                 :             :         }
   21507                 :             :     }
   21508                 :             :   else
   21509                 :             :     {
   21510                 :   175580715 :       if (constant_op1)
   21511                 :   174932329 :         return cost->shift_const;
   21512                 :      648386 :       else if (shift_and_truncate)
   21513                 :             :         {
   21514                 :       19057 :           if (skip_op0)
   21515                 :       19057 :             *skip_op0 = *skip_op1 = true;
   21516                 :             :           /* Return the cost after shift-and truncation.  */
   21517                 :       19057 :           return cost->shift_var;
   21518                 :             :         }
   21519                 :             :       else
   21520                 :      629329 :         return cost->shift_var;
   21521                 :             :     }
   21522                 :             : }
   21523                 :             : 
   21524                 :             : /* Compute a (partial) cost for rtx X.  Return true if the complete
   21525                 :             :    cost has been computed, and false if subexpressions should be
   21526                 :             :    scanned.  In either case, *TOTAL contains the cost result.  */
   21527                 :             : 
   21528                 :             : static bool
   21529                 :  7572906080 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
   21530                 :             :                 int *total, bool speed)
   21531                 :             : {
   21532                 :  7572906080 :   rtx mask;
   21533                 :  7572906080 :   enum rtx_code code = GET_CODE (x);
   21534                 :  7572906080 :   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   21535                 : 15145812160 :   const struct processor_costs *cost
   21536                 :  7572906080 :     = speed ? ix86_tune_cost : &ix86_size_cost;
   21537                 :  7572906080 :   int src_cost;
   21538                 :             : 
   21539                 :  7572906080 :   switch (code)
   21540                 :             :     {
   21541                 :    46964716 :     case SET:
   21542                 :    46964716 :       if (register_operand (SET_DEST (x), VOIDmode)
   21543                 :    46964716 :           && register_operand (SET_SRC (x), VOIDmode))
   21544                 :             :         {
   21545                 :    30498449 :           *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
   21546                 :    30498449 :           return true;
   21547                 :             :         }
   21548                 :             : 
   21549                 :    16466267 :       if (register_operand (SET_SRC (x), VOIDmode))
   21550                 :             :         /* Avoid potentially incorrect high cost from rtx_costs
   21551                 :             :            for non-tieable SUBREGs.  */
   21552                 :             :         src_cost = 0;
   21553                 :             :       else
   21554                 :             :         {
   21555                 :    14213466 :           src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
   21556                 :             : 
   21557                 :    14213466 :           if (CONSTANT_P (SET_SRC (x)))
   21558                 :             :             /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
   21559                 :             :                a small value, possibly zero for cheap constants.  */
   21560                 :     6375128 :             src_cost += COSTS_N_INSNS (1);
   21561                 :             :         }
   21562                 :             : 
   21563                 :    16466267 :       *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
   21564                 :    16466267 :       return true;
   21565                 :             : 
   21566                 :  2801806269 :     case CONST_INT:
   21567                 :  2801806269 :     case CONST:
   21568                 :  2801806269 :     case LABEL_REF:
   21569                 :  2801806269 :     case SYMBOL_REF:
   21570                 :  2801806269 :       if (x86_64_immediate_operand (x, VOIDmode))
   21571                 :  2221176384 :         *total = 0;
   21572                 :             :      else
   21573                 :   580629885 :         *total = 1;
   21574                 :             :       return true;
   21575                 :             : 
   21576                 :     7288571 :     case CONST_DOUBLE:
   21577                 :     7288571 :       if (IS_STACK_MODE (mode))
   21578                 :     1283395 :         switch (standard_80387_constant_p (x))
   21579                 :             :           {
   21580                 :             :           case -1:
   21581                 :             :           case 0:
   21582                 :             :             break;
   21583                 :      260439 :           case 1: /* 0.0 */
   21584                 :      260439 :             *total = 1;
   21585                 :      260439 :             return true;
   21586                 :      485551 :           default: /* Other constants */
   21587                 :      485551 :             *total = 2;
   21588                 :      485551 :             return true;
   21589                 :             :           }
   21590                 :             :       /* FALLTHRU */
   21591                 :             : 
   21592                 :    12518444 :     case CONST_VECTOR:
   21593                 :    12518444 :       switch (standard_sse_constant_p (x, mode))
   21594                 :             :         {
   21595                 :             :         case 0:
   21596                 :             :           break;
   21597                 :     3336052 :         case 1:  /* 0: xor eliminates false dependency */
   21598                 :     3336052 :           *total = 0;
   21599                 :     3336052 :           return true;
   21600                 :       39191 :         default: /* -1: cmp contains false dependency */
   21601                 :       39191 :           *total = 1;
   21602                 :       39191 :           return true;
   21603                 :             :         }
   21604                 :             :       /* FALLTHRU */
   21605                 :             : 
   21606                 :    10756227 :     case CONST_WIDE_INT:
   21607                 :             :       /* Fall back to (MEM (SYMBOL_REF)), since that's where
   21608                 :             :          it'll probably end up.  Add a penalty for size.  */
   21609                 :    21512454 :       *total = (COSTS_N_INSNS (1)
   21610                 :    21293452 :                 + (!TARGET_64BIT && flag_pic)
   21611                 :    21512454 :                 + (GET_MODE_SIZE (mode) <= 4
   21612                 :    18901933 :                    ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
   21613                 :    10756227 :       return true;
   21614                 :             : 
   21615                 :    21614004 :     case ZERO_EXTEND:
   21616                 :             :       /* The zero extensions is often completely free on x86_64, so make
   21617                 :             :          it as cheap as possible.  */
   21618                 :    21614004 :       if (TARGET_64BIT && mode == DImode
   21619                 :     3732880 :           && GET_MODE (XEXP (x, 0)) == SImode)
   21620                 :     1957834 :         *total = 1;
   21621                 :    19656170 :       else if (TARGET_ZERO_EXTEND_WITH_AND)
   21622                 :           0 :         *total = cost->add;
   21623                 :             :       else
   21624                 :    19656170 :         *total = cost->movzx;
   21625                 :             :       return false;
   21626                 :             : 
   21627                 :     2621933 :     case SIGN_EXTEND:
   21628                 :     2621933 :       *total = cost->movsx;
   21629                 :     2621933 :       return false;
   21630                 :             : 
   21631                 :   624774687 :     case ASHIFT:
   21632                 :   624774687 :       if (SCALAR_INT_MODE_P (mode)
   21633                 :   236716310 :           && GET_MODE_SIZE (mode) < UNITS_PER_WORD
   21634                 :   665964326 :           && CONST_INT_P (XEXP (x, 1)))
   21635                 :             :         {
   21636                 :    41036560 :           HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   21637                 :    41036560 :           if (value == 1)
   21638                 :             :             {
   21639                 :     2326721 :               *total = cost->add;
   21640                 :     2326721 :               return false;
   21641                 :             :             }
   21642                 :    38709839 :           if ((value == 2 || value == 3)
   21643                 :     4297531 :               && cost->lea <= cost->shift_const)
   21644                 :             :             {
   21645                 :     2058396 :               *total = cost->lea;
   21646                 :     2058396 :               return false;
   21647                 :             :             }
   21648                 :             :         }
   21649                 :             :       /* FALLTHRU */
   21650                 :             : 
   21651                 :   756034310 :     case ROTATE:
   21652                 :   756034310 :     case ASHIFTRT:
   21653                 :   756034310 :     case LSHIFTRT:
   21654                 :   756034310 :     case ROTATERT:
   21655                 :   756034310 :       bool skip_op0, skip_op1;
   21656                 :   756034310 :       *total = ix86_shift_rotate_cost (cost, code, mode,
   21657                 :   756034310 :                                        CONSTANT_P (XEXP (x, 1)),
   21658                 :             :                                        CONST_INT_P (XEXP (x, 1))
   21659                 :             :                                          ? INTVAL (XEXP (x, 1)) : -1,
   21660                 :             :                                        GET_CODE (XEXP (x, 1)) == AND,
   21661                 :   756034310 :                                        SUBREG_P (XEXP (x, 1))
   21662                 :   756034310 :                                        && GET_CODE (XEXP (XEXP (x, 1),
   21663                 :             :                                                           0)) == AND,
   21664                 :             :                                        &skip_op0, &skip_op1);
   21665                 :   756034310 :       if (skip_op0 || skip_op1)
   21666                 :             :         {
   21667                 :       19057 :           if (!skip_op0)
   21668                 :           0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   21669                 :       19057 :           if (!skip_op1)
   21670                 :           0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
   21671                 :       19057 :           return true;
   21672                 :             :         }
   21673                 :             :       return false;
   21674                 :             : 
   21675                 :      157415 :     case FMA:
   21676                 :      157415 :       {
   21677                 :      157415 :         rtx sub;
   21678                 :             : 
   21679                 :      157415 :         gcc_assert (FLOAT_MODE_P (mode));
   21680                 :      157415 :         gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
   21681                 :             : 
   21682                 :      314830 :         *total = ix86_vec_cost (mode,
   21683                 :      157415 :                                 GET_MODE_INNER (mode) == SFmode
   21684                 :             :                                 ? cost->fmass : cost->fmasd);
   21685                 :      157415 :         *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
   21686                 :             : 
   21687                 :             :         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
   21688                 :      157415 :         sub = XEXP (x, 0);
   21689                 :      157415 :         if (GET_CODE (sub) == NEG)
   21690                 :       36539 :           sub = XEXP (sub, 0);
   21691                 :      157415 :         *total += rtx_cost (sub, mode, FMA, 0, speed);
   21692                 :             : 
   21693                 :      157415 :         sub = XEXP (x, 2);
   21694                 :      157415 :         if (GET_CODE (sub) == NEG)
   21695                 :       31583 :           sub = XEXP (sub, 0);
   21696                 :      157415 :         *total += rtx_cost (sub, mode, FMA, 2, speed);
   21697                 :      157415 :         return true;
   21698                 :             :       }
   21699                 :             : 
   21700                 :  1724602315 :     case MULT:
   21701                 :  1724602315 :       if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
   21702                 :             :         {
   21703                 :   527917392 :           rtx op0 = XEXP (x, 0);
   21704                 :   527917392 :           rtx op1 = XEXP (x, 1);
   21705                 :   527917392 :           int nbits;
   21706                 :   527917392 :           if (CONST_INT_P (XEXP (x, 1)))
   21707                 :             :             {
   21708                 :   511498832 :               unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   21709                 :  1038212969 :               for (nbits = 0; value != 0; value &= value - 1)
   21710                 :   526714137 :                 nbits++;
   21711                 :             :             }
   21712                 :             :           else
   21713                 :             :             /* This is arbitrary.  */
   21714                 :             :             nbits = 7;
   21715                 :             : 
   21716                 :             :           /* Compute costs correctly for widening multiplication.  */
   21717                 :   527917392 :           if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
   21718                 :   533203289 :               && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
   21719                 :     5285897 :                  == GET_MODE_SIZE (mode))
   21720                 :             :             {
   21721                 :     5285308 :               int is_mulwiden = 0;
   21722                 :     5285308 :               machine_mode inner_mode = GET_MODE (op0);
   21723                 :             : 
   21724                 :     5285308 :               if (GET_CODE (op0) == GET_CODE (op1))
   21725                 :     5202774 :                 is_mulwiden = 1, op1 = XEXP (op1, 0);
   21726                 :       82534 :               else if (CONST_INT_P (op1))
   21727                 :             :                 {
   21728                 :       72385 :                   if (GET_CODE (op0) == SIGN_EXTEND)
   21729                 :       19430 :                     is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
   21730                 :       19430 :                                   == INTVAL (op1);
   21731                 :             :                   else
   21732                 :       52955 :                     is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
   21733                 :             :                 }
   21734                 :             : 
   21735                 :     5275159 :               if (is_mulwiden)
   21736                 :     5275159 :                 op0 = XEXP (op0, 0), mode = GET_MODE (op0);
   21737                 :             :             }
   21738                 :             : 
   21739                 :   527917392 :           int mult_init;
   21740                 :             :           // Double word multiplication requires 3 mults and 2 adds.
   21741                 :  1070839470 :           if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21742                 :             :             {
   21743                 :   318388136 :               mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
   21744                 :   318388136 :                           + 2 * cost->add;
   21745                 :   318388136 :               nbits *= 3;
   21746                 :             :             }
   21747                 :   419058512 :           else mult_init = cost->mult_init[MODE_INDEX (mode)];
   21748                 :             : 
   21749                 :  1055834784 :           *total = (mult_init
   21750                 :   527917392 :                     + nbits * cost->mult_bit
   21751                 :   527917392 :                     + rtx_cost (op0, mode, outer_code, opno, speed)
   21752                 :   527917392 :                     + rtx_cost (op1, mode, outer_code, opno, speed));
   21753                 :             : 
   21754                 :   527917392 :           return true;
   21755                 :             :         }
   21756                 :  1196684923 :       *total = ix86_multiplication_cost (cost, mode);
   21757                 :  1196684923 :       return false;
   21758                 :             : 
   21759                 :    71016649 :     case DIV:
   21760                 :    71016649 :     case UDIV:
   21761                 :    71016649 :     case MOD:
   21762                 :    71016649 :     case UMOD:
   21763                 :    71016649 :       *total = ix86_division_cost (cost, mode);
   21764                 :    71016649 :       return false;
   21765                 :             : 
   21766                 :   714118129 :     case PLUS:
   21767                 :   714118129 :       if (GET_MODE_CLASS (mode) == MODE_INT
   21768                 :  1012722097 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   21769                 :             :         {
   21770                 :   176651212 :           if (GET_CODE (XEXP (x, 0)) == PLUS
   21771                 :     2299168 :               && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   21772                 :      626597 :               && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
   21773                 :      626592 :               && CONSTANT_P (XEXP (x, 1)))
   21774                 :             :             {
   21775                 :      626540 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
   21776                 :      626540 :               if (val == 2 || val == 4 || val == 8)
   21777                 :             :                 {
   21778                 :      626484 :                   *total = cost->lea;
   21779                 :      626484 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   21780                 :             :                                       outer_code, opno, speed);
   21781                 :      626484 :                   *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
   21782                 :             :                                       outer_code, opno, speed);
   21783                 :      626484 :                   *total += rtx_cost (XEXP (x, 1), mode,
   21784                 :             :                                       outer_code, opno, speed);
   21785                 :      626484 :                   return true;
   21786                 :             :                 }
   21787                 :             :             }
   21788                 :   176024672 :           else if (GET_CODE (XEXP (x, 0)) == MULT
   21789                 :    49891893 :                    && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   21790                 :             :             {
   21791                 :    49844187 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
   21792                 :    49844187 :               if (val == 2 || val == 4 || val == 8)
   21793                 :             :                 {
   21794                 :     7370856 :                   *total = cost->lea;
   21795                 :     7370856 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21796                 :             :                                       outer_code, opno, speed);
   21797                 :     7370856 :                   *total += rtx_cost (XEXP (x, 1), mode,
   21798                 :             :                                       outer_code, opno, speed);
   21799                 :     7370856 :                   return true;
   21800                 :             :                 }
   21801                 :             :             }
   21802                 :   126180485 :           else if (GET_CODE (XEXP (x, 0)) == PLUS)
   21803                 :             :             {
   21804                 :     1672628 :               rtx op = XEXP (XEXP (x, 0), 0);
   21805                 :             : 
   21806                 :             :               /* Add with carry, ignore the cost of adding a carry flag.  */
   21807                 :     1672628 :               if (ix86_carry_flag_operator (op, mode)
   21808                 :     1672628 :                   || ix86_carry_flag_unset_operator (op, mode))
   21809                 :       82802 :                 *total = cost->add;
   21810                 :             :               else
   21811                 :             :                 {
   21812                 :     1589826 :                   *total = cost->lea;
   21813                 :     1589826 :                   *total += rtx_cost (op, mode,
   21814                 :             :                                       outer_code, opno, speed);
   21815                 :             :                 }
   21816                 :             : 
   21817                 :     1672628 :               *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   21818                 :             :                                   outer_code, opno, speed);
   21819                 :     1672628 :               *total += rtx_cost (XEXP (x, 1), mode,
   21820                 :             :                                   outer_code, opno, speed);
   21821                 :     1672628 :               return true;
   21822                 :             :             }
   21823                 :             :         }
   21824                 :             :       /* FALLTHRU */
   21825                 :             : 
   21826                 :  1840798615 :     case MINUS:
   21827                 :             :       /* Subtract with borrow, ignore the cost of subtracting a carry flag.  */
   21828                 :  1840798615 :       if (GET_MODE_CLASS (mode) == MODE_INT
   21829                 :   552439042 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   21830                 :   266282453 :           && GET_CODE (XEXP (x, 0)) == MINUS
   21831                 :  1840835551 :           && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
   21832                 :        9833 :               || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
   21833                 :             :         {
   21834                 :       27103 :           *total = cost->add;
   21835                 :       27103 :           *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21836                 :             :                               outer_code, opno, speed);
   21837                 :       27103 :           *total += rtx_cost (XEXP (x, 1), mode,
   21838                 :             :                               outer_code, opno, speed);
   21839                 :       27103 :           return true;
   21840                 :             :         }
   21841                 :             : 
   21842                 :  1840771512 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   21843                 :     2261161 :         *total = cost->addss;
   21844                 :  1838510351 :       else if (X87_FLOAT_MODE_P (mode))
   21845                 :      220233 :         *total = cost->fadd;
   21846                 :  1838290118 :       else if (FLOAT_MODE_P (mode))
   21847                 :      312663 :         *total = ix86_vec_cost (mode, cost->addss);
   21848                 :  1837977455 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21849                 :  1196280130 :         *total = ix86_vec_cost (mode, cost->sse_op);
   21850                 :  1334319640 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21851                 :   317487295 :         *total = cost->add * 2;
   21852                 :             :       else
   21853                 :   324210030 :         *total = cost->add;
   21854                 :             :       return false;
   21855                 :             : 
   21856                 :     3530451 :     case IOR:
   21857                 :     3530451 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   21858                 :     3455462 :           || SSE_FLOAT_MODE_P (mode))
   21859                 :             :         {
   21860                 :             :           /* (ior (not ...) ...) can be a single insn in AVX512.  */
   21861                 :          29 :           if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
   21862                 :       84404 :               && ((TARGET_EVEX512
   21863                 :          29 :                    && GET_MODE_SIZE (mode) == 64)
   21864                 :          14 :                   || (TARGET_AVX512VL
   21865                 :          14 :                       && (GET_MODE_SIZE (mode) == 32
   21866                 :           0 :                           || GET_MODE_SIZE (mode) == 16))))
   21867                 :             :             {
   21868                 :          58 :               rtx right = GET_CODE (XEXP (x, 1)) != NOT
   21869                 :          29 :                           ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
   21870                 :             : 
   21871                 :          29 :               *total = ix86_vec_cost (mode, cost->sse_op)
   21872                 :          29 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21873                 :             :                                    outer_code, opno, speed)
   21874                 :          29 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   21875                 :          29 :               return true;
   21876                 :             :             }
   21877                 :       84346 :           *total = ix86_vec_cost (mode, cost->sse_op);
   21878                 :       84346 :         }
   21879                 :     7162509 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21880                 :     1687610 :         *total = cost->add * 2;
   21881                 :             :       else
   21882                 :     1758466 :         *total = cost->add;
   21883                 :             :       return false;
   21884                 :             : 
   21885                 :      450845 :     case XOR:
   21886                 :      450845 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   21887                 :      392563 :           || SSE_FLOAT_MODE_P (mode))
   21888                 :       58282 :         *total = ix86_vec_cost (mode, cost->sse_op);
   21889                 :      843708 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21890                 :       16164 :         *total = cost->add * 2;
   21891                 :             :       else
   21892                 :      376399 :         *total = cost->add;
   21893                 :             :       return false;
   21894                 :             : 
   21895                 :     6905586 :     case AND:
   21896                 :     6905586 :       if (address_no_seg_operand (x, mode))
   21897                 :             :         {
   21898                 :       10563 :           *total = cost->lea;
   21899                 :       10563 :           return true;
   21900                 :             :         }
   21901                 :     6895023 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   21902                 :     6627107 :                || SSE_FLOAT_MODE_P (mode))
   21903                 :             :         {
   21904                 :             :           /* pandn is a single instruction.  */
   21905                 :      301304 :           if (GET_CODE (XEXP (x, 0)) == NOT)
   21906                 :             :             {
   21907                 :       37732 :               rtx right = XEXP (x, 1);
   21908                 :             : 
   21909                 :             :               /* (and (not ...) (not ...)) can be a single insn in AVX512.  */
   21910                 :          72 :               if (GET_CODE (right) == NOT && TARGET_AVX512F
   21911                 :       37732 :                   && ((TARGET_EVEX512
   21912                 :           0 :                        && GET_MODE_SIZE (mode) == 64)
   21913                 :           0 :                       || (TARGET_AVX512VL
   21914                 :           0 :                           && (GET_MODE_SIZE (mode) == 32
   21915                 :           0 :                               || GET_MODE_SIZE (mode) == 16))))
   21916                 :           0 :                 right = XEXP (right, 0);
   21917                 :             : 
   21918                 :       37732 :               *total = ix86_vec_cost (mode, cost->sse_op)
   21919                 :       37732 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21920                 :             :                                    outer_code, opno, speed)
   21921                 :       37732 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   21922                 :       37732 :               return true;
   21923                 :             :             }
   21924                 :      263572 :           else if (GET_CODE (XEXP (x, 1)) == NOT)
   21925                 :             :             {
   21926                 :         153 :               *total = ix86_vec_cost (mode, cost->sse_op)
   21927                 :         153 :                        + rtx_cost (XEXP (x, 0), mode,
   21928                 :             :                                    outer_code, opno, speed)
   21929                 :         153 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   21930                 :             :                                    outer_code, opno, speed);
   21931                 :         153 :               return true;
   21932                 :             :             }
   21933                 :      263419 :           *total = ix86_vec_cost (mode, cost->sse_op);
   21934                 :      263419 :         }
   21935                 :    13822086 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21936                 :             :         {
   21937                 :     1661527 :           if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   21938                 :             :             {
   21939                 :        1700 :               *total = cost->add * 2
   21940                 :         850 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21941                 :             :                                    outer_code, opno, speed)
   21942                 :         850 :                        + rtx_cost (XEXP (x, 1), mode,
   21943                 :             :                                    outer_code, opno, speed);
   21944                 :         850 :               return true;
   21945                 :             :             }
   21946                 :     1660677 :           else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
   21947                 :             :             {
   21948                 :           0 :               *total = cost->add * 2
   21949                 :           0 :                        + rtx_cost (XEXP (x, 0), mode,
   21950                 :             :                                    outer_code, opno, speed)
   21951                 :           0 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   21952                 :             :                                    outer_code, opno, speed);
   21953                 :           0 :               return true;
   21954                 :             :             }
   21955                 :     1660677 :           *total = cost->add * 2;
   21956                 :             :         }
   21957                 :     4932192 :       else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   21958                 :             :         {
   21959                 :         804 :           *total = cost->add
   21960                 :         402 :                    + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21961                 :             :                                outer_code, opno, speed)
   21962                 :         402 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   21963                 :         402 :           return true;
   21964                 :             :         }
   21965                 :     4931790 :       else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
   21966                 :             :         {
   21967                 :         112 :           *total = cost->add
   21968                 :          56 :                    + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   21969                 :          56 :                    + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   21970                 :             :                                outer_code, opno, speed);
   21971                 :          56 :           return true;
   21972                 :             :         }
   21973                 :             :       else
   21974                 :     4931734 :         *total = cost->add;
   21975                 :             :       return false;
   21976                 :             : 
   21977                 :      465314 :     case NOT:
   21978                 :      465314 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   21979                 :             :         {
   21980                 :             :           /* (not (xor ...)) can be a single insn in AVX512.  */
   21981                 :           4 :           if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
   21982                 :        5058 :               && ((TARGET_EVEX512
   21983                 :           4 :                    && GET_MODE_SIZE (mode) == 64)
   21984                 :           0 :                   || (TARGET_AVX512VL
   21985                 :           0 :                       && (GET_MODE_SIZE (mode) == 32
   21986                 :           0 :                           || GET_MODE_SIZE (mode) == 16))))
   21987                 :             :             {
   21988                 :           4 :               *total = ix86_vec_cost (mode, cost->sse_op)
   21989                 :           4 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   21990                 :             :                                    outer_code, opno, speed)
   21991                 :           4 :                        + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   21992                 :             :                                    outer_code, opno, speed);
   21993                 :           4 :               return true;
   21994                 :             :             }
   21995                 :             : 
   21996                 :             :           // vnot is pxor -1.
   21997                 :        5050 :           *total = ix86_vec_cost (mode, cost->sse_op) + 1;
   21998                 :             :         }
   21999                 :     1067377 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22000                 :       66442 :         *total = cost->add * 2;
   22001                 :             :       else
   22002                 :      393818 :         *total = cost->add;
   22003                 :             :       return false;
   22004                 :             : 
   22005                 :    17838390 :     case NEG:
   22006                 :    17838390 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   22007                 :       48143 :         *total = cost->sse_op;
   22008                 :    17790247 :       else if (X87_FLOAT_MODE_P (mode))
   22009                 :       15912 :         *total = cost->fchs;
   22010                 :    17774335 :       else if (FLOAT_MODE_P (mode))
   22011                 :       29513 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22012                 :    17744822 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22013                 :    13257534 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22014                 :     9119074 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22015                 :     1690559 :         *total = cost->add * 3;
   22016                 :             :       else
   22017                 :     2796729 :         *total = cost->add;
   22018                 :             :       return false;
   22019                 :             : 
   22020                 :    47305731 :     case COMPARE:
   22021                 :    47305731 :       rtx op0, op1;
   22022                 :    47305731 :       op0 = XEXP (x, 0);
   22023                 :    47305731 :       op1 = XEXP (x, 1);
   22024                 :    47305731 :       if (GET_CODE (op0) == ZERO_EXTRACT
   22025                 :      122382 :           && XEXP (op0, 1) == const1_rtx
   22026                 :      105899 :           && CONST_INT_P (XEXP (op0, 2))
   22027                 :      105799 :           && op1 == const0_rtx)
   22028                 :             :         {
   22029                 :             :           /* This kind of construct is implemented using test[bwl].
   22030                 :             :              Treat it as if we had an AND.  */
   22031                 :      105799 :           mode = GET_MODE (XEXP (op0, 0));
   22032                 :      211598 :           *total = (cost->add
   22033                 :      105799 :                     + rtx_cost (XEXP (op0, 0), mode, outer_code,
   22034                 :             :                                 opno, speed)
   22035                 :      105799 :                     + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
   22036                 :      105799 :           return true;
   22037                 :             :         }
   22038                 :             : 
   22039                 :    47199932 :       if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
   22040                 :             :         {
   22041                 :             :           /* This is an overflow detection, count it as a normal compare.  */
   22042                 :      137578 :           *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
   22043                 :      137578 :           return true;
   22044                 :             :         }
   22045                 :             : 
   22046                 :    47062354 :       rtx geu;
   22047                 :             :       /* Match x
   22048                 :             :          (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   22049                 :             :                       (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))  */
   22050                 :    47062354 :       if (mode == CCCmode
   22051                 :      350092 :           && GET_CODE (op0) == NEG
   22052                 :       23012 :           && GET_CODE (geu = XEXP (op0, 0)) == GEU
   22053                 :       22337 :           && REG_P (XEXP (geu, 0))
   22054                 :       22337 :           && (GET_MODE (XEXP (geu, 0)) == CCCmode
   22055                 :        2016 :               || GET_MODE (XEXP (geu, 0)) == CCmode)
   22056                 :       22337 :           && REGNO (XEXP (geu, 0)) == FLAGS_REG
   22057                 :       22337 :           && XEXP (geu, 1) == const0_rtx
   22058                 :       22337 :           && GET_CODE (op1) == LTU
   22059                 :       22337 :           && REG_P (XEXP (op1, 0))
   22060                 :       22337 :           && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   22061                 :       22337 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   22062                 :    47084691 :           && XEXP (op1, 1) == const0_rtx)
   22063                 :             :         {
   22064                 :             :           /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop.  */
   22065                 :       22337 :           *total = 0;
   22066                 :       22337 :           return true;
   22067                 :             :         }
   22068                 :             :       /* Match x
   22069                 :             :          (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   22070                 :             :                       (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))  */
   22071                 :    47040017 :       if (mode == CCCmode
   22072                 :      327755 :           && GET_CODE (op0) == NEG
   22073                 :         675 :           && GET_CODE (XEXP (op0, 0)) == LTU
   22074                 :         395 :           && REG_P (XEXP (XEXP (op0, 0), 0))
   22075                 :         395 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   22076                 :           3 :           && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
   22077                 :           3 :           && XEXP (XEXP (op0, 0), 1) == const0_rtx
   22078                 :           3 :           && GET_CODE (op1) == GEU
   22079                 :           3 :           && REG_P (XEXP (op1, 0))
   22080                 :           3 :           && GET_MODE (XEXP (op1, 0)) == CCCmode
   22081                 :           3 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   22082                 :    47040020 :           && XEXP (op1, 1) == const0_rtx)
   22083                 :             :         {
   22084                 :             :           /* This is *x86_cmc.  */
   22085                 :           3 :           if (!speed)
   22086                 :           0 :             *total = COSTS_N_BYTES (1);
   22087                 :           3 :           else if (TARGET_SLOW_STC)
   22088                 :           0 :             *total = COSTS_N_INSNS (2);
   22089                 :             :           else 
   22090                 :           3 :             *total = COSTS_N_INSNS (1);
   22091                 :           3 :           return true;
   22092                 :             :         }
   22093                 :             : 
   22094                 :    47040014 :       if (SCALAR_INT_MODE_P (GET_MODE (op0))
   22095                 :    98004642 :           && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
   22096                 :             :         {
   22097                 :      691521 :           if (op1 == const0_rtx)
   22098                 :      220556 :             *total = cost->add
   22099                 :      110278 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
   22100                 :             :           else
   22101                 :     1162486 :             *total = 3*cost->add
   22102                 :      581243 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
   22103                 :      581243 :                      + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
   22104                 :      691521 :           return true;
   22105                 :             :         }
   22106                 :             : 
   22107                 :             :       /* The embedded comparison operand is completely free.  */
   22108                 :    46348493 :       if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
   22109                 :      303786 :         *total = 0;
   22110                 :             : 
   22111                 :             :       return false;
   22112                 :             : 
   22113                 :     1280605 :     case FLOAT_EXTEND:
   22114                 :     1280605 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   22115                 :      644299 :         *total = 0;
   22116                 :             :       else
   22117                 :      636306 :         *total = ix86_vec_cost (mode, cost->addss);
   22118                 :             :       return false;
   22119                 :             : 
   22120                 :       79222 :     case FLOAT_TRUNCATE:
   22121                 :       79222 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   22122                 :       54114 :         *total = cost->fadd;
   22123                 :             :       else
   22124                 :       25108 :         *total = ix86_vec_cost (mode, cost->addss);
   22125                 :             :       return false;
   22126                 :             : 
   22127                 :      302809 :     case ABS:
   22128                 :             :       /* SSE requires memory load for the constant operand. It may make
   22129                 :             :          sense to account for this.  Of course the constant operand may or
   22130                 :             :          may not be reused. */
   22131                 :      302809 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   22132                 :      213439 :         *total = cost->sse_op;
   22133                 :       89370 :       else if (X87_FLOAT_MODE_P (mode))
   22134                 :       32336 :         *total = cost->fabs;
   22135                 :       57034 :       else if (FLOAT_MODE_P (mode))
   22136                 :       23493 :         *total = ix86_vec_cost (mode, cost->sse_op);
   22137                 :             :       return false;
   22138                 :             : 
   22139                 :       25701 :     case SQRT:
   22140                 :       25701 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   22141                 :       17662 :         *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
   22142                 :        8039 :       else if (X87_FLOAT_MODE_P (mode))
   22143                 :        4239 :         *total = cost->fsqrt;
   22144                 :        3800 :       else if (FLOAT_MODE_P (mode))
   22145                 :        3800 :         *total = ix86_vec_cost (mode,
   22146                 :             :                                 mode == SFmode ? cost->sqrtss : cost->sqrtsd);
   22147                 :             :       return false;
   22148                 :             : 
   22149                 :     3574439 :     case UNSPEC:
   22150                 :     3574439 :       if (XINT (x, 1) == UNSPEC_TP)
   22151                 :      114540 :         *total = 0;
   22152                 :     3459899 :       else if (XINT (x, 1) == UNSPEC_VTERNLOG)
   22153                 :             :         {
   22154                 :        2516 :           *total = cost->sse_op;
   22155                 :        2516 :           return true;
   22156                 :             :         }
   22157                 :     3457383 :       else if (XINT (x, 1) == UNSPEC_PTEST)
   22158                 :             :         {
   22159                 :       43416 :           *total = cost->sse_op;
   22160                 :       43416 :           rtx test_op0 = XVECEXP (x, 0, 0);
   22161                 :       43416 :           if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
   22162                 :             :             return false;
   22163                 :       42763 :           if (GET_CODE (test_op0) == AND)
   22164                 :             :             {
   22165                 :          25 :               rtx and_op0 = XEXP (test_op0, 0);
   22166                 :          25 :               if (GET_CODE (and_op0) == NOT)
   22167                 :           0 :                 and_op0 = XEXP (and_op0, 0);
   22168                 :          25 :               *total += rtx_cost (and_op0, GET_MODE (and_op0),
   22169                 :             :                                   AND, 0, speed)
   22170                 :          25 :                         + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
   22171                 :             :                                     AND, 1, speed);
   22172                 :             :             }
   22173                 :             :           else
   22174                 :       42738 :             *total = rtx_cost (test_op0, GET_MODE (test_op0),
   22175                 :             :                                UNSPEC, 0, speed);
   22176                 :       42763 :           return true;
   22177                 :             :         }
   22178                 :             :       return false;
   22179                 :             : 
   22180                 :     5345965 :     case VEC_SELECT:
   22181                 :     5345965 :     case VEC_CONCAT:
   22182                 :     5345965 :     case VEC_DUPLICATE:
   22183                 :             :       /* ??? Assume all of these vector manipulation patterns are
   22184                 :             :          recognizable.  In which case they all pretty much have the
   22185                 :             :          same cost.  */
   22186                 :     5345965 :      *total = cost->sse_op;
   22187                 :     5345965 :      return true;
   22188                 :      579002 :     case VEC_MERGE:
   22189                 :      579002 :       mask = XEXP (x, 2);
   22190                 :             :       /* This is masked instruction, assume the same cost,
   22191                 :             :          as nonmasked variant.  */
   22192                 :      579002 :       if (TARGET_AVX512F && register_operand (mask, GET_MODE (mask)))
   22193                 :      333609 :         *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed);
   22194                 :             :       else
   22195                 :      245393 :         *total = cost->sse_op;
   22196                 :             :       return true;
   22197                 :             : 
   22198                 :    92891087 :     case MEM:
   22199                 :             :       /* An insn that accesses memory is slightly more expensive
   22200                 :             :          than one that does not.  */
   22201                 :    92891087 :       if (speed)
   22202                 :    83612249 :         *total += 1;
   22203                 :             :       return false;
   22204                 :             : 
   22205                 :       50810 :     case ZERO_EXTRACT:
   22206                 :       50810 :       if (XEXP (x, 1) == const1_rtx
   22207                 :        9689 :           && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
   22208                 :        9689 :           && GET_MODE (XEXP (x, 2)) == SImode
   22209                 :           0 :           && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
   22210                 :             :         {
   22211                 :             :           /* Ignore cost of zero extension and masking of last argument.  */
   22212                 :           0 :           *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22213                 :           0 :           *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22214                 :           0 :           *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
   22215                 :           0 :           return true;
   22216                 :             :         }
   22217                 :             :       return false;
   22218                 :             : 
   22219                 :    23689518 :     case IF_THEN_ELSE:
   22220                 :    23689518 :       if (TARGET_XOP
   22221                 :       17420 :           && VECTOR_MODE_P (mode)
   22222                 :    23695639 :           && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
   22223                 :             :         {
   22224                 :             :           /* vpcmov.  */
   22225                 :        5053 :           *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
   22226                 :        5053 :           if (!REG_P (XEXP (x, 0)))
   22227                 :        4819 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22228                 :        5053 :           if (!REG_P (XEXP (x, 1)))
   22229                 :        4782 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22230                 :        5053 :           if (!REG_P (XEXP (x, 2)))
   22231                 :        4806 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   22232                 :        5053 :           return true;
   22233                 :             :         }
   22234                 :           0 :       else if (TARGET_CMOVE
   22235                 :    23684465 :                && SCALAR_INT_MODE_P (mode)
   22236                 :    25290670 :                && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   22237                 :             :         {
   22238                 :             :           /* cmov.  */
   22239                 :     1486561 :           *total = COSTS_N_INSNS (1);
   22240                 :     1486561 :           if (!REG_P (XEXP (x, 0)))
   22241                 :     1486561 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22242                 :     1486561 :           if (!REG_P (XEXP (x, 1)))
   22243                 :       79262 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   22244                 :     1486561 :           if (!REG_P (XEXP (x, 2)))
   22245                 :      512912 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   22246                 :     1486561 :           return true;
   22247                 :             :         }
   22248                 :             :       return false;
   22249                 :             : 
   22250                 :             :     default:
   22251                 :             :       return false;
   22252                 :             :     }
   22253                 :             : }
   22254                 :             : 
   22255                 :             : #if TARGET_MACHO
   22256                 :             : 
   22257                 :             : static int current_machopic_label_num;
   22258                 :             : 
   22259                 :             : /* Given a symbol name and its associated stub, write out the
   22260                 :             :    definition of the stub.  */
   22261                 :             : 
   22262                 :             : void
   22263                 :             : machopic_output_stub (FILE *file, const char *symb, const char *stub)
   22264                 :             : {
   22265                 :             :   unsigned int length;
   22266                 :             :   char *binder_name, *symbol_name, lazy_ptr_name[32];
   22267                 :             :   int label = ++current_machopic_label_num;
   22268                 :             : 
   22269                 :             :   /* For 64-bit we shouldn't get here.  */
   22270                 :             :   gcc_assert (!TARGET_64BIT);
   22271                 :             : 
   22272                 :             :   /* Lose our funky encoding stuff so it doesn't contaminate the stub.  */
   22273                 :             :   symb = targetm.strip_name_encoding (symb);
   22274                 :             : 
   22275                 :             :   length = strlen (stub);
   22276                 :             :   binder_name = XALLOCAVEC (char, length + 32);
   22277                 :             :   GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
   22278                 :             : 
   22279                 :             :   length = strlen (symb);
   22280                 :             :   symbol_name = XALLOCAVEC (char, length + 32);
   22281                 :             :   GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
   22282                 :             : 
   22283                 :             :   sprintf (lazy_ptr_name, "L%d$lz", label);
   22284                 :             : 
   22285                 :             :   if (MACHOPIC_ATT_STUB)
   22286                 :             :     switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
   22287                 :             :   else if (MACHOPIC_PURE)
   22288                 :             :     switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
   22289                 :             :   else
   22290                 :             :     switch_to_section (darwin_sections[machopic_symbol_stub_section]);
   22291                 :             : 
   22292                 :             :   fprintf (file, "%s:\n", stub);
   22293                 :             :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   22294                 :             : 
   22295                 :             :   if (MACHOPIC_ATT_STUB)
   22296                 :             :     {
   22297                 :             :       fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
   22298                 :             :     }
   22299                 :             :   else if (MACHOPIC_PURE)
   22300                 :             :     {
   22301                 :             :       /* PIC stub.  */
   22302                 :             :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   22303                 :             :       rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
   22304                 :             :       output_set_got (tmp, NULL_RTX);   /* "CALL ___<cpu>.get_pc_thunk.cx".  */
   22305                 :             :       fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
   22306                 :             :                label, lazy_ptr_name, label);
   22307                 :             :       fprintf (file, "\tjmp\t*%%ecx\n");
   22308                 :             :     }
   22309                 :             :   else
   22310                 :             :     fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
   22311                 :             : 
   22312                 :             :   /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
   22313                 :             :      it needs no stub-binding-helper.  */
   22314                 :             :   if (MACHOPIC_ATT_STUB)
   22315                 :             :     return;
   22316                 :             : 
   22317                 :             :   fprintf (file, "%s:\n", binder_name);
   22318                 :             : 
   22319                 :             :   if (MACHOPIC_PURE)
   22320                 :             :     {
   22321                 :             :       fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
   22322                 :             :       fprintf (file, "\tpushl\t%%ecx\n");
   22323                 :             :     }
   22324                 :             :   else
   22325                 :             :     fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
   22326                 :             : 
   22327                 :             :   fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
   22328                 :             : 
   22329                 :             :   /* N.B. Keep the correspondence of these
   22330                 :             :      'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
   22331                 :             :      old-pic/new-pic/non-pic stubs; altering this will break
   22332                 :             :      compatibility with existing dylibs.  */
   22333                 :             :   if (MACHOPIC_PURE)
   22334                 :             :     {
   22335                 :             :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   22336                 :             :       switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
   22337                 :             :     }
   22338                 :             :   else
   22339                 :             :     /* 16-byte -mdynamic-no-pic stub.  */
   22340                 :             :     switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
   22341                 :             : 
   22342                 :             :   fprintf (file, "%s:\n", lazy_ptr_name);
   22343                 :             :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   22344                 :             :   fprintf (file, ASM_LONG "%s\n", binder_name);
   22345                 :             : }
   22346                 :             : #endif /* TARGET_MACHO */
   22347                 :             : 
   22348                 :             : /* Order the registers for register allocator.  */
   22349                 :             : 
   22350                 :             : void
   22351                 :      208054 : x86_order_regs_for_local_alloc (void)
   22352                 :             : {
   22353                 :      208054 :    int pos = 0;
   22354                 :      208054 :    int i;
   22355                 :             : 
   22356                 :             :    /* First allocate the local general purpose registers.  */
   22357                 :    19349022 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22358                 :    25798696 :      if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i))
   22359                 :     5418561 :         reg_alloc_order [pos++] = i;
   22360                 :             : 
   22361                 :             :    /* Global general purpose registers.  */
   22362                 :    19349022 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22363                 :    22218841 :      if (GENERAL_REGNO_P (i) && !call_used_or_fixed_reg_p (i))
   22364                 :     1239167 :         reg_alloc_order [pos++] = i;
   22365                 :             : 
   22366                 :             :    /* x87 registers come first in case we are doing FP math
   22367                 :             :       using them.  */
   22368                 :      208054 :    if (!TARGET_SSE_MATH)
   22369                 :       55530 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   22370                 :       49360 :        reg_alloc_order [pos++] = i;
   22371                 :             : 
   22372                 :             :    /* SSE registers.  */
   22373                 :     1872486 :    for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
   22374                 :     1664432 :      reg_alloc_order [pos++] = i;
   22375                 :     1872486 :    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
   22376                 :     1664432 :      reg_alloc_order [pos++] = i;
   22377                 :             : 
   22378                 :             :    /* Extended REX SSE registers.  */
   22379                 :     3536918 :    for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
   22380                 :     3328864 :      reg_alloc_order [pos++] = i;
   22381                 :             : 
   22382                 :             :    /* Mask register.  */
   22383                 :     1872486 :    for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
   22384                 :     1664432 :      reg_alloc_order [pos++] = i;
   22385                 :             : 
   22386                 :             :    /* x87 registers.  */
   22387                 :      208054 :    if (TARGET_SSE_MATH)
   22388                 :     1816956 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   22389                 :     1615072 :        reg_alloc_order [pos++] = i;
   22390                 :             : 
   22391                 :     1872486 :    for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
   22392                 :     1664432 :      reg_alloc_order [pos++] = i;
   22393                 :             : 
   22394                 :             :    /* Initialize the rest of array as we do not allocate some registers
   22395                 :             :       at all.  */
   22396                 :     1040270 :    while (pos < FIRST_PSEUDO_REGISTER)
   22397                 :      832216 :      reg_alloc_order [pos++] = 0;
   22398                 :      208054 : }
   22399                 :             : 
   22400                 :             : static bool
   22401                 :   196867558 : ix86_ms_bitfield_layout_p (const_tree record_type)
   22402                 :             : {
   22403                 :   196867558 :   return ((TARGET_MS_BITFIELD_LAYOUT
   22404                 :         215 :            && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
   22405                 :   196867558 :           || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
   22406                 :             : }
   22407                 :             : 
   22408                 :             : /* Returns an expression indicating where the this parameter is
   22409                 :             :    located on entry to the FUNCTION.  */
   22410                 :             : 
   22411                 :             : static rtx
   22412                 :        2268 : x86_this_parameter (tree function)
   22413                 :             : {
   22414                 :        2268 :   tree type = TREE_TYPE (function);
   22415                 :        2268 :   bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
   22416                 :        2268 :   int nregs;
   22417                 :             : 
   22418                 :        2268 :   if (TARGET_64BIT)
   22419                 :             :     {
   22420                 :        2266 :       const int *parm_regs;
   22421                 :             : 
   22422                 :        2266 :       if (ix86_function_type_abi (type) == MS_ABI)
   22423                 :             :         parm_regs = x86_64_ms_abi_int_parameter_registers;
   22424                 :             :       else
   22425                 :        2266 :         parm_regs = x86_64_int_parameter_registers;
   22426                 :        2266 :       return gen_rtx_REG (Pmode, parm_regs[aggr]);
   22427                 :             :     }
   22428                 :             : 
   22429                 :           2 :   nregs = ix86_function_regparm (type, function);
   22430                 :             : 
   22431                 :           2 :   if (nregs > 0 && !stdarg_p (type))
   22432                 :             :     {
   22433                 :           0 :       int regno;
   22434                 :           0 :       unsigned int ccvt = ix86_get_callcvt (type);
   22435                 :             : 
   22436                 :           0 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   22437                 :           0 :         regno = aggr ? DX_REG : CX_REG;
   22438                 :           0 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   22439                 :             :         {
   22440                 :           0 :           regno = CX_REG;
   22441                 :           0 :           if (aggr)
   22442                 :           0 :             return gen_rtx_MEM (SImode,
   22443                 :           0 :                                 plus_constant (Pmode, stack_pointer_rtx, 4));
   22444                 :             :         }
   22445                 :             :       else
   22446                 :             :         {
   22447                 :           0 :           regno = AX_REG;
   22448                 :           0 :           if (aggr)
   22449                 :             :             {
   22450                 :           0 :               regno = DX_REG;
   22451                 :           0 :               if (nregs == 1)
   22452                 :           0 :                 return gen_rtx_MEM (SImode,
   22453                 :           0 :                                     plus_constant (Pmode,
   22454                 :           0 :                                                    stack_pointer_rtx, 4));
   22455                 :             :             }
   22456                 :             :         }
   22457                 :           0 :       return gen_rtx_REG (SImode, regno);
   22458                 :             :     }
   22459                 :             : 
   22460                 :           2 :   return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
   22461                 :           4 :                                              aggr ? 8 : 4));
   22462                 :             : }
   22463                 :             : 
   22464                 :             : /* Determine whether x86_output_mi_thunk can succeed.  */
   22465                 :             : 
   22466                 :             : static bool
   22467                 :        6067 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   22468                 :             :                          const_tree function)
   22469                 :             : {
   22470                 :             :   /* 64-bit can handle anything.  */
   22471                 :        6067 :   if (TARGET_64BIT)
   22472                 :             :     return true;
   22473                 :             : 
   22474                 :             :   /* For 32-bit, everything's fine if we have one free register.  */
   22475                 :          76 :   if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
   22476                 :             :     return true;
   22477                 :             : 
   22478                 :             :   /* Need a free register for vcall_offset.  */
   22479                 :           0 :   if (vcall_offset)
   22480                 :             :     return false;
   22481                 :             : 
   22482                 :             :   /* Need a free register for GOT references.  */
   22483                 :           0 :   if (flag_pic && !targetm.binds_local_p (function))
   22484                 :             :     return false;
   22485                 :             : 
   22486                 :             :   /* Otherwise ok.  */
   22487                 :             :   return true;
   22488                 :             : }
   22489                 :             : 
   22490                 :             : /* Output the assembler code for a thunk function.  THUNK_DECL is the
   22491                 :             :    declaration for the thunk function itself, FUNCTION is the decl for
   22492                 :             :    the target function.  DELTA is an immediate constant offset to be
   22493                 :             :    added to THIS.  If VCALL_OFFSET is nonzero, the word at
   22494                 :             :    *(*this + vcall_offset) should be added to THIS.  */
   22495                 :             : 
   22496                 :             : static void
   22497                 :        2268 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
   22498                 :             :                      HOST_WIDE_INT vcall_offset, tree function)
   22499                 :             : {
   22500                 :        2268 :   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   22501                 :        2268 :   rtx this_param = x86_this_parameter (function);
   22502                 :        2268 :   rtx this_reg, tmp, fnaddr;
   22503                 :        2268 :   unsigned int tmp_regno;
   22504                 :        2268 :   rtx_insn *insn;
   22505                 :        2268 :   int saved_flag_force_indirect_call = flag_force_indirect_call;
   22506                 :             : 
   22507                 :        2268 :   if (TARGET_64BIT)
   22508                 :             :     tmp_regno = R10_REG;
   22509                 :             :   else
   22510                 :             :     {
   22511                 :           2 :       unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
   22512                 :           2 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   22513                 :             :         tmp_regno = AX_REG;
   22514                 :           2 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   22515                 :             :         tmp_regno = DX_REG;
   22516                 :             :       else
   22517                 :           2 :         tmp_regno = CX_REG;
   22518                 :             : 
   22519                 :           2 :       if (flag_pic)
   22520                 :           2 :   flag_force_indirect_call = 0;
   22521                 :             :     }
   22522                 :             : 
   22523                 :        2268 :   emit_note (NOTE_INSN_PROLOGUE_END);
   22524                 :             : 
   22525                 :             :   /* CET is enabled, insert EB instruction.  */
   22526                 :        2268 :   if ((flag_cf_protection & CF_BRANCH))
   22527                 :          20 :     emit_insn (gen_nop_endbr ());
   22528                 :             : 
   22529                 :             :   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
   22530                 :             :      pull it in now and let DELTA benefit.  */
   22531                 :        2268 :   if (REG_P (this_param))
   22532                 :             :     this_reg = this_param;
   22533                 :           2 :   else if (vcall_offset)
   22534                 :             :     {
   22535                 :             :       /* Put the this parameter into %eax.  */
   22536                 :           1 :       this_reg = gen_rtx_REG (Pmode, AX_REG);
   22537                 :           1 :       emit_move_insn (this_reg, this_param);
   22538                 :             :     }
   22539                 :             :   else
   22540                 :             :     this_reg = NULL_RTX;
   22541                 :             : 
   22542                 :             :   /* Adjust the this parameter by a fixed constant.  */
   22543                 :        2268 :   if (delta)
   22544                 :             :     {
   22545                 :        1068 :       rtx delta_rtx = GEN_INT (delta);
   22546                 :        1068 :       rtx delta_dst = this_reg ? this_reg : this_param;
   22547                 :             : 
   22548                 :        1068 :       if (TARGET_64BIT)
   22549                 :             :         {
   22550                 :        1067 :           if (!x86_64_general_operand (delta_rtx, Pmode))
   22551                 :             :             {
   22552                 :           0 :               tmp = gen_rtx_REG (Pmode, tmp_regno);
   22553                 :           0 :               emit_move_insn (tmp, delta_rtx);
   22554                 :           0 :               delta_rtx = tmp;
   22555                 :             :             }
   22556                 :             :         }
   22557                 :             : 
   22558                 :        1068 :       ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
   22559                 :             :     }
   22560                 :             : 
   22561                 :             :   /* Adjust the this parameter by a value stored in the vtable.  */
   22562                 :        2268 :   if (vcall_offset)
   22563                 :             :     {
   22564                 :        1268 :       rtx vcall_addr, vcall_mem, this_mem;
   22565                 :             : 
   22566                 :        1268 :       tmp = gen_rtx_REG (Pmode, tmp_regno);
   22567                 :             : 
   22568                 :        1268 :       this_mem = gen_rtx_MEM (ptr_mode, this_reg);
   22569                 :        1268 :       if (Pmode != ptr_mode)
   22570                 :           0 :         this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
   22571                 :        1268 :       emit_move_insn (tmp, this_mem);
   22572                 :             : 
   22573                 :             :       /* Adjust the this parameter.  */
   22574                 :        1268 :       vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
   22575                 :        1268 :       if (TARGET_64BIT
   22576                 :        1268 :           && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
   22577                 :             :         {
   22578                 :           0 :           rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
   22579                 :           0 :           emit_move_insn (tmp2, GEN_INT (vcall_offset));
   22580                 :           0 :           vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
   22581                 :             :         }
   22582                 :             : 
   22583                 :        1268 :       vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
   22584                 :        1268 :       if (Pmode != ptr_mode)
   22585                 :           0 :         emit_insn (gen_addsi_1_zext (this_reg,
   22586                 :             :                                      gen_rtx_REG (ptr_mode,
   22587                 :             :                                                   REGNO (this_reg)),
   22588                 :             :                                      vcall_mem));
   22589                 :             :       else
   22590                 :        1268 :         ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
   22591                 :             :     }
   22592                 :             : 
   22593                 :             :   /* If necessary, drop THIS back to its stack slot.  */
   22594                 :        2268 :   if (this_reg && this_reg != this_param)
   22595                 :           1 :     emit_move_insn (this_param, this_reg);
   22596                 :             : 
   22597                 :        2268 :   fnaddr = XEXP (DECL_RTL (function), 0);
   22598                 :        2268 :   if (TARGET_64BIT)
   22599                 :             :     {
   22600                 :          29 :       if (!flag_pic || targetm.binds_local_p (function)
   22601                 :        2295 :           || TARGET_PECOFF)
   22602                 :             :         ;
   22603                 :             :       else
   22604                 :             :         {
   22605                 :           0 :           tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
   22606                 :           0 :           tmp = gen_rtx_CONST (Pmode, tmp);
   22607                 :           0 :           fnaddr = gen_const_mem (Pmode, tmp);
   22608                 :             :         }
   22609                 :             :     }
   22610                 :             :   else
   22611                 :             :     {
   22612                 :           2 :       if (!flag_pic || targetm.binds_local_p (function))
   22613                 :             :         ;
   22614                 :             : #if TARGET_MACHO
   22615                 :             :       else if (TARGET_MACHO)
   22616                 :             :         {
   22617                 :             :           fnaddr = machopic_indirect_call_target (DECL_RTL (function));
   22618                 :             :           fnaddr = XEXP (fnaddr, 0);
   22619                 :             :         }
   22620                 :             : #endif /* TARGET_MACHO */
   22621                 :             :       else
   22622                 :             :         {
   22623                 :           0 :           tmp = gen_rtx_REG (Pmode, CX_REG);
   22624                 :           0 :           output_set_got (tmp, NULL_RTX);
   22625                 :             : 
   22626                 :           0 :           fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
   22627                 :           0 :           fnaddr = gen_rtx_CONST (Pmode, fnaddr);
   22628                 :           0 :           fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
   22629                 :           0 :           fnaddr = gen_const_mem (Pmode, fnaddr);
   22630                 :             :         }
   22631                 :             :     }
   22632                 :             : 
   22633                 :             :   /* Our sibling call patterns do not allow memories, because we have no
   22634                 :             :      predicate that can distinguish between frame and non-frame memory.
   22635                 :             :      For our purposes here, we can get away with (ab)using a jump pattern,
   22636                 :             :      because we're going to do no optimization.  */
   22637                 :        2268 :   if (MEM_P (fnaddr))
   22638                 :             :     {
   22639                 :           0 :       if (sibcall_insn_operand (fnaddr, word_mode))
   22640                 :             :         {
   22641                 :           0 :           fnaddr = XEXP (DECL_RTL (function), 0);
   22642                 :           0 :           tmp = gen_rtx_MEM (QImode, fnaddr);
   22643                 :           0 :           tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   22644                 :           0 :           tmp = emit_call_insn (tmp);
   22645                 :           0 :           SIBLING_CALL_P (tmp) = 1;
   22646                 :             :         }
   22647                 :             :       else
   22648                 :           0 :         emit_jump_insn (gen_indirect_jump (fnaddr));
   22649                 :             :     }
   22650                 :             :   else
   22651                 :             :     {
   22652                 :        2268 :       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
   22653                 :             :         {
   22654                 :             :           // CM_LARGE_PIC always uses pseudo PIC register which is
   22655                 :             :           // uninitialized.  Since FUNCTION is local and calling it
   22656                 :             :           // doesn't go through PLT, we use scratch register %r11 as
   22657                 :             :           // PIC register and initialize it here.
   22658                 :           4 :           pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
   22659                 :           4 :           ix86_init_large_pic_reg (tmp_regno);
   22660                 :           4 :           fnaddr = legitimize_pic_address (fnaddr,
   22661                 :           4 :                                            gen_rtx_REG (Pmode, tmp_regno));
   22662                 :             :         }
   22663                 :             : 
   22664                 :        2268 :       if (!sibcall_insn_operand (fnaddr, word_mode))
   22665                 :             :         {
   22666                 :          12 :           tmp = gen_rtx_REG (word_mode, tmp_regno);
   22667                 :          12 :           if (GET_MODE (fnaddr) != word_mode)
   22668                 :           0 :             fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
   22669                 :          12 :           emit_move_insn (tmp, fnaddr);
   22670                 :          12 :           fnaddr = tmp;
   22671                 :             :         }
   22672                 :             : 
   22673                 :        2268 :       tmp = gen_rtx_MEM (QImode, fnaddr);
   22674                 :        2268 :       tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   22675                 :        2268 :       tmp = emit_call_insn (tmp);
   22676                 :        2268 :       SIBLING_CALL_P (tmp) = 1;
   22677                 :             :     }
   22678                 :        2268 :   emit_barrier ();
   22679                 :             : 
   22680                 :             :   /* Emit just enough of rest_of_compilation to get the insns emitted.  */
   22681                 :        2268 :   insn = get_insns ();
   22682                 :        2268 :   shorten_branches (insn);
   22683                 :        2268 :   assemble_start_function (thunk_fndecl, fnname);
   22684                 :        2268 :   final_start_function (insn, file, 1);
   22685                 :        2268 :   final (insn, file, 1);
   22686                 :        2268 :   final_end_function ();
   22687                 :        2268 :   assemble_end_function (thunk_fndecl, fnname);
   22688                 :             : 
   22689                 :        2268 :   flag_force_indirect_call = saved_flag_force_indirect_call;
   22690                 :        2268 : }
   22691                 :             : 
   22692                 :             : static void
   22693                 :      265705 : x86_file_start (void)
   22694                 :             : {
   22695                 :      265705 :   default_file_start ();
   22696                 :      265705 :   if (TARGET_16BIT)
   22697                 :           6 :     fputs ("\t.code16gcc\n", asm_out_file);
   22698                 :             : #if TARGET_MACHO
   22699                 :             :   darwin_file_start ();
   22700                 :             : #endif
   22701                 :      265705 :   if (X86_FILE_START_VERSION_DIRECTIVE)
   22702                 :             :     fputs ("\t.version\t\"01.01\"\n", asm_out_file);
   22703                 :      265705 :   if (X86_FILE_START_FLTUSED)
   22704                 :             :     fputs ("\t.global\t__fltused\n", asm_out_file);
   22705                 :      265705 :   if (ix86_asm_dialect == ASM_INTEL)
   22706                 :          47 :     fputs ("\t.intel_syntax noprefix\n", asm_out_file);
   22707                 :      265705 : }
   22708                 :             : 
   22709                 :             : int
   22710                 :    82398960 : x86_field_alignment (tree type, int computed)
   22711                 :             : {
   22712                 :    82398960 :   machine_mode mode;
   22713                 :             : 
   22714                 :    82398960 :   if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
   22715                 :             :     return computed;
   22716                 :     8606937 :   if (TARGET_IAMCU)
   22717                 :           0 :     return iamcu_alignment (type, computed);
   22718                 :     8606937 :   type = strip_array_types (type);
   22719                 :     8606937 :   mode = TYPE_MODE (type);
   22720                 :     8606937 :   if (mode == DFmode || mode == DCmode
   22721                 :     8504712 :       || GET_MODE_CLASS (mode) == MODE_INT
   22722                 :     2936048 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
   22723                 :             :     {
   22724                 :     5670889 :       if (TYPE_ATOMIC (type) && computed > 32)
   22725                 :             :         {
   22726                 :           0 :           static bool warned;
   22727                 :             : 
   22728                 :           0 :           if (!warned && warn_psabi)
   22729                 :             :             {
   22730                 :           0 :               const char *url
   22731                 :             :                 = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
   22732                 :             : 
   22733                 :           0 :               warned = true;
   22734                 :           0 :               inform (input_location, "the alignment of %<_Atomic %T%> "
   22735                 :             :                                       "fields changed in %{GCC 11.1%}",
   22736                 :           0 :                       TYPE_MAIN_VARIANT (type), url);
   22737                 :             :             }
   22738                 :             :         }
   22739                 :             :       else
   22740                 :     5670889 :       return MIN (32, computed);
   22741                 :             :     }
   22742                 :             :   return computed;
   22743                 :             : }
   22744                 :             : 
   22745                 :             : /* Print call to TARGET to FILE.  */
   22746                 :             : 
   22747                 :             : static void
   22748                 :         401 : x86_print_call_or_nop (FILE *file, const char *target)
   22749                 :             : {
   22750                 :         401 :   if (flag_nop_mcount || !strcmp (target, "nop"))
   22751                 :             :     /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
   22752                 :           5 :     fprintf (file, "1:" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   22753                 :             :   else
   22754                 :         396 :     fprintf (file, "1:\tcall\t%s\n", target);
   22755                 :         401 : }
   22756                 :             : 
   22757                 :             : static bool
   22758                 :         415 : current_fentry_name (const char **name)
   22759                 :             : {
   22760                 :         415 :   tree attr = lookup_attribute ("fentry_name",
   22761                 :         415 :                                 DECL_ATTRIBUTES (current_function_decl));
   22762                 :         415 :   if (!attr)
   22763                 :             :     return false;
   22764                 :           2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   22765                 :           2 :   return true;
   22766                 :             : }
   22767                 :             : 
   22768                 :             : static bool
   22769                 :          10 : current_fentry_section (const char **name)
   22770                 :             : {
   22771                 :          10 :   tree attr = lookup_attribute ("fentry_section",
   22772                 :          10 :                                 DECL_ATTRIBUTES (current_function_decl));
   22773                 :          10 :   if (!attr)
   22774                 :             :     return false;
   22775                 :           2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   22776                 :           2 :   return true;
   22777                 :             : }
   22778                 :             : 
   22779                 :             : /* Return a caller-saved register which isn't live or a callee-saved
   22780                 :             :    register which has been saved on stack in the prologue at entry for
   22781                 :             :    profile.  */
   22782                 :             : 
   22783                 :             : static int
   22784                 :          13 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
   22785                 :             : {
   22786                 :             :   /* Use %r10 if the profiler is emitted before the prologue or it isn't
   22787                 :             :      used by DRAP.  */
   22788                 :          13 :   if (ix86_profile_before_prologue ()
   22789                 :           9 :       || !crtl->drap_reg
   22790                 :          16 :       || REGNO (crtl->drap_reg) != R10_REG)
   22791                 :             :     return R10_REG;
   22792                 :             : 
   22793                 :             :   /* The profiler is emitted after the prologue.  If there is a
   22794                 :             :      caller-saved register which isn't live or a callee-saved
   22795                 :             :      register saved on stack in the prologue, use it.  */
   22796                 :             : 
   22797                 :           3 :   bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
   22798                 :             : 
   22799                 :           3 :   int i;
   22800                 :          88 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22801                 :          56 :     if (GENERAL_REGNO_P (i)
   22802                 :          29 :         && i != R10_REG
   22803                 :             : #ifdef NO_PROFILE_COUNTERS
   22804                 :          27 :         && (r11_ok || i != R11_REG)
   22805                 :             : #else
   22806                 :             :         && i != R11_REG
   22807                 :             : #endif
   22808                 :          26 :         && TEST_HARD_REG_BIT (accessible_reg_set, i)
   22809                 :         111 :         && (ix86_save_reg (i, true, true)
   22810                 :          25 :             || (call_used_regs[i]
   22811                 :          18 :                 && !fixed_regs[i]
   22812                 :          16 :                 && !REGNO_REG_SET_P (reg_live, i))))
   22813                 :           3 :       return i;
   22814                 :             : 
   22815                 :           0 :   sorry ("no register available for profiling %<-mcmodel=large%s%>",
   22816                 :           0 :          ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
   22817                 :             : 
   22818                 :           0 :   return R10_REG;
   22819                 :             : }
   22820                 :             : 
   22821                 :             : /* Output assembler code to FILE to increment profiler label # LABELNO
   22822                 :             :    for profiling a function entry.  */
   22823                 :             : void
   22824                 :         415 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   22825                 :             : {
   22826                 :         415 :   if (cfun->machine->insn_queued_at_entrance)
   22827                 :             :     {
   22828                 :           5 :       if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
   22829                 :           4 :         fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
   22830                 :           5 :       unsigned int patch_area_size
   22831                 :           5 :         = crtl->patch_area_size - crtl->patch_area_entry;
   22832                 :           5 :       if (patch_area_size)
   22833                 :           2 :         ix86_output_patchable_area (patch_area_size,
   22834                 :             :                                     crtl->patch_area_entry == 0);
   22835                 :             :     }
   22836                 :             : 
   22837                 :         415 :   const char *mcount_name = MCOUNT_NAME;
   22838                 :             : 
   22839                 :         415 :   if (current_fentry_name (&mcount_name))
   22840                 :             :     ;
   22841                 :         413 :   else if (fentry_name)
   22842                 :           1 :     mcount_name = fentry_name;
   22843                 :         412 :   else if (flag_fentry)
   22844                 :          21 :     mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
   22845                 :             : 
   22846                 :         415 :   if (TARGET_64BIT)
   22847                 :             :     {
   22848                 :             : #ifndef NO_PROFILE_COUNTERS
   22849                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   22850                 :             :         fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
   22851                 :             :       else
   22852                 :             :         fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
   22853                 :             : #endif
   22854                 :             : 
   22855                 :         415 :       int scratch;
   22856                 :         415 :       const char *reg;
   22857                 :         415 :       char legacy_reg[4] = { 0 };
   22858                 :             : 
   22859                 :         415 :       if (!TARGET_PECOFF)
   22860                 :             :         {
   22861                 :         415 :           switch (ix86_cmodel)
   22862                 :             :             {
   22863                 :           5 :             case CM_LARGE:
   22864                 :           5 :               scratch = x86_64_select_profile_regnum (true);
   22865                 :           5 :               reg = hi_reg_name[scratch];
   22866                 :           5 :               if (LEGACY_INT_REGNO_P (scratch))
   22867                 :             :                 {
   22868                 :           0 :                   legacy_reg[0] = 'r';
   22869                 :           0 :                   legacy_reg[1] = reg[0];
   22870                 :           0 :                   legacy_reg[2] = reg[1];
   22871                 :           0 :                   reg = legacy_reg;
   22872                 :             :                 }
   22873                 :           5 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   22874                 :           1 :                 fprintf (file, "1:\tmovabs\t%s, OFFSET FLAT:%s\n"
   22875                 :             :                                "\tcall\t%s\n", reg, mcount_name, reg);
   22876                 :             :               else
   22877                 :           4 :                 fprintf (file, "1:\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
   22878                 :             :                          mcount_name, reg, reg);
   22879                 :             :               break;
   22880                 :           8 :             case CM_LARGE_PIC:
   22881                 :             : #ifdef NO_PROFILE_COUNTERS
   22882                 :           8 :               scratch = x86_64_select_profile_regnum (false);
   22883                 :           8 :               reg = hi_reg_name[scratch];
   22884                 :           8 :               if (LEGACY_INT_REGNO_P (scratch))
   22885                 :             :                 {
   22886                 :           1 :                   legacy_reg[0] = 'r';
   22887                 :           1 :                   legacy_reg[1] = reg[0];
   22888                 :           1 :                   legacy_reg[2] = reg[1];
   22889                 :           1 :                   reg = legacy_reg;
   22890                 :             :                 }
   22891                 :           8 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   22892                 :             :                 {
   22893                 :           1 :                   fprintf (file, "1:movabs\tr11, "
   22894                 :             :                                  "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
   22895                 :           1 :                   fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
   22896                 :           1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   22897                 :           1 :                   fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
   22898                 :             :                            mcount_name);
   22899                 :           1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   22900                 :           1 :                   fprintf (file, "\tcall\t%s\n", reg);
   22901                 :           1 :                   break;
   22902                 :             :                 }
   22903                 :           7 :               fprintf (file,
   22904                 :             :                        "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
   22905                 :           7 :               fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
   22906                 :           7 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   22907                 :           7 :               fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
   22908                 :           7 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   22909                 :           7 :               fprintf (file, "\tcall\t*%%%s\n", reg);
   22910                 :             : #else
   22911                 :             :               sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
   22912                 :             : #endif
   22913                 :           7 :               break;
   22914                 :           5 :             case CM_SMALL_PIC:
   22915                 :           5 :             case CM_MEDIUM_PIC:
   22916                 :           5 :               if (!ix86_direct_extern_access)
   22917                 :             :                 {
   22918                 :           1 :                   if (ASSEMBLER_DIALECT == ASM_INTEL)
   22919                 :           1 :                     fprintf (file, "1:\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
   22920                 :             :                              mcount_name);
   22921                 :             :                   else
   22922                 :           0 :                     fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n",
   22923                 :             :                              mcount_name);
   22924                 :             :                   break;
   22925                 :             :                 }
   22926                 :             :               /* fall through */
   22927                 :         401 :             default:
   22928                 :         401 :               x86_print_call_or_nop (file, mcount_name);
   22929                 :         401 :               break;
   22930                 :             :             }
   22931                 :             :         }
   22932                 :             :       else
   22933                 :             :         x86_print_call_or_nop (file, mcount_name);
   22934                 :             :     }
   22935                 :           0 :   else if (flag_pic)
   22936                 :             :     {
   22937                 :             : #ifndef NO_PROFILE_COUNTERS
   22938                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   22939                 :             :         fprintf (file,
   22940                 :             :                  "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
   22941                 :             :                  LPREFIX, labelno);
   22942                 :             :       else
   22943                 :             :         fprintf (file,
   22944                 :             :                  "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
   22945                 :             :                  LPREFIX, labelno);
   22946                 :             : #endif
   22947                 :           0 :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   22948                 :           0 :         fprintf (file, "1:\tcall\t[DWORD PTR %s@GOT[ebx]]\n", mcount_name);
   22949                 :             :       else
   22950                 :           0 :         fprintf (file, "1:\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
   22951                 :             :     }
   22952                 :             :   else
   22953                 :             :     {
   22954                 :             : #ifndef NO_PROFILE_COUNTERS
   22955                 :             :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   22956                 :             :         fprintf (file,
   22957                 :             :                  "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
   22958                 :             :                  LPREFIX, labelno);
   22959                 :             :       else
   22960                 :             :         fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
   22961                 :             :                  LPREFIX, labelno);
   22962                 :             : #endif
   22963                 :           0 :       x86_print_call_or_nop (file, mcount_name);
   22964                 :             :     }
   22965                 :             : 
   22966                 :         415 :   if (flag_record_mcount
   22967                 :         821 :       || lookup_attribute ("fentry_section",
   22968                 :         406 :                            DECL_ATTRIBUTES (current_function_decl)))
   22969                 :             :     {
   22970                 :          10 :       const char *sname = "__mcount_loc";
   22971                 :             : 
   22972                 :          10 :       if (current_fentry_section (&sname))
   22973                 :             :         ;
   22974                 :           8 :       else if (fentry_section)
   22975                 :           1 :         sname = fentry_section;
   22976                 :             : 
   22977                 :          10 :       fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
   22978                 :          10 :       fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   22979                 :          10 :       fprintf (file, "\t.previous\n");
   22980                 :             :     }
   22981                 :         415 : }
   22982                 :             : 
   22983                 :             : /* We don't have exact information about the insn sizes, but we may assume
   22984                 :             :    quite safely that we are informed about all 1 byte insns and memory
   22985                 :             :    address sizes.  This is enough to eliminate unnecessary padding in
   22986                 :             :    99% of cases.  */
   22987                 :             : 
   22988                 :             : int
   22989                 :   320858854 : ix86_min_insn_size (rtx_insn *insn)
   22990                 :             : {
   22991                 :   320858854 :   int l = 0, len;
   22992                 :             : 
   22993                 :   320858854 :   if (!INSN_P (insn) || !active_insn_p (insn))
   22994                 :      471795 :     return 0;
   22995                 :             : 
   22996                 :             :   /* Discard alignments we've emit and jump instructions.  */
   22997                 :   320387059 :   if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
   22998                 :   320387059 :       && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
   22999                 :             :     return 0;
   23000                 :             : 
   23001                 :             :   /* Important case - calls are always 5 bytes.
   23002                 :             :      It is common to have many calls in the row.  */
   23003                 :   320387054 :   if (CALL_P (insn)
   23004                 :     8304159 :       && symbolic_reference_mentioned_p (PATTERN (insn))
   23005                 :   328383114 :       && !SIBLING_CALL_P (insn))
   23006                 :             :     return 5;
   23007                 :   312599020 :   len = get_attr_length (insn);
   23008                 :   312599020 :   if (len <= 1)
   23009                 :             :     return 1;
   23010                 :             : 
   23011                 :             :   /* For normal instructions we rely on get_attr_length being exact,
   23012                 :             :      with a few exceptions.  */
   23013                 :   303583809 :   if (!JUMP_P (insn))
   23014                 :             :     {
   23015                 :   298886411 :       enum attr_type type = get_attr_type (insn);
   23016                 :             : 
   23017                 :   298886411 :       switch (type)
   23018                 :             :         {
   23019                 :       89384 :         case TYPE_MULTI:
   23020                 :       89384 :           if (GET_CODE (PATTERN (insn)) == ASM_INPUT
   23021                 :       89384 :               || asm_noperands (PATTERN (insn)) >= 0)
   23022                 :         118 :             return 0;
   23023                 :             :           break;
   23024                 :             :         case TYPE_OTHER:
   23025                 :             :         case TYPE_FCMP:
   23026                 :             :           break;
   23027                 :             :         default:
   23028                 :             :           /* Otherwise trust get_attr_length.  */
   23029                 :             :           return len;
   23030                 :             :         }
   23031                 :             : 
   23032                 :      443791 :       l = get_attr_length_address (insn);
   23033                 :      443791 :       if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
   23034                 :             :         l = 4;
   23035                 :             :     }
   23036                 :      356857 :   if (l)
   23037                 :       86934 :     return 1+l;
   23038                 :             :   else
   23039                 :     5054255 :     return 2;
   23040                 :             : }
   23041                 :             : 
   23042                 :             : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   23043                 :             : 
   23044                 :             : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
   23045                 :             :    window.  */
   23046                 :             : 
   23047                 :             : static void
   23048                 :       41087 : ix86_avoid_jump_mispredicts (void)
   23049                 :             : {
   23050                 :       41087 :   rtx_insn *insn, *start = get_insns ();
   23051                 :       41087 :   int nbytes = 0, njumps = 0;
   23052                 :       41087 :   bool isjump = false;
   23053                 :             : 
   23054                 :             :   /* Look for all minimal intervals of instructions containing 4 jumps.
   23055                 :             :      The intervals are bounded by START and INSN.  NBYTES is the total
   23056                 :             :      size of instructions in the interval including INSN and not including
   23057                 :             :      START.  When the NBYTES is smaller than 16 bytes, it is possible
   23058                 :             :      that the end of START and INSN ends up in the same 16byte page.
   23059                 :             : 
   23060                 :             :      The smallest offset in the page INSN can start is the case where START
   23061                 :             :      ends on the offset 0.  Offset of INSN is then NBYTES - sizeof (INSN).
   23062                 :             :      We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
   23063                 :             : 
   23064                 :             :      Don't consider asm goto as jump, while it can contain a jump, it doesn't
   23065                 :             :      have to, control transfer to label(s) can be performed through other
   23066                 :             :      means, and also we estimate minimum length of all asm stmts as 0.  */
   23067                 :      656632 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   23068                 :             :     {
   23069                 :      615545 :       int min_size;
   23070                 :             : 
   23071                 :      615545 :       if (LABEL_P (insn))
   23072                 :             :         {
   23073                 :        1049 :           align_flags alignment = label_to_alignment (insn);
   23074                 :        1049 :           int align = alignment.levels[0].log;
   23075                 :        1049 :           int max_skip = alignment.levels[0].maxskip;
   23076                 :             : 
   23077                 :        1049 :           if (max_skip > 15)
   23078                 :             :             max_skip = 15;
   23079                 :             :           /* If align > 3, only up to 16 - max_skip - 1 bytes can be
   23080                 :             :              already in the current 16 byte page, because otherwise
   23081                 :             :              ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
   23082                 :             :              bytes to reach 16 byte boundary.  */
   23083                 :        1049 :           if (align <= 0
   23084                 :         340 :               || (align <= 3 && max_skip != (1 << align) - 1))
   23085                 :        1049 :             max_skip = 0;
   23086                 :        1049 :           if (dump_file)
   23087                 :           0 :             fprintf (dump_file, "Label %i with max_skip %i\n",
   23088                 :           0 :                      INSN_UID (insn), max_skip);
   23089                 :        1049 :           if (max_skip)
   23090                 :             :             {
   23091                 :        6802 :               while (nbytes + max_skip >= 16)
   23092                 :             :                 {
   23093                 :        6462 :                   start = NEXT_INSN (start);
   23094                 :         332 :                   if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   23095                 :        6480 :                       || CALL_P (start))
   23096                 :         362 :                     njumps--, isjump = true;
   23097                 :             :                   else
   23098                 :             :                     isjump = false;
   23099                 :        6462 :                   nbytes -= ix86_min_insn_size (start);
   23100                 :             :                 }
   23101                 :             :             }
   23102                 :        1049 :           continue;
   23103                 :        1049 :         }
   23104                 :             : 
   23105                 :      614496 :       min_size = ix86_min_insn_size (insn);
   23106                 :      614496 :       nbytes += min_size;
   23107                 :      614496 :       if (dump_file)
   23108                 :           0 :         fprintf (dump_file, "Insn %i estimated to %i bytes\n",
   23109                 :           0 :                  INSN_UID (insn), min_size);
   23110                 :       42365 :       if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
   23111                 :      614516 :           || CALL_P (insn))
   23112                 :       43486 :         njumps++;
   23113                 :             :       else
   23114                 :      571010 :         continue;
   23115                 :             : 
   23116                 :       53018 :       while (njumps > 3)
   23117                 :             :         {
   23118                 :        9532 :           start = NEXT_INSN (start);
   23119                 :         598 :           if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   23120                 :        9532 :               || CALL_P (start))
   23121                 :        1326 :             njumps--, isjump = true;
   23122                 :             :           else
   23123                 :             :             isjump = false;
   23124                 :        9532 :           nbytes -= ix86_min_insn_size (start);
   23125                 :             :         }
   23126                 :       43486 :       gcc_assert (njumps >= 0);
   23127                 :       43486 :       if (dump_file)
   23128                 :           0 :         fprintf (dump_file, "Interval %i to %i has %i bytes\n",
   23129                 :           0 :                  INSN_UID (start), INSN_UID (insn), nbytes);
   23130                 :             : 
   23131                 :       43486 :       if (njumps == 3 && isjump && nbytes < 16)
   23132                 :             :         {
   23133                 :          55 :           int padsize = 15 - nbytes + ix86_min_insn_size (insn);
   23134                 :             : 
   23135                 :          55 :           if (dump_file)
   23136                 :           0 :             fprintf (dump_file, "Padding insn %i by %i bytes!\n",
   23137                 :           0 :                      INSN_UID (insn), padsize);
   23138                 :          55 :           emit_insn_before (gen_pad (GEN_INT (padsize)), insn);
   23139                 :             :         }
   23140                 :             :     }
   23141                 :       41087 : }
   23142                 :             : #endif
   23143                 :             : 
   23144                 :             : /* AMD Athlon works faster
   23145                 :             :    when RET is not destination of conditional jump or directly preceded
   23146                 :             :    by other jump instruction.  We avoid the penalty by inserting NOP just
   23147                 :             :    before the RET instructions in such cases.  */
   23148                 :             : static void
   23149                 :       40789 : ix86_pad_returns (void)
   23150                 :             : {
   23151                 :       40789 :   edge e;
   23152                 :       40789 :   edge_iterator ei;
   23153                 :             : 
   23154                 :       81606 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23155                 :             :     {
   23156                 :       40817 :       basic_block bb = e->src;
   23157                 :       40817 :       rtx_insn *ret = BB_END (bb);
   23158                 :       40817 :       rtx_insn *prev;
   23159                 :       40817 :       bool replace = false;
   23160                 :             : 
   23161                 :       40804 :       if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
   23162                 :       81621 :           || optimize_bb_for_size_p (bb))
   23163                 :          38 :         continue;
   23164                 :      162083 :       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
   23165                 :      120887 :         if (active_insn_p (prev) || LABEL_P (prev))
   23166                 :             :           break;
   23167                 :       40779 :       if (prev && LABEL_P (prev))
   23168                 :             :         {
   23169                 :          69 :           edge e;
   23170                 :          69 :           edge_iterator ei;
   23171                 :             : 
   23172                 :          81 :           FOR_EACH_EDGE (e, ei, bb->preds)
   23173                 :         221 :             if (EDGE_FREQUENCY (e) && e->src->index >= 0
   23174                 :         147 :                 && !(e->flags & EDGE_FALLTHRU))
   23175                 :             :               {
   23176                 :             :                 replace = true;
   23177                 :             :                 break;
   23178                 :             :               }
   23179                 :             :         }
   23180                 :          69 :       if (!replace)
   23181                 :             :         {
   23182                 :       40717 :           prev = prev_active_insn (ret);
   23183                 :       40717 :           if (prev
   23184                 :       40717 :               && ((JUMP_P (prev) && any_condjump_p (prev))
   23185                 :       40281 :                   || CALL_P (prev)))
   23186                 :             :             replace = true;
   23187                 :             :           /* Empty functions get branch mispredict even when
   23188                 :             :              the jump destination is not visible to us.  */
   23189                 :       40717 :           if (!prev && !optimize_function_for_size_p (cfun))
   23190                 :             :             replace = true;
   23191                 :             :         }
   23192                 :       40300 :       if (replace)
   23193                 :             :         {
   23194                 :         552 :           emit_jump_insn_before (gen_simple_return_internal_long (), ret);
   23195                 :         552 :           delete_insn (ret);
   23196                 :             :         }
   23197                 :             :     }
   23198                 :       40789 : }
   23199                 :             : 
   23200                 :             : /* Count the minimum number of instructions in BB.  Return 4 if the
   23201                 :             :    number of instructions >= 4.  */
   23202                 :             : 
   23203                 :             : static int
   23204                 :          43 : ix86_count_insn_bb (basic_block bb)
   23205                 :             : {
   23206                 :          43 :   rtx_insn *insn;
   23207                 :          43 :   int insn_count = 0;
   23208                 :             : 
   23209                 :             :   /* Count number of instructions in this block.  Return 4 if the number
   23210                 :             :      of instructions >= 4.  */
   23211                 :         319 :   FOR_BB_INSNS (bb, insn)
   23212                 :             :     {
   23213                 :             :       /* Only happen in exit blocks.  */
   23214                 :         313 :       if (JUMP_P (insn)
   23215                 :         313 :           && ANY_RETURN_P (PATTERN (insn)))
   23216                 :             :         break;
   23217                 :             : 
   23218                 :         288 :       if (NONDEBUG_INSN_P (insn)
   23219                 :         105 :           && GET_CODE (PATTERN (insn)) != USE
   23220                 :         375 :           && GET_CODE (PATTERN (insn)) != CLOBBER)
   23221                 :             :         {
   23222                 :          87 :           insn_count++;
   23223                 :          87 :           if (insn_count >= 4)
   23224                 :          12 :             return insn_count;
   23225                 :             :         }
   23226                 :             :     }
   23227                 :             : 
   23228                 :             :   return insn_count;
   23229                 :             : }
   23230                 :             : 
   23231                 :             : 
   23232                 :             : /* Count the minimum number of instructions in code path in BB.
   23233                 :             :    Return 4 if the number of instructions >= 4.  */
   23234                 :             : 
   23235                 :             : static int
   23236                 :          64 : ix86_count_insn (basic_block bb)
   23237                 :             : {
   23238                 :          64 :   edge e;
   23239                 :          64 :   edge_iterator ei;
   23240                 :          64 :   int min_prev_count;
   23241                 :             : 
   23242                 :             :   /* Only bother counting instructions along paths with no
   23243                 :             :      more than 2 basic blocks between entry and exit.  Given
   23244                 :             :      that BB has an edge to exit, determine if a predecessor
   23245                 :             :      of BB has an edge from entry.  If so, compute the number
   23246                 :             :      of instructions in the predecessor block.  If there
   23247                 :             :      happen to be multiple such blocks, compute the minimum.  */
   23248                 :          64 :   min_prev_count = 4;
   23249                 :         148 :   FOR_EACH_EDGE (e, ei, bb->preds)
   23250                 :             :     {
   23251                 :         111 :       edge prev_e;
   23252                 :         111 :       edge_iterator prev_ei;
   23253                 :             : 
   23254                 :         111 :       if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   23255                 :             :         {
   23256                 :          27 :           min_prev_count = 0;
   23257                 :          27 :           break;
   23258                 :             :         }
   23259                 :         186 :       FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
   23260                 :             :         {
   23261                 :         112 :           if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   23262                 :             :             {
   23263                 :          10 :               int count = ix86_count_insn_bb (e->src);
   23264                 :          10 :               if (count < min_prev_count)
   23265                 :          84 :                 min_prev_count = count;
   23266                 :             :               break;
   23267                 :             :             }
   23268                 :             :         }
   23269                 :             :     }
   23270                 :             : 
   23271                 :          64 :   if (min_prev_count < 4)
   23272                 :          33 :     min_prev_count += ix86_count_insn_bb (bb);
   23273                 :             : 
   23274                 :          64 :   return min_prev_count;
   23275                 :             : }
   23276                 :             : 
   23277                 :             : /* Pad short function to 4 instructions.   */
   23278                 :             : 
   23279                 :             : static void
   23280                 :          66 : ix86_pad_short_function (void)
   23281                 :             : {
   23282                 :          66 :   edge e;
   23283                 :          66 :   edge_iterator ei;
   23284                 :             : 
   23285                 :         133 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23286                 :             :     {
   23287                 :          67 :       rtx_insn *ret = BB_END (e->src);
   23288                 :          67 :       if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
   23289                 :             :         {
   23290                 :          64 :           int insn_count = ix86_count_insn (e->src);
   23291                 :             : 
   23292                 :             :           /* Pad short function.  */
   23293                 :          64 :           if (insn_count < 4)
   23294                 :             :             {
   23295                 :             :               rtx_insn *insn = ret;
   23296                 :             : 
   23297                 :             :               /* Find epilogue.  */
   23298                 :             :               while (insn
   23299                 :          56 :                      && (!NOTE_P (insn)
   23300                 :          26 :                          || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
   23301                 :          32 :                 insn = PREV_INSN (insn);
   23302                 :             : 
   23303                 :          24 :               if (!insn)
   23304                 :           0 :                 insn = ret;
   23305                 :             : 
   23306                 :             :               /* Two NOPs count as one instruction.  */
   23307                 :          24 :               insn_count = 2 * (4 - insn_count);
   23308                 :          24 :               emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
   23309                 :             :             }
   23310                 :             :         }
   23311                 :             :     }
   23312                 :          66 : }
   23313                 :             : 
   23314                 :             : /* Fix up a Windows system unwinder issue.  If an EH region falls through into
   23315                 :             :    the epilogue, the Windows system unwinder will apply epilogue logic and
   23316                 :             :    produce incorrect offsets.  This can be avoided by adding a nop between
   23317                 :             :    the last insn that can throw and the first insn of the epilogue.  */
   23318                 :             : 
   23319                 :             : static void
   23320                 :           0 : ix86_seh_fixup_eh_fallthru (void)
   23321                 :             : {
   23322                 :           0 :   edge e;
   23323                 :           0 :   edge_iterator ei;
   23324                 :             : 
   23325                 :           0 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   23326                 :             :     {
   23327                 :           0 :       rtx_insn *insn, *next;
   23328                 :             : 
   23329                 :             :       /* Find the beginning of the epilogue.  */
   23330                 :           0 :       for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
   23331                 :           0 :         if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
   23332                 :             :           break;
   23333                 :           0 :       if (insn == NULL)
   23334                 :           0 :         continue;
   23335                 :             : 
   23336                 :             :       /* We only care about preceding insns that can throw.  */
   23337                 :           0 :       insn = prev_active_insn (insn);
   23338                 :           0 :       if (insn == NULL || !can_throw_internal (insn))
   23339                 :           0 :         continue;
   23340                 :             : 
   23341                 :             :       /* Do not separate calls from their debug information.  */
   23342                 :           0 :       for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
   23343                 :           0 :         if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
   23344                 :           0 :           insn = next;
   23345                 :             :         else
   23346                 :             :           break;
   23347                 :             : 
   23348                 :           0 :       emit_insn_after (gen_nops (const1_rtx), insn);
   23349                 :             :     }
   23350                 :           0 : }
   23351                 :             : /* Split vector load from parm_decl to elemental loads to avoid STLF
   23352                 :             :    stalls.  */
   23353                 :             : static void
   23354                 :      912331 : ix86_split_stlf_stall_load ()
   23355                 :             : {
   23356                 :      912331 :   rtx_insn* insn, *start = get_insns ();
   23357                 :      912331 :   unsigned window = 0;
   23358                 :             : 
   23359                 :    24788163 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   23360                 :             :     {
   23361                 :    24787306 :       if (!NONDEBUG_INSN_P (insn))
   23362                 :    13530453 :         continue;
   23363                 :    11256853 :       window++;
   23364                 :             :       /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
   23365                 :             :          other, just emulate for pipeline) before stalled load, stlf stall
   23366                 :             :          case is as fast as no stall cases on CLX.
   23367                 :             :          Since CFG is freed before machine_reorg, just do a rough
   23368                 :             :          calculation of the window according to the layout.  */
   23369                 :    11256853 :       if (window > (unsigned) x86_stlf_window_ninsns)
   23370                 :             :         return;
   23371                 :             : 
   23372                 :    11239676 :       if (any_uncondjump_p (insn)
   23373                 :    11206512 :           || ANY_RETURN_P (PATTERN (insn))
   23374                 :    22099455 :           || CALL_P (insn))
   23375                 :             :         return;
   23376                 :             : 
   23377                 :    10345379 :       rtx set = single_set (insn);
   23378                 :    10345379 :       if (!set)
   23379                 :      375997 :         continue;
   23380                 :     9969382 :       rtx src = SET_SRC (set);
   23381                 :    19938414 :       if (!MEM_P (src)
   23382                 :             :           /* Only handle V2DFmode load since it doesn't need any scratch
   23383                 :             :              register.  */
   23384                 :     9969382 :           || GET_MODE (src) != E_V2DFmode
   23385                 :        4756 :           || !MEM_EXPR (src)
   23386                 :     9972720 :           || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL)
   23387                 :     9969032 :         continue;
   23388                 :             : 
   23389                 :         350 :       rtx zero = CONST0_RTX (V2DFmode);
   23390                 :         350 :       rtx dest = SET_DEST (set);
   23391                 :         350 :       rtx m = adjust_address (src, DFmode, 0);
   23392                 :         350 :       rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
   23393                 :         350 :       emit_insn_before (loadlpd, insn);
   23394                 :         350 :       m = adjust_address (src, DFmode, 8);
   23395                 :         350 :       rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
   23396                 :         350 :       if (dump_file && (dump_flags & TDF_DETAILS))
   23397                 :             :         {
   23398                 :           0 :           fputs ("Due to potential STLF stall, split instruction:\n",
   23399                 :             :                  dump_file);
   23400                 :           0 :           print_rtl_single (dump_file, insn);
   23401                 :           0 :           fputs ("To:\n", dump_file);
   23402                 :           0 :           print_rtl_single (dump_file, loadlpd);
   23403                 :           0 :           print_rtl_single (dump_file, loadhpd);
   23404                 :             :         }
   23405                 :         350 :       PATTERN (insn) = loadhpd;
   23406                 :         350 :       INSN_CODE (insn) = -1;
   23407                 :         350 :       gcc_assert (recog_memoized (insn) != -1);
   23408                 :             :     }
   23409                 :             : }
   23410                 :             : 
   23411                 :             : /* Implement machine specific optimizations.  We implement padding of returns
   23412                 :             :    for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window.  */
   23413                 :             : static void
   23414                 :     1392360 : ix86_reorg (void)
   23415                 :             : {
   23416                 :             :   /* We are freeing block_for_insn in the toplev to keep compatibility
   23417                 :             :      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   23418                 :     1392360 :   compute_bb_for_insn ();
   23419                 :             : 
   23420                 :     1392360 :   if (TARGET_SEH && current_function_has_exception_handlers ())
   23421                 :             :     ix86_seh_fixup_eh_fallthru ();
   23422                 :             : 
   23423                 :     1392360 :   if (optimize && optimize_function_for_speed_p (cfun))
   23424                 :             :     {
   23425                 :      914601 :       if (TARGET_SSE2)
   23426                 :      912331 :         ix86_split_stlf_stall_load ();
   23427                 :      914601 :       if (TARGET_PAD_SHORT_FUNCTION)
   23428                 :          66 :         ix86_pad_short_function ();
   23429                 :      914535 :       else if (TARGET_PAD_RETURNS)
   23430                 :       40789 :         ix86_pad_returns ();
   23431                 :             : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   23432                 :      914601 :       if (TARGET_FOUR_JUMP_LIMIT)
   23433                 :       41087 :         ix86_avoid_jump_mispredicts ();
   23434                 :             : #endif
   23435                 :             :     }
   23436                 :     1392360 : }
   23437                 :             : 
   23438                 :             : /* Return nonzero when QImode register that must be represented via REX prefix
   23439                 :             :    is used.  */
   23440                 :             : bool
   23441                 :     7297972 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
   23442                 :             : {
   23443                 :     7297972 :   int i;
   23444                 :     7297972 :   extract_insn_cached (insn);
   23445                 :    27787819 :   for (i = 0; i < recog_data.n_operands; i++)
   23446                 :     3964949 :     if (GENERAL_REG_P (recog_data.operand[i])
   23447                 :    18319279 :         && !QI_REGNO_P (REGNO (recog_data.operand[i])))
   23448                 :             :        return true;
   23449                 :             :   return false;
   23450                 :             : }
   23451                 :             : 
   23452                 :             : /* Return true when INSN mentions register that must be encoded using REX
   23453                 :             :    prefix.  */
   23454                 :             : bool
   23455                 :   170827334 : x86_extended_reg_mentioned_p (rtx insn)
   23456                 :             : {
   23457                 :   170827334 :   subrtx_iterator::array_type array;
   23458                 :   887828773 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   23459                 :             :     {
   23460                 :   761055024 :       const_rtx x = *iter;
   23461                 :   761055024 :       if (REG_P (x)
   23462                 :   761055024 :           && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
   23463                 :   217693461 :               || REX2_INT_REGNO_P (REGNO (x))))
   23464                 :    44053585 :         return true;
   23465                 :             :     }
   23466                 :   126773749 :   return false;
   23467                 :   170827334 : }
   23468                 :             : 
   23469                 :             : /* Return true when INSN mentions register that must be encoded using REX2
   23470                 :             :    prefix.  */
   23471                 :             : bool
   23472                 :     1803904 : x86_extended_rex2reg_mentioned_p (rtx insn)
   23473                 :             : {
   23474                 :     1803904 :   subrtx_iterator::array_type array;
   23475                 :     8515393 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   23476                 :             :     {
   23477                 :     6712138 :       const_rtx x = *iter;
   23478                 :     6712138 :       if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
   23479                 :         649 :         return true;
   23480                 :             :     }
   23481                 :     1803255 :   return false;
   23482                 :     1803904 : }
   23483                 :             : 
   23484                 :             : /* Return true when rtx operands mentions register that must be encoded using
   23485                 :             :    evex prefix.  */
   23486                 :             : bool
   23487                 :          16 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
   23488                 :             : {
   23489                 :          16 :   int i;
   23490                 :          52 :   for (i = 0; i < nops; i++)
   23491                 :          36 :     if (EXT_REX_SSE_REG_P (operands[i])
   23492                 :          72 :         || x86_extended_rex2reg_mentioned_p (operands[i]))
   23493                 :           4 :       return true;
   23494                 :             :   return false;
   23495                 :             : }
   23496                 :             : 
   23497                 :             : /* If profitable, negate (without causing overflow) integer constant
   23498                 :             :    of mode MODE at location LOC.  Return true in this case.  */
   23499                 :             : bool
   23500                 :     5517916 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
   23501                 :             : {
   23502                 :     5517916 :   HOST_WIDE_INT val;
   23503                 :             : 
   23504                 :     5517916 :   if (!CONST_INT_P (*loc))
   23505                 :             :     return false;
   23506                 :             : 
   23507                 :     4674088 :   switch (mode)
   23508                 :             :     {
   23509                 :     2573948 :     case E_DImode:
   23510                 :             :       /* DImode x86_64 constants must fit in 32 bits.  */
   23511                 :     2573948 :       gcc_assert (x86_64_immediate_operand (*loc, mode));
   23512                 :             : 
   23513                 :             :       mode = SImode;
   23514                 :             :       break;
   23515                 :             : 
   23516                 :             :     case E_SImode:
   23517                 :             :     case E_HImode:
   23518                 :             :     case E_QImode:
   23519                 :             :       break;
   23520                 :             : 
   23521                 :           0 :     default:
   23522                 :           0 :       gcc_unreachable ();
   23523                 :             :     }
   23524                 :             : 
   23525                 :             :   /* Avoid overflows.  */
   23526                 :     4674088 :   if (mode_signbit_p (mode, *loc))
   23527                 :             :     return false;
   23528                 :             : 
   23529                 :     4673671 :   val = INTVAL (*loc);
   23530                 :             : 
   23531                 :             :   /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
   23532                 :             :      Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
   23533                 :     4673671 :   if ((val < 0 && val != -128)
   23534                 :     3050408 :       || val == 128)
   23535                 :             :     {
   23536                 :     1633634 :       *loc = GEN_INT (-val);
   23537                 :     1633634 :       return true;
   23538                 :             :     }
   23539                 :             : 
   23540                 :             :   return false;
   23541                 :             : }
   23542                 :             : 
   23543                 :             : /* Generate an unsigned DImode/SImode to FP conversion.  This is the same code
   23544                 :             :    optabs would emit if we didn't have TFmode patterns.  */
   23545                 :             : 
   23546                 :             : void
   23547                 :        4602 : x86_emit_floatuns (rtx operands[2])
   23548                 :             : {
   23549                 :        4602 :   rtx_code_label *neglab, *donelab;
   23550                 :        4602 :   rtx i0, i1, f0, in, out;
   23551                 :        4602 :   machine_mode mode, inmode;
   23552                 :             : 
   23553                 :        4602 :   inmode = GET_MODE (operands[1]);
   23554                 :        4602 :   gcc_assert (inmode == SImode || inmode == DImode);
   23555                 :             : 
   23556                 :        4602 :   out = operands[0];
   23557                 :        4602 :   in = force_reg (inmode, operands[1]);
   23558                 :        4602 :   mode = GET_MODE (out);
   23559                 :        4602 :   neglab = gen_label_rtx ();
   23560                 :        4602 :   donelab = gen_label_rtx ();
   23561                 :        4602 :   f0 = gen_reg_rtx (mode);
   23562                 :             : 
   23563                 :        4602 :   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
   23564                 :             : 
   23565                 :        4602 :   expand_float (out, in, 0);
   23566                 :             : 
   23567                 :        4602 :   emit_jump_insn (gen_jump (donelab));
   23568                 :        4602 :   emit_barrier ();
   23569                 :             : 
   23570                 :        4602 :   emit_label (neglab);
   23571                 :             : 
   23572                 :        4602 :   i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
   23573                 :             :                             1, OPTAB_DIRECT);
   23574                 :        4602 :   i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
   23575                 :             :                             1, OPTAB_DIRECT);
   23576                 :        4602 :   i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
   23577                 :             : 
   23578                 :        4602 :   expand_float (f0, i0, 0);
   23579                 :             : 
   23580                 :        4602 :   emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
   23581                 :             : 
   23582                 :        4602 :   emit_label (donelab);
   23583                 :        4602 : }
   23584                 :             : 
   23585                 :             : /* Return the diagnostic message string if conversion from FROMTYPE to
   23586                 :             :    TOTYPE is not allowed, NULL otherwise.  */
   23587                 :             : 
   23588                 :             : static const char *
   23589                 :   843536865 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
   23590                 :             : {
   23591                 :   843536865 :   machine_mode from_mode = element_mode (fromtype);
   23592                 :   843536865 :   machine_mode to_mode = element_mode (totype);
   23593                 :             : 
   23594                 :   843536865 :   if (!TARGET_SSE2 && from_mode != to_mode)
   23595                 :             :     {
   23596                 :             :       /* Do no allow conversions to/from BFmode/HFmode scalar types
   23597                 :             :          when TARGET_SSE2 is not available.  */
   23598                 :      524200 :       if (from_mode == BFmode)
   23599                 :             :         return N_("invalid conversion from type %<__bf16%> "
   23600                 :             :                   "without option %<-msse2%>");
   23601                 :      524199 :       if (from_mode == HFmode)
   23602                 :             :         return N_("invalid conversion from type %<_Float16%> "
   23603                 :             :                   "without option %<-msse2%>");
   23604                 :      524199 :       if (to_mode == BFmode)
   23605                 :             :         return N_("invalid conversion to type %<__bf16%> "
   23606                 :             :                   "without option %<-msse2%>");
   23607                 :      524199 :       if (to_mode == HFmode)
   23608                 :             :         return N_("invalid conversion to type %<_Float16%> "
   23609                 :             :                   "without option %<-msse2%>");
   23610                 :             :     }
   23611                 :             : 
   23612                 :             :   /* Warn for silent implicit conversion between __bf16 and short,
   23613                 :             :      since __bfloat16 is refined as real __bf16 instead of short
   23614                 :             :      since GCC13.  */
   23615                 :   843536863 :   if (element_mode (fromtype) != element_mode (totype)
   23616                 :   843536863 :       && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
   23617                 :             :     {
   23618                 :             :       /* Warn for silent implicit conversion where user may expect
   23619                 :             :          a bitcast.  */
   23620                 :      879633 :       if ((TYPE_MODE (fromtype) == BFmode
   23621                 :           4 :            && TYPE_MODE (totype) == HImode)
   23622                 :      879636 :           || (TYPE_MODE (totype) == BFmode
   23623                 :           2 :               && TYPE_MODE (fromtype) == HImode))
   23624                 :           1 :         warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
   23625                 :             :                 "to real %<__bf16%> since GCC 13.1, be careful of "
   23626                 :             :                  "implicit conversion between %<__bf16%> and %<short%>; "
   23627                 :             :                  "an explicit bitcast may be needed here");
   23628                 :             :     }
   23629                 :             : 
   23630                 :             :   /* Conversion allowed.  */
   23631                 :             :   return NULL;
   23632                 :             : }
   23633                 :             : 
   23634                 :             : /* Return the diagnostic message string if the unary operation OP is
   23635                 :             :    not permitted on TYPE, NULL otherwise.  */
   23636                 :             : 
   23637                 :             : static const char *
   23638                 :    77011277 : ix86_invalid_unary_op (int op, const_tree type)
   23639                 :             : {
   23640                 :    77011277 :   machine_mode mmode = element_mode (type);
   23641                 :             :   /* Reject all single-operand operations on BFmode/HFmode except for &
   23642                 :             :      when TARGET_SSE2 is not available.  */
   23643                 :    77011277 :   if (!TARGET_SSE2 && op != ADDR_EXPR)
   23644                 :             :     {
   23645                 :      107089 :       if (mmode == BFmode)
   23646                 :             :         return N_("operation not permitted on type %<__bf16%> "
   23647                 :             :                   "without option %<-msse2%>");
   23648                 :      107089 :       if (mmode == HFmode)
   23649                 :           0 :         return N_("operation not permitted on type %<_Float16%> "
   23650                 :             :                   "without option %<-msse2%>");
   23651                 :             :     }
   23652                 :             : 
   23653                 :             :   /* Operation allowed.  */
   23654                 :             :   return NULL;
   23655                 :             : }
   23656                 :             : 
   23657                 :             : /* Return the diagnostic message string if the binary operation OP is
   23658                 :             :    not permitted on TYPE1 and TYPE2, NULL otherwise.  */
   23659                 :             : 
   23660                 :             : static const char *
   23661                 :   126203614 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
   23662                 :             :                         const_tree type2)
   23663                 :             : {
   23664                 :   126203614 :   machine_mode type1_mode = element_mode (type1);
   23665                 :   126203614 :   machine_mode type2_mode = element_mode (type2);
   23666                 :             :   /* Reject all 2-operand operations on BFmode or HFmode
   23667                 :             :      when TARGET_SSE2 is not available.  */
   23668                 :   126203614 :   if (!TARGET_SSE2)
   23669                 :             :     {
   23670                 :      973568 :       if (type1_mode == BFmode || type2_mode == BFmode)
   23671                 :             :         return N_("operation not permitted on type %<__bf16%> "
   23672                 :             :                   "without option %<-msse2%>");
   23673                 :             : 
   23674                 :      973568 :       if (type1_mode == HFmode || type2_mode == HFmode)
   23675                 :           0 :         return N_("operation not permitted on type %<_Float16%> "
   23676                 :             :                   "without option %<-msse2%>");
   23677                 :             :     }
   23678                 :             : 
   23679                 :             :   /* Operation allowed.  */
   23680                 :             :   return NULL;
   23681                 :             : }
   23682                 :             : 
   23683                 :             : 
   23684                 :             : /* Target hook for scalar_mode_supported_p.  */
   23685                 :             : static bool
   23686                 :     4240115 : ix86_scalar_mode_supported_p (scalar_mode mode)
   23687                 :             : {
   23688                 :     4240115 :   if (DECIMAL_FLOAT_MODE_P (mode))
   23689                 :      620567 :     return default_decimal_float_supported_p ();
   23690                 :     3619548 :   else if (mode == TFmode)
   23691                 :             :     return true;
   23692                 :     3307365 :   else if (mode == HFmode || mode == BFmode)
   23693                 :             :     return true;
   23694                 :             :   else
   23695                 :     2684982 :     return default_scalar_mode_supported_p (mode);
   23696                 :             : }
   23697                 :             : 
   23698                 :             : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
   23699                 :             :    if MODE is HFmode, and punt to the generic implementation otherwise.  */
   23700                 :             : 
   23701                 :             : static bool
   23702                 :     2144462 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
   23703                 :             : {
   23704                 :             :   /* NB: Always return TRUE for HFmode so that the _Float16 type will
   23705                 :             :      be defined by the C front-end for AVX512FP16 intrinsics.  We will
   23706                 :             :      issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
   23707                 :             :      enabled.  */
   23708                 :     1833746 :   return ((mode == HFmode || mode == BFmode)
   23709                 :     3667492 :           ? true
   23710                 :     1523030 :           : default_libgcc_floating_mode_supported_p (mode));
   23711                 :             : }
   23712                 :             : 
   23713                 :             : /* Implements target hook vector_mode_supported_p.  */
   23714                 :             : static bool
   23715                 :  1457486285 : ix86_vector_mode_supported_p (machine_mode mode)
   23716                 :             : {
   23717                 :             :   /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
   23718                 :             :      either.  */
   23719                 :  1626771208 :   if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
   23720                 :             :     return false;
   23721                 :  1457486041 :   if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   23722                 :             :     return true;
   23723                 :  1250652326 :   if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   23724                 :             :     return true;
   23725                 :   449250602 :   if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   23726                 :             :     return true;
   23727                 :   327771556 :   if (TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
   23728                 :             :     return true;
   23729                 :   218261811 :   if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   23730                 :   218200202 :       && VALID_MMX_REG_MODE (mode))
   23731                 :             :     return true;
   23732                 :    26511667 :   if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
   23733                 :    25902166 :       && VALID_MMX_REG_MODE_3DNOW (mode))
   23734                 :             :     return true;
   23735                 :    18040476 :   if (mode == V2QImode)
   23736                 :             :     return true;
   23737                 :             :   return false;
   23738                 :             : }
   23739                 :             : 
   23740                 :             : /* Target hook for c_mode_for_suffix.  */
   23741                 :             : static machine_mode
   23742                 :       74438 : ix86_c_mode_for_suffix (char suffix)
   23743                 :             : {
   23744                 :       74438 :   if (suffix == 'q')
   23745                 :             :     return TFmode;
   23746                 :          38 :   if (suffix == 'w')
   23747                 :             :     return XFmode;
   23748                 :             : 
   23749                 :           0 :   return VOIDmode;
   23750                 :             : }
   23751                 :             : 
   23752                 :             : /* Helper function to map common constraints to non-EGPR ones.
   23753                 :             :    All related constraints have h prefix, and h plus Upper letter
   23754                 :             :    means the constraint is strictly EGPR enabled, while h plus
   23755                 :             :    lower letter indicates the constraint is strictly gpr16 only.
   23756                 :             : 
   23757                 :             :    Specially for "g" constraint, split it to rmi as there is
   23758                 :             :    no corresponding general constraint define for backend.
   23759                 :             : 
   23760                 :             :    Here is the full list to map constraints that may involve
   23761                 :             :    gpr to h prefixed.
   23762                 :             : 
   23763                 :             :    "g" -> "jrjmi"
   23764                 :             :    "r" -> "jr"
   23765                 :             :    "m" -> "jm"
   23766                 :             :    "<" -> "j<"
   23767                 :             :    ">" -> "j>"
   23768                 :             :    "o" -> "jo"
   23769                 :             :    "V" -> "jV"
   23770                 :             :    "p" -> "jp"
   23771                 :             :    "Bm" -> "ja"
   23772                 :             : */
   23773                 :             : 
   23774                 :          13 : static void map_egpr_constraints (vec<const char *> &constraints)
   23775                 :             : {
   23776                 :          46 :   for (size_t i = 0; i < constraints.length(); i++)
   23777                 :             :     {
   23778                 :          10 :       const char *cur = constraints[i];
   23779                 :             : 
   23780                 :          10 :       if (startswith (cur, "=@cc"))
   23781                 :           0 :         continue;
   23782                 :             : 
   23783                 :          10 :       int len = strlen (cur);
   23784                 :          10 :       auto_vec<char> buf;
   23785                 :             : 
   23786                 :          24 :       for (int j = 0; j < len; j++)
   23787                 :             :         {
   23788                 :          14 :           switch (cur[j])
   23789                 :             :             {
   23790                 :           2 :             case 'g':
   23791                 :           2 :               buf.safe_push ('j');
   23792                 :           2 :               buf.safe_push ('r');
   23793                 :           2 :               buf.safe_push ('j');
   23794                 :           2 :               buf.safe_push ('m');
   23795                 :           2 :               buf.safe_push ('i');
   23796                 :           2 :               break;
   23797                 :           8 :             case 'r':
   23798                 :           8 :             case 'm':
   23799                 :           8 :             case '<':
   23800                 :           8 :             case '>':
   23801                 :           8 :             case 'o':
   23802                 :           8 :             case 'V':
   23803                 :           8 :             case 'p':
   23804                 :           8 :               buf.safe_push ('j');
   23805                 :           8 :               buf.safe_push (cur[j]);
   23806                 :           8 :               break;
   23807                 :           0 :             case 'B':
   23808                 :           0 :               if (cur[j + 1] == 'm')
   23809                 :             :                 {
   23810                 :           0 :                   buf.safe_push ('j');
   23811                 :           0 :                   buf.safe_push ('a');
   23812                 :           0 :                   j++;
   23813                 :             :                 }
   23814                 :             :               else
   23815                 :             :                 {
   23816                 :           0 :                   buf.safe_push (cur[j]);
   23817                 :           0 :                   buf.safe_push (cur[j + 1]);
   23818                 :           0 :                   j++;
   23819                 :             :                 }
   23820                 :             :               break;
   23821                 :           0 :             case 'T':
   23822                 :           0 :             case 'Y':
   23823                 :           0 :             case 'W':
   23824                 :           0 :             case 'j':
   23825                 :           0 :               buf.safe_push (cur[j]);
   23826                 :           0 :               buf.safe_push (cur[j + 1]);
   23827                 :           0 :               j++;
   23828                 :           0 :               break;
   23829                 :           4 :             default:
   23830                 :           4 :               buf.safe_push (cur[j]);
   23831                 :           4 :               break;
   23832                 :             :             }
   23833                 :             :         }
   23834                 :          10 :       buf.safe_push ('\0');
   23835                 :          20 :       constraints[i] = xstrdup (buf.address ());
   23836                 :          10 :     }
   23837                 :          13 : }
   23838                 :             : 
   23839                 :             : /* Worker function for TARGET_MD_ASM_ADJUST.
   23840                 :             : 
   23841                 :             :    We implement asm flag outputs, and maintain source compatibility
   23842                 :             :    with the old cc0-based compiler.  */
   23843                 :             : 
   23844                 :             : static rtx_insn *
   23845                 :      113397 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
   23846                 :             :                     vec<machine_mode> & /*input_modes*/,
   23847                 :             :                     vec<const char *> &constraints, vec<rtx> &/*uses*/,
   23848                 :             :                     vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
   23849                 :             :                     location_t loc)
   23850                 :             : {
   23851                 :      113397 :   bool saw_asm_flag = false;
   23852                 :             : 
   23853                 :      113397 :   start_sequence ();
   23854                 :             : 
   23855                 :      113397 :   if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
   23856                 :          13 :     map_egpr_constraints (constraints);
   23857                 :             : 
   23858                 :      317610 :   for (unsigned i = 0, n = outputs.length (); i < n; ++i)
   23859                 :             :     {
   23860                 :       91538 :       const char *con = constraints[i];
   23861                 :       91538 :       if (!startswith (con, "=@cc"))
   23862                 :       91450 :         continue;
   23863                 :          88 :       con += 4;
   23864                 :          88 :       if (strchr (con, ',') != NULL)
   23865                 :             :         {
   23866                 :           1 :           error_at (loc, "alternatives not allowed in %<asm%> flag output");
   23867                 :           1 :           continue;
   23868                 :             :         }
   23869                 :             : 
   23870                 :          87 :       bool invert = false;
   23871                 :          87 :       if (con[0] == 'n')
   23872                 :          19 :         invert = true, con++;
   23873                 :             : 
   23874                 :          87 :       machine_mode mode = CCmode;
   23875                 :          87 :       rtx_code code = UNKNOWN;
   23876                 :             : 
   23877                 :          87 :       switch (con[0])
   23878                 :             :         {
   23879                 :          15 :         case 'a':
   23880                 :          15 :           if (con[1] == 0)
   23881                 :             :             mode = CCAmode, code = EQ;
   23882                 :           4 :           else if (con[1] == 'e' && con[2] == 0)
   23883                 :             :             mode = CCCmode, code = NE;
   23884                 :             :           break;
   23885                 :          11 :         case 'b':
   23886                 :          11 :           if (con[1] == 0)
   23887                 :             :             mode = CCCmode, code = EQ;
   23888                 :           6 :           else if (con[1] == 'e' && con[2] == 0)
   23889                 :             :             mode = CCAmode, code = NE;
   23890                 :             :           break;
   23891                 :          14 :         case 'c':
   23892                 :          14 :           if (con[1] == 0)
   23893                 :             :             mode = CCCmode, code = EQ;
   23894                 :             :           break;
   23895                 :           9 :         case 'e':
   23896                 :           9 :           if (con[1] == 0)
   23897                 :             :             mode = CCZmode, code = EQ;
   23898                 :             :           break;
   23899                 :          11 :         case 'g':
   23900                 :          11 :           if (con[1] == 0)
   23901                 :             :             mode = CCGCmode, code = GT;
   23902                 :           5 :           else if (con[1] == 'e' && con[2] == 0)
   23903                 :             :             mode = CCGCmode, code = GE;
   23904                 :             :           break;
   23905                 :          10 :         case 'l':
   23906                 :          10 :           if (con[1] == 0)
   23907                 :             :             mode = CCGCmode, code = LT;
   23908                 :           5 :           else if (con[1] == 'e' && con[2] == 0)
   23909                 :             :             mode = CCGCmode, code = LE;
   23910                 :             :           break;
   23911                 :           4 :         case 'o':
   23912                 :           4 :           if (con[1] == 0)
   23913                 :             :             mode = CCOmode, code = EQ;
   23914                 :             :           break;
   23915                 :           4 :         case 'p':
   23916                 :           4 :           if (con[1] == 0)
   23917                 :             :             mode = CCPmode, code = EQ;
   23918                 :             :           break;
   23919                 :           4 :         case 's':
   23920                 :           4 :           if (con[1] == 0)
   23921                 :             :             mode = CCSmode, code = EQ;
   23922                 :             :           break;
   23923                 :           5 :         case 'z':
   23924                 :           5 :           if (con[1] == 0)
   23925                 :             :             mode = CCZmode, code = EQ;
   23926                 :             :           break;
   23927                 :             :         }
   23928                 :           1 :       if (code == UNKNOWN)
   23929                 :             :         {
   23930                 :           1 :           error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
   23931                 :           1 :           continue;
   23932                 :             :         }
   23933                 :          86 :       if (invert)
   23934                 :          19 :         code = reverse_condition (code);
   23935                 :             : 
   23936                 :          86 :       rtx dest = outputs[i];
   23937                 :          86 :       if (!saw_asm_flag)
   23938                 :             :         {
   23939                 :             :           /* This is the first asm flag output.  Here we put the flags
   23940                 :             :              register in as the real output and adjust the condition to
   23941                 :             :              allow it.  */
   23942                 :          75 :           constraints[i] = "=Bf";
   23943                 :          75 :           outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
   23944                 :          75 :           saw_asm_flag = true;
   23945                 :             :         }
   23946                 :             :       else
   23947                 :             :         {
   23948                 :             :           /* We don't need the flags register as output twice.  */
   23949                 :          11 :           constraints[i] = "=X";
   23950                 :          11 :           outputs[i] = gen_rtx_SCRATCH (SImode);
   23951                 :             :         }
   23952                 :             : 
   23953                 :          86 :       rtx x = gen_rtx_REG (mode, FLAGS_REG);
   23954                 :          86 :       x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
   23955                 :             : 
   23956                 :          86 :       machine_mode dest_mode = GET_MODE (dest);
   23957                 :          86 :       if (!SCALAR_INT_MODE_P (dest_mode))
   23958                 :             :         {
   23959                 :           3 :           error_at (loc, "invalid type for %<asm%> flag output");
   23960                 :           3 :           continue;
   23961                 :             :         }
   23962                 :             : 
   23963                 :          83 :       if (dest_mode == QImode)
   23964                 :          73 :         emit_insn (gen_rtx_SET (dest, x));
   23965                 :             :       else
   23966                 :             :         {
   23967                 :          10 :           rtx reg = gen_reg_rtx (QImode);
   23968                 :          10 :           emit_insn (gen_rtx_SET (reg, x));
   23969                 :             : 
   23970                 :          10 :           reg = convert_to_mode (dest_mode, reg, 1);
   23971                 :          10 :           emit_move_insn (dest, reg);
   23972                 :             :         }
   23973                 :             :     }
   23974                 :             : 
   23975                 :      113397 :   rtx_insn *seq = get_insns ();
   23976                 :      113397 :   end_sequence ();
   23977                 :             : 
   23978                 :      113397 :   if (saw_asm_flag)
   23979                 :             :     return seq;
   23980                 :             :   else
   23981                 :             :     {
   23982                 :             :       /* If we had no asm flag outputs, clobber the flags.  */
   23983                 :      113322 :       clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
   23984                 :      113322 :       SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
   23985                 :      113322 :       return NULL;
   23986                 :             :     }
   23987                 :             : }
   23988                 :             : 
   23989                 :             : /* Implements target vector targetm.asm.encode_section_info.  */
   23990                 :             : 
   23991                 :             : static void ATTRIBUTE_UNUSED
   23992                 :     9625302 : ix86_encode_section_info (tree decl, rtx rtl, int first)
   23993                 :             : {
   23994                 :     9625302 :   default_encode_section_info (decl, rtl, first);
   23995                 :             : 
   23996                 :     9625302 :   if (ix86_in_large_data_p (decl))
   23997                 :          36 :     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
   23998                 :     9625302 : }
   23999                 :             : 
   24000                 :             : /* Worker function for REVERSE_CONDITION.  */
   24001                 :             : 
   24002                 :             : enum rtx_code
   24003                 :    27522514 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
   24004                 :             : {
   24005                 :    27522514 :   return (mode == CCFPmode
   24006                 :    27522514 :           ? reverse_condition_maybe_unordered (code)
   24007                 :    23430116 :           : reverse_condition (code));
   24008                 :             : }
   24009                 :             : 
   24010                 :             : /* Output code to perform an x87 FP register move, from OPERANDS[1]
   24011                 :             :    to OPERANDS[0].  */
   24012                 :             : 
   24013                 :             : const char *
   24014                 :      663611 : output_387_reg_move (rtx_insn *insn, rtx *operands)
   24015                 :             : {
   24016                 :      663611 :   if (REG_P (operands[0]))
   24017                 :             :     {
   24018                 :      554946 :       if (REG_P (operands[1])
   24019                 :      554946 :           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   24020                 :             :         {
   24021                 :      303004 :           if (REGNO (operands[0]) == FIRST_STACK_REG)
   24022                 :      282177 :             return output_387_ffreep (operands, 0);
   24023                 :             :           return "fstp\t%y0";
   24024                 :             :         }
   24025                 :      251942 :       if (STACK_TOP_P (operands[0]))
   24026                 :      251942 :         return "fld%Z1\t%y1";
   24027                 :             :       return "fst\t%y0";
   24028                 :             :     }
   24029                 :      108665 :   else if (MEM_P (operands[0]))
   24030                 :             :     {
   24031                 :      108665 :       gcc_assert (REG_P (operands[1]));
   24032                 :      108665 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   24033                 :             :         return "fstp%Z0\t%y0";
   24034                 :             :       else
   24035                 :             :         {
   24036                 :             :           /* There is no non-popping store to memory for XFmode.
   24037                 :             :              So if we need one, follow the store with a load.  */
   24038                 :        6264 :           if (GET_MODE (operands[0]) == XFmode)
   24039                 :             :             return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
   24040                 :             :           else
   24041                 :        1912 :             return "fst%Z0\t%y0";
   24042                 :             :         }
   24043                 :             :     }
   24044                 :             :   else
   24045                 :           0 :     gcc_unreachable();
   24046                 :             : }
   24047                 :             : #ifdef TARGET_SOLARIS
   24048                 :             : /* Solaris implementation of TARGET_ASM_NAMED_SECTION.  */
   24049                 :             : 
   24050                 :             : static void
   24051                 :             : i386_solaris_elf_named_section (const char *name, unsigned int flags,
   24052                 :             :                                 tree decl)
   24053                 :             : {
   24054                 :             :   /* With Binutils 2.15, the "@unwind" marker must be specified on
   24055                 :             :      every occurrence of the ".eh_frame" section, not just the first
   24056                 :             :      one.  */
   24057                 :             :   if (TARGET_64BIT
   24058                 :             :       && strcmp (name, ".eh_frame") == 0)
   24059                 :             :     {
   24060                 :             :       fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
   24061                 :             :                flags & SECTION_WRITE ? "aw" : "a");
   24062                 :             :       return;
   24063                 :             :     }
   24064                 :             : 
   24065                 :             : #ifndef USE_GAS
   24066                 :             :   if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
   24067                 :             :     {
   24068                 :             :       solaris_elf_asm_comdat_section (name, flags, decl);
   24069                 :             :       return;
   24070                 :             :     }
   24071                 :             : 
   24072                 :             :   /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
   24073                 :             :      SPARC assembler.  One cannot mix single-letter flags and #exclude, so
   24074                 :             :      only emit the latter here.  */
   24075                 :             :   if (flags & SECTION_EXCLUDE)
   24076                 :             :     {
   24077                 :             :       fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
   24078                 :             :       return;
   24079                 :             :     }
   24080                 :             : #endif
   24081                 :             : 
   24082                 :             :   default_elf_asm_named_section (name, flags, decl);
   24083                 :             : }
   24084                 :             : #endif /* TARGET_SOLARIS */
   24085                 :             : 
   24086                 :             : /* Return the mangling of TYPE if it is an extended fundamental type.  */
   24087                 :             : 
   24088                 :             : static const char *
   24089                 :   577244031 : ix86_mangle_type (const_tree type)
   24090                 :             : {
   24091                 :   577244031 :   type = TYPE_MAIN_VARIANT (type);
   24092                 :             : 
   24093                 :   577244031 :   if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
   24094                 :             :       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
   24095                 :             :     return NULL;
   24096                 :             : 
   24097                 :   307574925 :   if (type == float128_type_node || type == float64x_type_node)
   24098                 :             :     return NULL;
   24099                 :             : 
   24100                 :   306811743 :   switch (TYPE_MODE (type))
   24101                 :             :     {
   24102                 :             :     case E_BFmode:
   24103                 :             :       return "DF16b";
   24104                 :      268047 :     case E_HFmode:
   24105                 :             :       /* _Float16 is "DF16_".
   24106                 :             :          Align with clang's decision in https://reviews.llvm.org/D33719. */
   24107                 :      268047 :       return "DF16_";
   24108                 :      369097 :     case E_TFmode:
   24109                 :             :       /* __float128 is "g".  */
   24110                 :      369097 :       return "g";
   24111                 :     5466066 :     case E_XFmode:
   24112                 :             :       /* "long double" or __float80 is "e".  */
   24113                 :     5466066 :       return "e";
   24114                 :             :     default:
   24115                 :             :       return NULL;
   24116                 :             :     }
   24117                 :             : }
   24118                 :             : 
   24119                 :             : /* Create C++ tinfo symbols for only conditionally available fundamental
   24120                 :             :    types.  */
   24121                 :             : 
   24122                 :             : static void
   24123                 :           6 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
   24124                 :             : {
   24125                 :           6 :   extern tree ix86_float16_type_node;
   24126                 :           6 :   extern tree ix86_bf16_type_node;
   24127                 :             : 
   24128                 :           6 :   if (!TARGET_SSE2)
   24129                 :             :     {
   24130                 :           0 :       if (!float16_type_node)
   24131                 :           0 :         float16_type_node = ix86_float16_type_node;
   24132                 :           0 :       if (!bfloat16_type_node)
   24133                 :           0 :         bfloat16_type_node = ix86_bf16_type_node;
   24134                 :           0 :       callback (float16_type_node);
   24135                 :           0 :       callback (bfloat16_type_node);
   24136                 :           0 :       float16_type_node = NULL_TREE;
   24137                 :           0 :       bfloat16_type_node = NULL_TREE;
   24138                 :             :     }
   24139                 :           6 : }
   24140                 :             : 
   24141                 :             : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
   24142                 :             : 
   24143                 :             : static tree
   24144                 :         204 : ix86_stack_protect_guard (void)
   24145                 :             : {
   24146                 :         204 :   if (TARGET_SSP_TLS_GUARD)
   24147                 :             :     {
   24148                 :         204 :       tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
   24149                 :         204 :       int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
   24150                 :         204 :       tree type = build_qualified_type (type_node, qual);
   24151                 :         204 :       tree t;
   24152                 :             : 
   24153                 :         204 :       if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
   24154                 :             :         {
   24155                 :           1 :           t = ix86_tls_stack_chk_guard_decl;
   24156                 :             : 
   24157                 :           1 :           if (t == NULL)
   24158                 :             :             {
   24159                 :           1 :               rtx x;
   24160                 :             : 
   24161                 :           1 :               t = build_decl
   24162                 :           1 :                 (UNKNOWN_LOCATION, VAR_DECL,
   24163                 :             :                  get_identifier (ix86_stack_protector_guard_symbol_str),
   24164                 :             :                  type);
   24165                 :           1 :               TREE_STATIC (t) = 1;
   24166                 :           1 :               TREE_PUBLIC (t) = 1;
   24167                 :           1 :               DECL_EXTERNAL (t) = 1;
   24168                 :           1 :               TREE_USED (t) = 1;
   24169                 :           1 :               TREE_THIS_VOLATILE (t) = 1;
   24170                 :           1 :               DECL_ARTIFICIAL (t) = 1;
   24171                 :           1 :               DECL_IGNORED_P (t) = 1;
   24172                 :             : 
   24173                 :             :               /* Do not share RTL as the declaration is visible outside of
   24174                 :             :                  current function.  */
   24175                 :           1 :               x = DECL_RTL (t);
   24176                 :           1 :               RTX_FLAG (x, used) = 1;
   24177                 :             : 
   24178                 :           1 :               ix86_tls_stack_chk_guard_decl = t;
   24179                 :             :             }
   24180                 :             :         }
   24181                 :             :       else
   24182                 :             :         {
   24183                 :         203 :           tree asptrtype = build_pointer_type (type);
   24184                 :             : 
   24185                 :         203 :           t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
   24186                 :         203 :           t = build2 (MEM_REF, asptrtype, t,
   24187                 :         203 :                       build_int_cst (asptrtype, 0));
   24188                 :         203 :           TREE_THIS_VOLATILE (t) = 1;
   24189                 :             :         }
   24190                 :             : 
   24191                 :         204 :       return t;
   24192                 :             :     }
   24193                 :             : 
   24194                 :           0 :   return default_stack_protect_guard ();
   24195                 :             : }
   24196                 :             : 
   24197                 :             : /* For 32-bit code we can save PIC register setup by using
   24198                 :             :    __stack_chk_fail_local hidden function instead of calling
   24199                 :             :    __stack_chk_fail directly.  64-bit code doesn't need to setup any PIC
   24200                 :             :    register, so it is better to call __stack_chk_fail directly.  */
   24201                 :             : 
   24202                 :             : static tree ATTRIBUTE_UNUSED
   24203                 :         217 : ix86_stack_protect_fail (void)
   24204                 :             : {
   24205                 :         217 :   return TARGET_64BIT
   24206                 :         217 :          ? default_external_stack_protect_fail ()
   24207                 :           1 :          : default_hidden_stack_protect_fail ();
   24208                 :             : }
   24209                 :             : 
   24210                 :             : /* Select a format to encode pointers in exception handling data.  CODE
   24211                 :             :    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
   24212                 :             :    true if the symbol may be affected by dynamic relocations.
   24213                 :             : 
   24214                 :             :    ??? All x86 object file formats are capable of representing this.
   24215                 :             :    After all, the relocation needed is the same as for the call insn.
   24216                 :             :    Whether or not a particular assembler allows us to enter such, I
   24217                 :             :    guess we'll have to see.  */
   24218                 :             : 
   24219                 :             : int
   24220                 :      748738 : asm_preferred_eh_data_format (int code, int global)
   24221                 :             : {
   24222                 :             :   /* PE-COFF is effectively always -fPIC because of the .reloc section.  */
   24223                 :      748738 :   if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
   24224                 :             :     {
   24225                 :       36498 :       int type = DW_EH_PE_sdata8;
   24226                 :       36498 :       if (ptr_mode == SImode
   24227                 :       22996 :           || ix86_cmodel == CM_SMALL_PIC
   24228                 :       36568 :           || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
   24229                 :             :         type = DW_EH_PE_sdata4;
   24230                 :       51137 :       return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
   24231                 :             :     }
   24232                 :             : 
   24233                 :      712240 :   if (ix86_cmodel == CM_SMALL
   24234                 :       18498 :       || (ix86_cmodel == CM_MEDIUM && code))
   24235                 :      693753 :     return DW_EH_PE_udata4;
   24236                 :             : 
   24237                 :             :   return DW_EH_PE_absptr;
   24238                 :             : }
   24239                 :             : 
   24240                 :             : /* Implement targetm.vectorize.builtin_vectorization_cost.  */
   24241                 :             : static int
   24242                 :    12391523 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
   24243                 :             :                                  tree vectype, int)
   24244                 :             : {
   24245                 :    12391523 :   bool fp = false;
   24246                 :    12391523 :   machine_mode mode = TImode;
   24247                 :    12391523 :   int index;
   24248                 :    12391523 :   if (vectype != NULL)
   24249                 :             :     {
   24250                 :    11984986 :       fp = FLOAT_TYPE_P (vectype);
   24251                 :    11984986 :       mode = TYPE_MODE (vectype);
   24252                 :             :     }
   24253                 :             : 
   24254                 :    12391523 :   switch (type_of_cost)
   24255                 :             :     {
   24256                 :     1163913 :       case scalar_stmt:
   24257                 :     1163913 :         return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
   24258                 :             : 
   24259                 :     1355508 :       case scalar_load:
   24260                 :             :         /* load/store costs are relative to register move which is 2. Recompute
   24261                 :             :            it to COSTS_N_INSNS so everything have same base.  */
   24262                 :     2711016 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
   24263                 :     1355508 :                               : ix86_cost->int_load [2]) / 2;
   24264                 :             : 
   24265                 :     3960861 :       case scalar_store:
   24266                 :     7921722 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
   24267                 :     3960861 :                               : ix86_cost->int_store [2]) / 2;
   24268                 :             : 
   24269                 :      779811 :       case vector_stmt:
   24270                 :     1559622 :         return ix86_vec_cost (mode,
   24271                 :     1559622 :                               fp ? ix86_cost->addss : ix86_cost->sse_op);
   24272                 :             : 
   24273                 :     1118263 :       case vector_load:
   24274                 :     1118263 :         index = sse_store_index (mode);
   24275                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24276                 :     1118263 :         if (index < 0)
   24277                 :       86207 :           index = 2;
   24278                 :     1118263 :         return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
   24279                 :             : 
   24280                 :      832647 :       case vector_store:
   24281                 :      832647 :         index = sse_store_index (mode);
   24282                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24283                 :      832647 :         if (index < 0)
   24284                 :       83357 :           index = 2;
   24285                 :      832647 :         return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
   24286                 :             : 
   24287                 :     1167007 :       case vec_to_scalar:
   24288                 :     1167007 :       case scalar_to_vec:
   24289                 :     1167007 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   24290                 :             : 
   24291                 :             :       /* We should have separate costs for unaligned loads and gather/scatter.
   24292                 :             :          Do that incrementally.  */
   24293                 :      375453 :       case unaligned_load:
   24294                 :      375453 :         index = sse_store_index (mode);
   24295                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24296                 :      375453 :         if (index < 0)
   24297                 :        2425 :           index = 2;
   24298                 :      375453 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
   24299                 :             : 
   24300                 :      723479 :       case unaligned_store:
   24301                 :      723479 :         index = sse_store_index (mode);
   24302                 :             :         /* See PR82713 - we may end up being called on non-vector type.  */
   24303                 :      723479 :         if (index < 0)
   24304                 :       16193 :           index = 2;
   24305                 :      723479 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
   24306                 :             : 
   24307                 :           0 :       case vector_gather_load:
   24308                 :           0 :         return ix86_vec_cost (mode,
   24309                 :           0 :                               COSTS_N_INSNS
   24310                 :             :                                  (ix86_cost->gather_static
   24311                 :             :                                   + ix86_cost->gather_per_elt
   24312                 :           0 :                                     * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
   24313                 :             : 
   24314                 :           0 :       case vector_scatter_store:
   24315                 :           0 :         return ix86_vec_cost (mode,
   24316                 :           0 :                               COSTS_N_INSNS
   24317                 :             :                                  (ix86_cost->scatter_static
   24318                 :             :                                   + ix86_cost->scatter_per_elt
   24319                 :           0 :                                     * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
   24320                 :             : 
   24321                 :      119154 :       case cond_branch_taken:
   24322                 :      119154 :         return ix86_cost->cond_taken_branch_cost;
   24323                 :             : 
   24324                 :        2867 :       case cond_branch_not_taken:
   24325                 :        2867 :         return ix86_cost->cond_not_taken_branch_cost;
   24326                 :             : 
   24327                 :      217116 :       case vec_perm:
   24328                 :      217116 :       case vec_promote_demote:
   24329                 :      217116 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   24330                 :             : 
   24331                 :      575444 :       case vec_construct:
   24332                 :      575444 :         {
   24333                 :      575444 :           int n = TYPE_VECTOR_SUBPARTS (vectype);
   24334                 :             :           /* N - 1 element inserts into an SSE vector, the possible
   24335                 :             :              GPR -> XMM move is accounted for in add_stmt_cost.  */
   24336                 :     1150888 :           if (GET_MODE_BITSIZE (mode) <= 128)
   24337                 :      570185 :             return (n - 1) * ix86_cost->sse_op;
   24338                 :             :           /* One vinserti128 for combining two SSE vectors for AVX256.  */
   24339                 :       10518 :           else if (GET_MODE_BITSIZE (mode) == 256)
   24340                 :        4226 :             return ((n - 2) * ix86_cost->sse_op
   24341                 :        4226 :                     + ix86_vec_cost (mode, ix86_cost->addss));
   24342                 :             :           /* One vinserti64x4 and two vinserti128 for combining SSE
   24343                 :             :              and AVX256 vectors to AVX512.  */
   24344                 :        2066 :           else if (GET_MODE_BITSIZE (mode) == 512)
   24345                 :        1033 :             return ((n - 4) * ix86_cost->sse_op
   24346                 :        1033 :                     + 3 * ix86_vec_cost (mode, ix86_cost->addss));
   24347                 :           0 :           gcc_unreachable ();
   24348                 :             :         }
   24349                 :             : 
   24350                 :           0 :       default:
   24351                 :           0 :         gcc_unreachable ();
   24352                 :             :     }
   24353                 :             : }
   24354                 :             : 
   24355                 :             : 
   24356                 :             : /* This function returns the calling abi specific va_list type node.
   24357                 :             :    It returns  the FNDECL specific va_list type.  */
   24358                 :             : 
   24359                 :             : static tree
   24360                 :       46232 : ix86_fn_abi_va_list (tree fndecl)
   24361                 :             : {
   24362                 :       46232 :   if (!TARGET_64BIT)
   24363                 :         698 :     return va_list_type_node;
   24364                 :       45534 :   gcc_assert (fndecl != NULL_TREE);
   24365                 :             : 
   24366                 :       45534 :   if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
   24367                 :       12868 :     return ms_va_list_type_node;
   24368                 :             :   else
   24369                 :       32666 :     return sysv_va_list_type_node;
   24370                 :             : }
   24371                 :             : 
   24372                 :             : /* Returns the canonical va_list type specified by TYPE. If there
   24373                 :             :    is no valid TYPE provided, it return NULL_TREE.  */
   24374                 :             : 
   24375                 :             : static tree
   24376                 :      245260 : ix86_canonical_va_list_type (tree type)
   24377                 :             : {
   24378                 :      245260 :   if (TARGET_64BIT)
   24379                 :             :     {
   24380                 :      244758 :       if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
   24381                 :        5944 :         return ms_va_list_type_node;
   24382                 :             : 
   24383                 :      238814 :       if ((TREE_CODE (type) == ARRAY_TYPE
   24384                 :       49826 :            && integer_zerop (array_type_nelts (type)))
   24385                 :      238814 :           || POINTER_TYPE_P (type))
   24386                 :             :         {
   24387                 :      187276 :           tree elem_type = TREE_TYPE (type);
   24388                 :      187276 :           if (TREE_CODE (elem_type) == RECORD_TYPE
   24389                 :      338426 :               && lookup_attribute ("sysv_abi va_list",
   24390                 :      151150 :                                    TYPE_ATTRIBUTES (elem_type)))
   24391                 :      151150 :             return sysv_va_list_type_node;
   24392                 :             :         }
   24393                 :             : 
   24394                 :       87664 :       return NULL_TREE;
   24395                 :             :     }
   24396                 :             : 
   24397                 :         502 :   return std_canonical_va_list_type (type);
   24398                 :             : }
   24399                 :             : 
   24400                 :             : /* Iterate through the target-specific builtin types for va_list.
   24401                 :             :    IDX denotes the iterator, *PTREE is set to the result type of
   24402                 :             :    the va_list builtin, and *PNAME to its internal type.
   24403                 :             :    Returns zero if there is no element for this index, otherwise
   24404                 :             :    IDX should be increased upon the next call.
   24405                 :             :    Note, do not iterate a base builtin's name like __builtin_va_list.
   24406                 :             :    Used from c_common_nodes_and_builtins.  */
   24407                 :             : 
   24408                 :             : static int
   24409                 :      608939 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
   24410                 :             : {
   24411                 :      608939 :   if (TARGET_64BIT)
   24412                 :             :     {
   24413                 :      603849 :       switch (idx)
   24414                 :             :         {
   24415                 :             :         default:
   24416                 :             :           break;
   24417                 :             : 
   24418                 :      201283 :         case 0:
   24419                 :      201283 :           *ptree = ms_va_list_type_node;
   24420                 :      201283 :           *pname = "__builtin_ms_va_list";
   24421                 :      201283 :           return 1;
   24422                 :             : 
   24423                 :      201283 :         case 1:
   24424                 :      201283 :           *ptree = sysv_va_list_type_node;
   24425                 :      201283 :           *pname = "__builtin_sysv_va_list";
   24426                 :      201283 :           return 1;
   24427                 :             :         }
   24428                 :             :     }
   24429                 :             : 
   24430                 :             :   return 0;
   24431                 :             : }
   24432                 :             : 
   24433                 :             : #undef TARGET_SCHED_DISPATCH
   24434                 :             : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
   24435                 :             : #undef TARGET_SCHED_DISPATCH_DO
   24436                 :             : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
   24437                 :             : #undef TARGET_SCHED_REASSOCIATION_WIDTH
   24438                 :             : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
   24439                 :             : #undef TARGET_SCHED_REORDER
   24440                 :             : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
   24441                 :             : #undef TARGET_SCHED_ADJUST_PRIORITY
   24442                 :             : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
   24443                 :             : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
   24444                 :             : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
   24445                 :             :   ix86_dependencies_evaluation_hook
   24446                 :             : 
   24447                 :             : 
   24448                 :             : /* Implementation of reassociation_width target hook used by
   24449                 :             :    reassoc phase to identify parallelism level in reassociated
   24450                 :             :    tree.  Statements tree_code is passed in OPC.  Arguments type
   24451                 :             :    is passed in MODE.  */
   24452                 :             : 
   24453                 :             : static int
   24454                 :       22349 : ix86_reassociation_width (unsigned int op, machine_mode mode)
   24455                 :             : {
   24456                 :       22349 :   int width = 1;
   24457                 :             :   /* Vector part.  */
   24458                 :       22349 :   if (VECTOR_MODE_P (mode))
   24459                 :             :     {
   24460                 :        6621 :       int div = 1;
   24461                 :        6621 :       if (INTEGRAL_MODE_P (mode))
   24462                 :        2538 :         width = ix86_cost->reassoc_vec_int;
   24463                 :        4083 :       else if (FLOAT_MODE_P (mode))
   24464                 :        4083 :         width = ix86_cost->reassoc_vec_fp;
   24465                 :             : 
   24466                 :        6621 :       if (width == 1)
   24467                 :             :         return 1;
   24468                 :             : 
   24469                 :             :       /* Integer vector instructions execute in FP unit
   24470                 :             :          and can execute 3 additions and one multiplication per cycle.  */
   24471                 :        6597 :       if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
   24472                 :             :            || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4
   24473                 :        6597 :            || ix86_tune == PROCESSOR_ZNVER5)
   24474                 :           0 :           && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
   24475                 :             :         return 1;
   24476                 :             : 
   24477                 :             :       /* Account for targets that splits wide vectors into multiple parts.  */
   24478                 :        6597 :       if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
   24479                 :           0 :         div = GET_MODE_BITSIZE (mode) / 256;
   24480                 :        6597 :       else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
   24481                 :           0 :         div = GET_MODE_BITSIZE (mode) / 128;
   24482                 :        6597 :       else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
   24483                 :           0 :         div = GET_MODE_BITSIZE (mode) / 64;
   24484                 :        6597 :       width = (width + div - 1) / div;
   24485                 :        6597 :     }
   24486                 :             :   /* Scalar part.  */
   24487                 :             :   else if (INTEGRAL_MODE_P (mode))
   24488                 :       13224 :     width = ix86_cost->reassoc_int;
   24489                 :             :   else if (FLOAT_MODE_P (mode))
   24490                 :        2504 :     width = ix86_cost->reassoc_fp;
   24491                 :             : 
   24492                 :             :   /* Avoid using too many registers in 32bit mode.  */
   24493                 :       22325 :   if (!TARGET_64BIT && width > 2)
   24494                 :       22349 :     width = 2;
   24495                 :             :   return width;
   24496                 :             : }
   24497                 :             : 
   24498                 :             : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
   24499                 :             :    place emms and femms instructions.  */
   24500                 :             : 
   24501                 :             : static machine_mode
   24502                 :     4642351 : ix86_preferred_simd_mode (scalar_mode mode)
   24503                 :             : {
   24504                 :     4642351 :   if (!TARGET_SSE)
   24505                 :         848 :     return word_mode;
   24506                 :             : 
   24507                 :     4641503 :   switch (mode)
   24508                 :             :     {
   24509                 :      339788 :     case E_QImode:
   24510                 :      339788 :       if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24511                 :             :         return V64QImode;
   24512                 :      333726 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24513                 :             :         return V32QImode;
   24514                 :             :       else
   24515                 :      314124 :         return V16QImode;
   24516                 :             : 
   24517                 :      176637 :     case E_HImode:
   24518                 :      176637 :       if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24519                 :             :         return V32HImode;
   24520                 :      168201 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24521                 :             :         return V16HImode;
   24522                 :             :       else
   24523                 :      150867 :         return V8HImode;
   24524                 :             : 
   24525                 :     1399634 :     case E_SImode:
   24526                 :     1399634 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24527                 :             :         return V16SImode;
   24528                 :     1360321 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24529                 :             :         return V8SImode;
   24530                 :             :       else
   24531                 :     1200027 :         return V4SImode;
   24532                 :             : 
   24533                 :     1739377 :     case E_DImode:
   24534                 :     1739377 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24535                 :             :         return V8DImode;
   24536                 :     1471509 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24537                 :             :         return V4DImode;
   24538                 :             :       else
   24539                 :     1314316 :         return V2DImode;
   24540                 :             : 
   24541                 :      128972 :     case E_HFmode:
   24542                 :      128972 :       if (TARGET_AVX512FP16)
   24543                 :             :         {
   24544                 :      128439 :           if (TARGET_AVX512VL)
   24545                 :             :             {
   24546                 :       56262 :               if (TARGET_PREFER_AVX128)
   24547                 :             :                 return V8HFmode;
   24548                 :       56040 :               else if (TARGET_PREFER_AVX256 || !TARGET_EVEX512)
   24549                 :             :                 return V16HFmode;
   24550                 :             :             }
   24551                 :      102559 :           if (TARGET_EVEX512)
   24552                 :             :             return V32HFmode;
   24553                 :             :         }
   24554                 :        4263 :       return word_mode;
   24555                 :             : 
   24556                 :      544014 :     case E_SFmode:
   24557                 :      544014 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24558                 :             :         return V16SFmode;
   24559                 :      382874 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24560                 :             :         return V8SFmode;
   24561                 :             :       else
   24562                 :      304367 :         return V4SFmode;
   24563                 :             : 
   24564                 :      250579 :     case E_DFmode:
   24565                 :      250579 :       if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24566                 :             :         return V8DFmode;
   24567                 :      158454 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24568                 :             :         return V4DFmode;
   24569                 :       87797 :       else if (TARGET_SSE2)
   24570                 :             :         return V2DFmode;
   24571                 :             :       /* FALLTHRU */
   24572                 :             : 
   24573                 :       62558 :     default:
   24574                 :       62558 :       return word_mode;
   24575                 :             :     }
   24576                 :             : }
   24577                 :             : 
   24578                 :             : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
   24579                 :             :    vectors.  If AVX512F is enabled then try vectorizing with 512bit,
   24580                 :             :    256bit and 128bit vectors.  */
   24581                 :             : 
   24582                 :             : static unsigned int
   24583                 :     2176740 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
   24584                 :             : {
   24585                 :     2176740 :   if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
   24586                 :             :     {
   24587                 :       48553 :       modes->safe_push (V64QImode);
   24588                 :       48553 :       modes->safe_push (V32QImode);
   24589                 :       48553 :       modes->safe_push (V16QImode);
   24590                 :             :     }
   24591                 :     2128187 :   else if (TARGET_AVX512F && TARGET_EVEX512 && all)
   24592                 :             :     {
   24593                 :         555 :       modes->safe_push (V32QImode);
   24594                 :         555 :       modes->safe_push (V16QImode);
   24595                 :         555 :       modes->safe_push (V64QImode);
   24596                 :             :     }
   24597                 :     2127632 :   else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   24598                 :             :     {
   24599                 :       47390 :       modes->safe_push (V32QImode);
   24600                 :       47390 :       modes->safe_push (V16QImode);
   24601                 :             :     }
   24602                 :     2080242 :   else if (TARGET_AVX && all)
   24603                 :             :     {
   24604                 :          27 :       modes->safe_push (V16QImode);
   24605                 :          27 :       modes->safe_push (V32QImode);
   24606                 :             :     }
   24607                 :     2080215 :   else if (TARGET_SSE2)
   24608                 :     2077978 :     modes->safe_push (V16QImode);
   24609                 :             : 
   24610                 :     2176740 :   if (TARGET_MMX_WITH_SSE)
   24611                 :     1703437 :     modes->safe_push (V8QImode);
   24612                 :             : 
   24613                 :     2176740 :   if (TARGET_SSE2)
   24614                 :     2174503 :     modes->safe_push (V4QImode);
   24615                 :             : 
   24616                 :     2176740 :   return 0;
   24617                 :             : }
   24618                 :             : 
   24619                 :             : /* Implemenation of targetm.vectorize.get_mask_mode.  */
   24620                 :             : 
   24621                 :             : static opt_machine_mode
   24622                 :     1727705 : ix86_get_mask_mode (machine_mode data_mode)
   24623                 :             : {
   24624                 :     1727705 :   unsigned vector_size = GET_MODE_SIZE (data_mode);
   24625                 :     1727705 :   unsigned nunits = GET_MODE_NUNITS (data_mode);
   24626                 :     1727705 :   unsigned elem_size = vector_size / nunits;
   24627                 :             : 
   24628                 :             :   /* Scalar mask case.  */
   24629                 :      141083 :   if ((TARGET_AVX512F && TARGET_EVEX512 && vector_size == 64)
   24630                 :     1699742 :       || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
   24631                 :             :       /* AVX512FP16 only supports vector comparison
   24632                 :             :          to kmask for _Float16.  */
   24633                 :     3379990 :       || (TARGET_AVX512VL && TARGET_AVX512FP16
   24634                 :         562 :           && GET_MODE_INNER (data_mode) == E_HFmode))
   24635                 :             :     {
   24636                 :       75623 :       if (elem_size == 4
   24637                 :       75623 :           || elem_size == 8
   24638                 :       23963 :           || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
   24639                 :       67610 :         return smallest_int_mode_for_size (nunits);
   24640                 :             :     }
   24641                 :             : 
   24642                 :     1660095 :   scalar_int_mode elem_mode
   24643                 :     1660095 :     = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT);
   24644                 :             : 
   24645                 :     1660095 :   gcc_assert (elem_size * nunits == vector_size);
   24646                 :             : 
   24647                 :     1660095 :   return mode_for_vector (elem_mode, nunits);
   24648                 :             : }
   24649                 :             : 
   24650                 :             : 
   24651                 :             : 
   24652                 :             : /* Return class of registers which could be used for pseudo of MODE
   24653                 :             :    and of class RCLASS for spilling instead of memory.  Return NO_REGS
   24654                 :             :    if it is not possible or non-profitable.  */
   24655                 :             : 
   24656                 :             : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   24657                 :             : 
   24658                 :             : static reg_class_t
   24659                 :  6154635156 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
   24660                 :             : {
   24661                 :  6154635156 :   if (0 && TARGET_GENERAL_REGS_SSE_SPILL
   24662                 :             :       && TARGET_SSE2
   24663                 :             :       && TARGET_INTER_UNIT_MOVES_TO_VEC
   24664                 :             :       && TARGET_INTER_UNIT_MOVES_FROM_VEC
   24665                 :             :       && (mode == SImode || (TARGET_64BIT && mode == DImode))
   24666                 :             :       && INTEGER_CLASS_P (rclass))
   24667                 :             :     return ALL_SSE_REGS;
   24668                 :  6154635156 :   return NO_REGS;
   24669                 :             : }
   24670                 :             : 
   24671                 :             : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  Like the default implementation,
   24672                 :             :    but returns a lower bound.  */
   24673                 :             : 
   24674                 :             : static unsigned int
   24675                 :     1726971 : ix86_max_noce_ifcvt_seq_cost (edge e)
   24676                 :             : {
   24677                 :     1726971 :   bool predictable_p = predictable_edge_p (e);
   24678                 :     1726971 :   if (predictable_p)
   24679                 :             :     {
   24680                 :      133093 :       if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
   24681                 :           0 :         return param_max_rtl_if_conversion_predictable_cost;
   24682                 :             :     }
   24683                 :             :   else
   24684                 :             :     {
   24685                 :     1593878 :       if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
   24686                 :          92 :         return param_max_rtl_if_conversion_unpredictable_cost;
   24687                 :             :     }
   24688                 :             : 
   24689                 :     1726879 :   return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (2);
   24690                 :             : }
   24691                 :             : 
   24692                 :             : /* Return true if SEQ is a good candidate as a replacement for the
   24693                 :             :    if-convertible sequence described in IF_INFO.  */
   24694                 :             : 
   24695                 :             : static bool
   24696                 :      257160 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
   24697                 :             : {
   24698                 :      257160 :   if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
   24699                 :             :     {
   24700                 :             :       int cmov_cnt = 0;
   24701                 :             :       /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
   24702                 :             :          Maybe we should allow even more conditional moves as long as they
   24703                 :             :          are used far enough not to stall the CPU, or also consider
   24704                 :             :          IF_INFO->TEST_BB succ edge probabilities.  */
   24705                 :     1007604 :       for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
   24706                 :             :         {
   24707                 :      823666 :           rtx set = single_set (insn);
   24708                 :      823666 :           if (!set)
   24709                 :        2062 :             continue;
   24710                 :      821604 :           if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
   24711                 :      622165 :             continue;
   24712                 :      199439 :           rtx src = SET_SRC (set);
   24713                 :      199439 :           machine_mode mode = GET_MODE (src);
   24714                 :      199439 :           if (GET_MODE_CLASS (mode) != MODE_INT
   24715                 :       25196 :               && GET_MODE_CLASS (mode) != MODE_FLOAT)
   24716                 :           0 :             continue;
   24717                 :      199439 :           if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
   24718                 :      188208 :               || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
   24719                 :       12857 :             continue;
   24720                 :             :           /* insn is CMOV or FCMOV.  */
   24721                 :      186582 :           if (++cmov_cnt > 1)
   24722                 :             :             return false;
   24723                 :             :         }
   24724                 :             :     }
   24725                 :      241322 :   return default_noce_conversion_profitable_p (seq, if_info);
   24726                 :             : }
   24727                 :             : 
   24728                 :             : /* x86-specific vector costs.  */
   24729                 :             : class ix86_vector_costs : public vector_costs
   24730                 :             : {
   24731                 :             : public:
   24732                 :             :   ix86_vector_costs (vec_info *, bool);
   24733                 :             : 
   24734                 :             :   unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
   24735                 :             :                               stmt_vec_info stmt_info, slp_tree node,
   24736                 :             :                               tree vectype, int misalign,
   24737                 :             :                               vect_cost_model_location where) override;
   24738                 :             :   void finish_cost (const vector_costs *) override;
   24739                 :             : 
   24740                 :             : private:
   24741                 :             : 
   24742                 :             :   /* Estimate register pressure of the vectorized code.  */
   24743                 :             :   void ix86_vect_estimate_reg_pressure ();
   24744                 :             :   /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
   24745                 :             :      estimation of register pressure.
   24746                 :             :      ??? Currently it's only used by vec_construct/scalar_to_vec
   24747                 :             :      where we know it's not loaded from memory.  */
   24748                 :             :   unsigned m_num_gpr_needed[3];
   24749                 :             :   unsigned m_num_sse_needed[3];
   24750                 :             : };
   24751                 :             : 
   24752                 :     1587339 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
   24753                 :             :   : vector_costs (vinfo, costing_for_scalar),
   24754                 :     6349356 :     m_num_gpr_needed (),
   24755                 :     9524034 :     m_num_sse_needed ()
   24756                 :             : {
   24757                 :     1587339 : }
   24758                 :             : 
   24759                 :             : /* Implement targetm.vectorize.create_costs.  */
   24760                 :             : 
   24761                 :             : static vector_costs *
   24762                 :     1587339 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
   24763                 :             : {
   24764                 :     1587339 :   return new ix86_vector_costs (vinfo, costing_for_scalar);
   24765                 :             : }
   24766                 :             : 
   24767                 :             : unsigned
   24768                 :     5755457 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   24769                 :             :                                   stmt_vec_info stmt_info, slp_tree node,
   24770                 :             :                                   tree vectype, int misalign,
   24771                 :             :                                   vect_cost_model_location where)
   24772                 :             : {
   24773                 :     5755457 :   unsigned retval = 0;
   24774                 :     5755457 :   bool scalar_p
   24775                 :             :     = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
   24776                 :     5755457 :   int stmt_cost = - 1;
   24777                 :             : 
   24778                 :     5755457 :   bool fp = false;
   24779                 :     5755457 :   machine_mode mode = scalar_p ? SImode : TImode;
   24780                 :             : 
   24781                 :     5755457 :   if (vectype != NULL)
   24782                 :             :     {
   24783                 :     5589511 :       fp = FLOAT_TYPE_P (vectype);
   24784                 :     5589511 :       mode = TYPE_MODE (vectype);
   24785                 :     5589511 :       if (scalar_p)
   24786                 :     3150933 :         mode = TYPE_MODE (TREE_TYPE (vectype));
   24787                 :             :     }
   24788                 :             : 
   24789                 :     5755457 :   if ((kind == vector_stmt || kind == scalar_stmt)
   24790                 :     1053393 :       && stmt_info
   24791                 :     6805424 :       && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
   24792                 :             :     {
   24793                 :      888982 :       tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   24794                 :             :       /*machine_mode inner_mode = mode;
   24795                 :             :       if (VECTOR_MODE_P (mode))
   24796                 :             :         inner_mode = GET_MODE_INNER (mode);*/
   24797                 :             : 
   24798                 :      888982 :       switch (subcode)
   24799                 :             :         {
   24800                 :      419629 :         case PLUS_EXPR:
   24801                 :      419629 :         case POINTER_PLUS_EXPR:
   24802                 :      419629 :         case MINUS_EXPR:
   24803                 :      419629 :           if (kind == scalar_stmt)
   24804                 :             :             {
   24805                 :      274134 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   24806                 :       68067 :                 stmt_cost = ix86_cost->addss;
   24807                 :      206067 :               else if (X87_FLOAT_MODE_P (mode))
   24808                 :          62 :                 stmt_cost = ix86_cost->fadd;
   24809                 :             :               else
   24810                 :      206005 :                 stmt_cost = ix86_cost->add;
   24811                 :             :             }
   24812                 :             :           else
   24813                 :      145495 :             stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
   24814                 :             :                                        : ix86_cost->sse_op);
   24815                 :             :           break;
   24816                 :             : 
   24817                 :      156810 :         case MULT_EXPR:
   24818                 :             :           /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
   24819                 :             :              take it as MULT_EXPR.  */
   24820                 :      156810 :         case MULT_HIGHPART_EXPR:
   24821                 :      156810 :           stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   24822                 :      156810 :           break;
   24823                 :             :           /* There's no direct instruction for WIDEN_MULT_EXPR,
   24824                 :             :              take emulation into account.  */
   24825                 :        1460 :         case WIDEN_MULT_EXPR:
   24826                 :        2920 :           stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
   24827                 :        1460 :                                             TYPE_UNSIGNED (vectype));
   24828                 :        1460 :           break;
   24829                 :             : 
   24830                 :        6197 :         case NEGATE_EXPR:
   24831                 :        6197 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   24832                 :        1911 :             stmt_cost = ix86_cost->sse_op;
   24833                 :        4286 :           else if (X87_FLOAT_MODE_P (mode))
   24834                 :           0 :             stmt_cost = ix86_cost->fchs;
   24835                 :        4286 :           else if (VECTOR_MODE_P (mode))
   24836                 :        1899 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   24837                 :             :           else
   24838                 :        2387 :             stmt_cost = ix86_cost->add;
   24839                 :             :           break;
   24840                 :        7409 :         case TRUNC_DIV_EXPR:
   24841                 :        7409 :         case CEIL_DIV_EXPR:
   24842                 :        7409 :         case FLOOR_DIV_EXPR:
   24843                 :        7409 :         case ROUND_DIV_EXPR:
   24844                 :        7409 :         case TRUNC_MOD_EXPR:
   24845                 :        7409 :         case CEIL_MOD_EXPR:
   24846                 :        7409 :         case FLOOR_MOD_EXPR:
   24847                 :        7409 :         case RDIV_EXPR:
   24848                 :        7409 :         case ROUND_MOD_EXPR:
   24849                 :        7409 :         case EXACT_DIV_EXPR:
   24850                 :        7409 :           stmt_cost = ix86_division_cost (ix86_cost, mode);
   24851                 :        7409 :           break;
   24852                 :             : 
   24853                 :       37714 :         case RSHIFT_EXPR:
   24854                 :       37714 :         case LSHIFT_EXPR:
   24855                 :       37714 :         case LROTATE_EXPR:
   24856                 :       37714 :         case RROTATE_EXPR:
   24857                 :       37714 :           {
   24858                 :       37714 :             tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
   24859                 :       37714 :             tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
   24860                 :       37714 :             stmt_cost = ix86_shift_rotate_cost
   24861                 :       37714 :                            (ix86_cost,
   24862                 :             :                             (subcode == RSHIFT_EXPR
   24863                 :       24855 :                              && !TYPE_UNSIGNED (TREE_TYPE (op1)))
   24864                 :             :                             ? ASHIFTRT : LSHIFTRT, mode,
   24865                 :       37714 :                             TREE_CODE (op2) == INTEGER_CST,
   24866                 :       37714 :                             cst_and_fits_in_hwi (op2)
   24867                 :       24565 :                             ? int_cst_value (op2) : -1,
   24868                 :             :                             false, false, NULL, NULL);
   24869                 :             :           }
   24870                 :       37714 :           break;
   24871                 :       59577 :         case NOP_EXPR:
   24872                 :             :           /* Only sign-conversions are free.  */
   24873                 :       59577 :           if (tree_nop_conversion_p
   24874                 :       59577 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
   24875                 :       59577 :                  TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
   24876                 :     5755457 :             stmt_cost = 0;
   24877                 :             :           break;
   24878                 :             : 
   24879                 :      104387 :         case BIT_IOR_EXPR:
   24880                 :      104387 :         case ABS_EXPR:
   24881                 :      104387 :         case ABSU_EXPR:
   24882                 :      104387 :         case MIN_EXPR:
   24883                 :      104387 :         case MAX_EXPR:
   24884                 :      104387 :         case BIT_XOR_EXPR:
   24885                 :      104387 :         case BIT_AND_EXPR:
   24886                 :      104387 :         case BIT_NOT_EXPR:
   24887                 :      104387 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
   24888                 :         917 :             stmt_cost = ix86_cost->sse_op;
   24889                 :      103470 :           else if (VECTOR_MODE_P (mode))
   24890                 :       41232 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   24891                 :             :           else
   24892                 :       62238 :             stmt_cost = ix86_cost->add;
   24893                 :             :           break;
   24894                 :             :         default:
   24895                 :             :           break;
   24896                 :             :         }
   24897                 :             :     }
   24898                 :             : 
   24899                 :     5755457 :   combined_fn cfn;
   24900                 :     5755457 :   if ((kind == vector_stmt || kind == scalar_stmt)
   24901                 :     1053393 :       && stmt_info
   24902                 :     1049967 :       && stmt_info->stmt
   24903                 :     6805424 :       && (cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
   24904                 :       15453 :     switch (cfn)
   24905                 :             :       {
   24906                 :          28 :       case CFN_FMA:
   24907                 :          28 :         stmt_cost = ix86_vec_cost (mode,
   24908                 :          28 :                                    mode == SFmode ? ix86_cost->fmass
   24909                 :             :                                    : ix86_cost->fmasd);
   24910                 :          28 :         break;
   24911                 :          12 :       case CFN_MULH:
   24912                 :          12 :         stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   24913                 :          12 :         break;
   24914                 :             :       default:
   24915                 :             :         break;
   24916                 :             :       }
   24917                 :             : 
   24918                 :             :   /* If we do elementwise loads into a vector then we are bound by
   24919                 :             :      latency and execution resources for the many scalar loads
   24920                 :             :      (AGU and load ports).  Try to account for this by scaling the
   24921                 :             :      construction cost by the number of elements involved.  */
   24922                 :     5755457 :   if ((kind == vec_construct || kind == vec_to_scalar)
   24923                 :      518012 :       && stmt_info
   24924                 :      287063 :       && (STMT_VINFO_TYPE (stmt_info) == load_vec_info_type
   24925                 :      287063 :           || STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
   24926                 :      174672 :       && ((STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_ELEMENTWISE
   24927                 :      135644 :            && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
   24928                 :             :                != INTEGER_CST))
   24929                 :      144644 :           || STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER))
   24930                 :             :     {
   24931                 :       34748 :       stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   24932                 :       34748 :       stmt_cost *= (TYPE_VECTOR_SUBPARTS (vectype) + 1);
   24933                 :             :     }
   24934                 :     5720709 :   else if ((kind == vec_construct || kind == scalar_to_vec)
   24935                 :      479840 :            && node
   24936                 :      253119 :            && SLP_TREE_DEF_TYPE (node) == vect_external_def)
   24937                 :             :     {
   24938                 :      253119 :       stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   24939                 :      253119 :       unsigned i;
   24940                 :      253119 :       tree op;
   24941                 :     1100947 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   24942                 :      594709 :         if (TREE_CODE (op) == SSA_NAME)
   24943                 :      466159 :           TREE_VISITED (op) = 0;
   24944                 :     1100947 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   24945                 :             :         {
   24946                 :      757592 :           if (TREE_CODE (op) != SSA_NAME
   24947                 :      594709 :               || TREE_VISITED (op))
   24948                 :      162883 :             continue;
   24949                 :      431826 :           TREE_VISITED (op) = 1;
   24950                 :      431826 :           gimple *def = SSA_NAME_DEF_STMT (op);
   24951                 :      431826 :           tree tem;
   24952                 :      431826 :           if (is_gimple_assign (def)
   24953                 :      244015 :               && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
   24954                 :       29369 :               && ((tem = gimple_assign_rhs1 (def)), true)
   24955                 :       29369 :               && TREE_CODE (tem) == SSA_NAME
   24956                 :             :               /* A sign-change expands to nothing.  */
   24957                 :      461027 :               && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (def)),
   24958                 :       29201 :                                         TREE_TYPE (tem)))
   24959                 :        7621 :             def = SSA_NAME_DEF_STMT (tem);
   24960                 :             :           /* When the component is loaded from memory we can directly
   24961                 :             :              move it to a vector register, otherwise we have to go
   24962                 :             :              via a GPR or via vpinsr which involves similar cost.
   24963                 :             :              Likewise with a BIT_FIELD_REF extracting from a vector
   24964                 :             :              register we can hope to avoid using a GPR.  */
   24965                 :      431826 :           if (!is_gimple_assign (def)
   24966                 :      431826 :               || ((!gimple_assign_load_p (def)
   24967                 :      117146 :                    || (!TARGET_SSE4_1
   24968                 :      225608 :                        && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) == 1))
   24969                 :      128510 :                   && (gimple_assign_rhs_code (def) != BIT_FIELD_REF
   24970                 :        9684 :                       || !VECTOR_TYPE_P (TREE_TYPE
   24971                 :             :                                 (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))))
   24972                 :             :             {
   24973                 :      308113 :               if (fp)
   24974                 :       11594 :                 m_num_sse_needed[where]++;
   24975                 :             :               else
   24976                 :             :                 {
   24977                 :      296519 :                   m_num_gpr_needed[where]++;
   24978                 :      296519 :                   stmt_cost += ix86_cost->sse_to_integer;
   24979                 :             :                 }
   24980                 :             :             }
   24981                 :             :         }
   24982                 :      847828 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   24983                 :      594709 :         if (TREE_CODE (op) == SSA_NAME)
   24984                 :      466159 :           TREE_VISITED (op) = 0;
   24985                 :             :     }
   24986                 :     5755457 :   if (stmt_cost == -1)
   24987                 :     4733944 :     stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
   24988                 :             : 
   24989                 :             :   /* Penalize DFmode vector operations for Bonnell.  */
   24990                 :     5755457 :   if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
   24991                 :     5755517 :       && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
   24992                 :           8 :     stmt_cost *= 5;  /* FIXME: The value here is arbitrary.  */
   24993                 :             : 
   24994                 :             :   /* Statements in an inner loop relative to the loop being
   24995                 :             :      vectorized are weighted more heavily.  The value here is
   24996                 :             :      arbitrary and could potentially be improved with analysis.  */
   24997                 :     5755457 :   retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
   24998                 :             : 
   24999                 :             :   /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
   25000                 :             :      for Silvermont as it has out of order integer pipeline and can execute
   25001                 :             :      2 scalar instruction per tick, but has in order SIMD pipeline.  */
   25002                 :     5755457 :   if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
   25003                 :     5755457 :        || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
   25004                 :        2191 :       && stmt_info && stmt_info->stmt)
   25005                 :             :     {
   25006                 :        2099 :       tree lhs_op = gimple_get_lhs (stmt_info->stmt);
   25007                 :        2099 :       if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
   25008                 :        1655 :         retval = (retval * 17) / 10;
   25009                 :             :     }
   25010                 :             : 
   25011                 :     5755457 :   m_costs[where] += retval;
   25012                 :             : 
   25013                 :     5755457 :   return retval;
   25014                 :             : }
   25015                 :             : 
   25016                 :             : void
   25017                 :     1454004 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
   25018                 :             : {
   25019                 :     1454004 :   unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
   25020                 :     1454004 :   unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
   25021                 :             : 
   25022                 :             :   /* Any better way to have target available fp registers, currently use SSE_REGS.  */
   25023                 :     1454004 :   unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
   25024                 :     5816016 :   for (unsigned i = 0; i != 3; i++)
   25025                 :             :     {
   25026                 :     4362012 :       if (m_num_gpr_needed[i] > target_avail_regs)
   25027                 :         691 :         m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
   25028                 :             :       /* Only measure sse registers pressure.  */
   25029                 :     4362012 :       if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
   25030                 :         103 :         m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
   25031                 :             :     }
   25032                 :     1454004 : }
   25033                 :             : 
   25034                 :             : void
   25035                 :     1454004 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
   25036                 :             : {
   25037                 :     1454004 :   loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
   25038                 :      207888 :   if (loop_vinfo && !m_costing_for_scalar)
   25039                 :             :     {
   25040                 :             :       /* We are currently not asking the vectorizer to compare costs
   25041                 :             :          between different vector mode sizes.  When using predication
   25042                 :             :          that will end up always choosing the prefered mode size even
   25043                 :             :          if there's a smaller mode covering all lanes.  Test for this
   25044                 :             :          situation and artificially reject the larger mode attempt.
   25045                 :             :          ???  We currently lack masked ops for sub-SSE sized modes,
   25046                 :             :          so we could restrict this rejection to AVX and AVX512 modes
   25047                 :             :          but error on the safe side for now.  */
   25048                 :       37711 :       if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
   25049                 :           8 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   25050                 :           8 :           && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   25051                 :       37716 :           && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
   25052                 :          10 :               > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
   25053                 :           3 :         m_costs[vect_body] = INT_MAX;
   25054                 :             :     }
   25055                 :             : 
   25056                 :     1454004 :   ix86_vect_estimate_reg_pressure ();
   25057                 :             : 
   25058                 :     1454004 :   vector_costs::finish_cost (scalar_costs);
   25059                 :     1454004 : }
   25060                 :             : 
   25061                 :             : /* Validate target specific memory model bits in VAL. */
   25062                 :             : 
   25063                 :             : static unsigned HOST_WIDE_INT
   25064                 :      479938 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   25065                 :             : {
   25066                 :      479938 :   enum memmodel model = memmodel_from_int (val);
   25067                 :      479938 :   bool strong;
   25068                 :             : 
   25069                 :      479938 :   if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
   25070                 :             :                                       |MEMMODEL_MASK)
   25071                 :      479933 :       || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
   25072                 :             :     {
   25073                 :           5 :       warning (OPT_Winvalid_memory_model,
   25074                 :             :                "unknown architecture specific memory model");
   25075                 :           5 :       return MEMMODEL_SEQ_CST;
   25076                 :             :     }
   25077                 :      479933 :   strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
   25078                 :      479933 :   if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
   25079                 :             :     {
   25080                 :           0 :       warning (OPT_Winvalid_memory_model,
   25081                 :             :               "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
   25082                 :             :                "memory model");
   25083                 :           0 :       return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
   25084                 :             :     }
   25085                 :      479933 :   if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
   25086                 :             :     {
   25087                 :           0 :       warning (OPT_Winvalid_memory_model,
   25088                 :             :               "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
   25089                 :             :                "memory model");
   25090                 :           0 :       return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
   25091                 :             :     }
   25092                 :             :   return val;
   25093                 :             : }
   25094                 :             : 
   25095                 :             : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
   25096                 :             :    CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
   25097                 :             :    CLONEI->simdlen.  Return 0 if SIMD clones shouldn't be emitted,
   25098                 :             :    or number of vecsize_mangle variants that should be emitted.  */
   25099                 :             : 
   25100                 :             : static int
   25101                 :        8077 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
   25102                 :             :                                              struct cgraph_simd_clone *clonei,
   25103                 :             :                                              tree base_type, int num,
   25104                 :             :                                              bool explicit_p)
   25105                 :             : {
   25106                 :        8077 :   int ret = 1;
   25107                 :             : 
   25108                 :        8077 :   if (clonei->simdlen
   25109                 :        8077 :       && (clonei->simdlen < 2
   25110                 :        1361 :           || clonei->simdlen > 1024
   25111                 :        9438 :           || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
   25112                 :             :     {
   25113                 :           0 :       if (explicit_p)
   25114                 :           0 :         warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25115                 :             :                     "unsupported simdlen %wd", clonei->simdlen.to_constant ());
   25116                 :           0 :       return 0;
   25117                 :             :     }
   25118                 :             : 
   25119                 :        8077 :   tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
   25120                 :        8077 :   if (TREE_CODE (ret_type) != VOID_TYPE)
   25121                 :        7277 :     switch (TYPE_MODE (ret_type))
   25122                 :             :       {
   25123                 :        7277 :       case E_QImode:
   25124                 :        7277 :       case E_HImode:
   25125                 :        7277 :       case E_SImode:
   25126                 :        7277 :       case E_DImode:
   25127                 :        7277 :       case E_SFmode:
   25128                 :        7277 :       case E_DFmode:
   25129                 :             :       /* case E_SCmode: */
   25130                 :             :       /* case E_DCmode: */
   25131                 :        7277 :         if (!AGGREGATE_TYPE_P (ret_type))
   25132                 :             :           break;
   25133                 :             :         /* FALLTHRU */
   25134                 :           2 :       default:
   25135                 :           2 :         if (explicit_p)
   25136                 :           2 :           warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25137                 :             :                       "unsupported return type %qT for simd", ret_type);
   25138                 :           2 :         return 0;
   25139                 :             :       }
   25140                 :             : 
   25141                 :        8075 :   tree t;
   25142                 :        8075 :   int i;
   25143                 :        8075 :   tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
   25144                 :        8075 :   bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
   25145                 :             : 
   25146                 :        8075 :   for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
   25147                 :       22080 :        t && t != void_list_node; t = TREE_CHAIN (t), i++)
   25148                 :             :     {
   25149                 :       17900 :       tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
   25150                 :       14010 :       switch (TYPE_MODE (arg_type))
   25151                 :             :         {
   25152                 :       13989 :         case E_QImode:
   25153                 :       13989 :         case E_HImode:
   25154                 :       13989 :         case E_SImode:
   25155                 :       13989 :         case E_DImode:
   25156                 :       13989 :         case E_SFmode:
   25157                 :       13989 :         case E_DFmode:
   25158                 :             :         /* case E_SCmode: */
   25159                 :             :         /* case E_DCmode: */
   25160                 :       13989 :           if (!AGGREGATE_TYPE_P (arg_type))
   25161                 :             :             break;
   25162                 :             :           /* FALLTHRU */
   25163                 :          43 :         default:
   25164                 :          43 :           if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
   25165                 :             :             break;
   25166                 :           5 :           if (explicit_p)
   25167                 :           5 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25168                 :             :                         "unsupported argument type %qT for simd", arg_type);
   25169                 :             :           return 0;
   25170                 :             :         }
   25171                 :             :     }
   25172                 :             : 
   25173                 :        8070 :   if (!TREE_PUBLIC (node->decl) || !explicit_p)
   25174                 :             :     {
   25175                 :             :       /* If the function isn't exported, we can pick up just one ISA
   25176                 :             :          for the clones.  */
   25177                 :         118 :       if (TARGET_AVX512F && TARGET_EVEX512)
   25178                 :           0 :         clonei->vecsize_mangle = 'e';
   25179                 :         118 :       else if (TARGET_AVX2)
   25180                 :           1 :         clonei->vecsize_mangle = 'd';
   25181                 :         117 :       else if (TARGET_AVX)
   25182                 :          88 :         clonei->vecsize_mangle = 'c';
   25183                 :             :       else
   25184                 :          29 :         clonei->vecsize_mangle = 'b';
   25185                 :             :       ret = 1;
   25186                 :             :     }
   25187                 :             :   else
   25188                 :             :     {
   25189                 :        7952 :       clonei->vecsize_mangle = "bcde"[num];
   25190                 :        7952 :       ret = 4;
   25191                 :             :     }
   25192                 :        8070 :   clonei->mask_mode = VOIDmode;
   25193                 :        8070 :   switch (clonei->vecsize_mangle)
   25194                 :             :     {
   25195                 :        2017 :     case 'b':
   25196                 :        2017 :       clonei->vecsize_int = 128;
   25197                 :        2017 :       clonei->vecsize_float = 128;
   25198                 :        2017 :       break;
   25199                 :        2076 :     case 'c':
   25200                 :        2076 :       clonei->vecsize_int = 128;
   25201                 :        2076 :       clonei->vecsize_float = 256;
   25202                 :        2076 :       break;
   25203                 :        1989 :     case 'd':
   25204                 :        1989 :       clonei->vecsize_int = 256;
   25205                 :        1989 :       clonei->vecsize_float = 256;
   25206                 :        1989 :       break;
   25207                 :        1988 :     case 'e':
   25208                 :        1988 :       clonei->vecsize_int = 512;
   25209                 :        1988 :       clonei->vecsize_float = 512;
   25210                 :        1988 :       if (TYPE_MODE (base_type) == QImode)
   25211                 :          15 :         clonei->mask_mode = DImode;
   25212                 :             :       else
   25213                 :        1973 :         clonei->mask_mode = SImode;
   25214                 :             :       break;
   25215                 :             :     }
   25216                 :        8070 :   if (clonei->simdlen == 0)
   25217                 :             :     {
   25218                 :        6709 :       if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
   25219                 :        3653 :         clonei->simdlen = clonei->vecsize_int;
   25220                 :             :       else
   25221                 :        3056 :         clonei->simdlen = clonei->vecsize_float;
   25222                 :        6709 :       clonei->simdlen = clonei->simdlen
   25223                 :       13418 :                         / GET_MODE_BITSIZE (TYPE_MODE (base_type));
   25224                 :             :     }
   25225                 :        1361 :   else if (clonei->simdlen > 16)
   25226                 :             :     {
   25227                 :             :       /* For compatibility with ICC, use the same upper bounds
   25228                 :             :          for simdlen.  In particular, for CTYPE below, use the return type,
   25229                 :             :          unless the function returns void, in that case use the characteristic
   25230                 :             :          type.  If it is possible for given SIMDLEN to pass CTYPE value
   25231                 :             :          in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
   25232                 :             :          for 64-bit code), accept that SIMDLEN, otherwise warn and don't
   25233                 :             :          emit corresponding clone.  */
   25234                 :           0 :       tree ctype = ret_type;
   25235                 :           0 :       if (VOID_TYPE_P (ret_type))
   25236                 :           0 :         ctype = base_type;
   25237                 :           0 :       int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
   25238                 :           0 :       if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
   25239                 :           0 :         cnt /= clonei->vecsize_int;
   25240                 :             :       else
   25241                 :           0 :         cnt /= clonei->vecsize_float;
   25242                 :           0 :       if (cnt > (TARGET_64BIT ? 16 : 8))
   25243                 :             :         {
   25244                 :           0 :           if (explicit_p)
   25245                 :           0 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   25246                 :             :                         "unsupported simdlen %wd",
   25247                 :             :                         clonei->simdlen.to_constant ());
   25248                 :           0 :           return 0;
   25249                 :             :         }
   25250                 :             :       }
   25251                 :             :   return ret;
   25252                 :             : }
   25253                 :             : 
   25254                 :             : /* If SIMD clone NODE can't be used in a vectorized loop
   25255                 :             :    in current function, return -1, otherwise return a badness of using it
   25256                 :             :    (0 if it is most desirable from vecsize_mangle point of view, 1
   25257                 :             :    slightly less desirable, etc.).  */
   25258                 :             : 
   25259                 :             : static int
   25260                 :        1723 : ix86_simd_clone_usable (struct cgraph_node *node)
   25261                 :             : {
   25262                 :        1723 :   switch (node->simdclone->vecsize_mangle)
   25263                 :             :     {
   25264                 :         663 :     case 'b':
   25265                 :         663 :       if (!TARGET_SSE2)
   25266                 :             :         return -1;
   25267                 :         663 :       if (!TARGET_AVX)
   25268                 :             :         return 0;
   25269                 :         539 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 3 : TARGET_AVX2 ? 2 : 1;
   25270                 :         613 :     case 'c':
   25271                 :         613 :       if (!TARGET_AVX)
   25272                 :             :         return -1;
   25273                 :         572 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 2 : TARGET_AVX2 ? 1 : 0;
   25274                 :         295 :     case 'd':
   25275                 :         295 :       if (!TARGET_AVX2)
   25276                 :             :         return -1;
   25277                 :         107 :       return (TARGET_AVX512F && TARGET_EVEX512) ? 1 : 0;
   25278                 :         152 :     case 'e':
   25279                 :         152 :       if (!TARGET_AVX512F || !TARGET_EVEX512)
   25280                 :         117 :         return -1;
   25281                 :             :       return 0;
   25282                 :           0 :     default:
   25283                 :           0 :       gcc_unreachable ();
   25284                 :             :     }
   25285                 :             : }
   25286                 :             : 
   25287                 :             : /* This function adjusts the unroll factor based on
   25288                 :             :    the hardware capabilities. For ex, bdver3 has
   25289                 :             :    a loop buffer which makes unrolling of smaller
   25290                 :             :    loops less important. This function decides the
   25291                 :             :    unroll factor using number of memory references
   25292                 :             :    (value 32 is used) as a heuristic. */
   25293                 :             : 
   25294                 :             : static unsigned
   25295                 :      660357 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
   25296                 :             : {
   25297                 :      660357 :   basic_block *bbs;
   25298                 :      660357 :   rtx_insn *insn;
   25299                 :      660357 :   unsigned i;
   25300                 :      660357 :   unsigned mem_count = 0;
   25301                 :             : 
   25302                 :             :   /* Unroll small size loop when unroll factor is not explicitly
   25303                 :             :      specified.  */
   25304                 :      660357 :   if (ix86_unroll_only_small_loops && !loop->unroll)
   25305                 :             :     {
   25306                 :      622394 :       if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
   25307                 :       62762 :         return MIN (nunroll, ix86_cost->small_unroll_factor);
   25308                 :             :       else
   25309                 :             :         return 1;
   25310                 :             :     }
   25311                 :             : 
   25312                 :       37963 :   if (!TARGET_ADJUST_UNROLL)
   25313                 :             :      return nunroll;
   25314                 :             : 
   25315                 :             :   /* Count the number of memory references within the loop body.
   25316                 :             :      This value determines the unrolling factor for bdver3 and bdver4
   25317                 :             :      architectures. */
   25318                 :           7 :   subrtx_iterator::array_type array;
   25319                 :           7 :   bbs = get_loop_body (loop);
   25320                 :          21 :   for (i = 0; i < loop->num_nodes; i++)
   25321                 :         102 :     FOR_BB_INSNS (bbs[i], insn)
   25322                 :          88 :       if (NONDEBUG_INSN_P (insn))
   25323                 :         464 :         FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   25324                 :         404 :           if (const_rtx x = *iter)
   25325                 :         404 :             if (MEM_P (x))
   25326                 :             :               {
   25327                 :          25 :                 machine_mode mode = GET_MODE (x);
   25328                 :          50 :                 unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
   25329                 :          25 :                 if (n_words > 4)
   25330                 :           0 :                   mem_count += 2;
   25331                 :             :                 else
   25332                 :          25 :                   mem_count += 1;
   25333                 :             :               }
   25334                 :           7 :   free (bbs);
   25335                 :             : 
   25336                 :           7 :   if (mem_count && mem_count <=32)
   25337                 :           7 :     return MIN (nunroll, 32 / mem_count);
   25338                 :             : 
   25339                 :             :   return nunroll;
   25340                 :           7 : }
   25341                 :             : 
   25342                 :             : 
   25343                 :             : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P.  */
   25344                 :             : 
   25345                 :             : static bool
   25346                 :      411694 : ix86_float_exceptions_rounding_supported_p (void)
   25347                 :             : {
   25348                 :             :   /* For x87 floating point with standard excess precision handling,
   25349                 :             :      there is no adddf3 pattern (since x87 floating point only has
   25350                 :             :      XFmode operations) so the default hook implementation gets this
   25351                 :             :      wrong.  */
   25352                 :      411694 :   return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
   25353                 :             : }
   25354                 :             : 
   25355                 :             : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
   25356                 :             : 
   25357                 :             : static void
   25358                 :        7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   25359                 :             : {
   25360                 :        7054 :   if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
   25361                 :             :     return;
   25362                 :        7054 :   tree exceptions_var = create_tmp_var_raw (integer_type_node);
   25363                 :        7054 :   if (TARGET_80387)
   25364                 :             :     {
   25365                 :        7054 :       tree fenv_index_type = build_index_type (size_int (6));
   25366                 :        7054 :       tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
   25367                 :        7054 :       tree fenv_var = create_tmp_var_raw (fenv_type);
   25368                 :        7054 :       TREE_ADDRESSABLE (fenv_var) = 1;
   25369                 :        7054 :       tree fenv_ptr = build_pointer_type (fenv_type);
   25370                 :        7054 :       tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
   25371                 :        7054 :       fenv_addr = fold_convert (ptr_type_node, fenv_addr);
   25372                 :        7054 :       tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
   25373                 :        7054 :       tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
   25374                 :        7054 :       tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
   25375                 :        7054 :       tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
   25376                 :        7054 :       tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
   25377                 :        7054 :       tree hold_fnclex = build_call_expr (fnclex, 0);
   25378                 :        7054 :       fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
   25379                 :             :                          NULL_TREE, NULL_TREE);
   25380                 :        7054 :       *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
   25381                 :             :                       hold_fnclex);
   25382                 :        7054 :       *clear = build_call_expr (fnclex, 0);
   25383                 :        7054 :       tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
   25384                 :        7054 :       tree fnstsw_call = build_call_expr (fnstsw, 0);
   25385                 :        7054 :       tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
   25386                 :             :                             fnstsw_call, NULL_TREE, NULL_TREE);
   25387                 :        7054 :       tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
   25388                 :        7054 :       tree update_mod = build4 (TARGET_EXPR, integer_type_node,
   25389                 :             :                                 exceptions_var, exceptions_x87,
   25390                 :             :                                 NULL_TREE, NULL_TREE);
   25391                 :        7054 :       *update = build2 (COMPOUND_EXPR, integer_type_node,
   25392                 :             :                         sw_mod, update_mod);
   25393                 :        7054 :       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
   25394                 :        7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
   25395                 :             :     }
   25396                 :        7054 :   if (TARGET_SSE && TARGET_SSE_MATH)
   25397                 :             :     {
   25398                 :        7054 :       tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
   25399                 :        7054 :       tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
   25400                 :        7054 :       tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
   25401                 :        7054 :       tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
   25402                 :        7054 :       tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
   25403                 :        7054 :       tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
   25404                 :             :                                       mxcsr_orig_var, stmxcsr_hold_call,
   25405                 :             :                                       NULL_TREE, NULL_TREE);
   25406                 :        7054 :       tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
   25407                 :             :                                   mxcsr_orig_var,
   25408                 :        7054 :                                   build_int_cst (unsigned_type_node, 0x1f80));
   25409                 :        7054 :       hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
   25410                 :        7054 :                              build_int_cst (unsigned_type_node, 0xffffffc0));
   25411                 :        7054 :       tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
   25412                 :             :                                      mxcsr_mod_var, hold_mod_val,
   25413                 :             :                                      NULL_TREE, NULL_TREE);
   25414                 :        7054 :       tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   25415                 :        7054 :       tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
   25416                 :             :                               hold_assign_orig, hold_assign_mod);
   25417                 :        7054 :       hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
   25418                 :             :                          ldmxcsr_hold_call);
   25419                 :        7054 :       if (*hold)
   25420                 :        7054 :         *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
   25421                 :             :       else
   25422                 :           0 :         *hold = hold_all;
   25423                 :        7054 :       tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   25424                 :        7054 :       if (*clear)
   25425                 :        7054 :         *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
   25426                 :             :                          ldmxcsr_clear_call);
   25427                 :             :       else
   25428                 :           0 :         *clear = ldmxcsr_clear_call;
   25429                 :        7054 :       tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
   25430                 :        7054 :       tree exceptions_sse = fold_convert (integer_type_node,
   25431                 :             :                                           stxmcsr_update_call);
   25432                 :        7054 :       if (*update)
   25433                 :             :         {
   25434                 :        7054 :           tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
   25435                 :             :                                         exceptions_var, exceptions_sse);
   25436                 :        7054 :           tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
   25437                 :             :                                            exceptions_var, exceptions_mod);
   25438                 :        7054 :           *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
   25439                 :             :                             exceptions_assign);
   25440                 :             :         }
   25441                 :             :       else
   25442                 :           0 :         *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
   25443                 :             :                           exceptions_sse, NULL_TREE, NULL_TREE);
   25444                 :        7054 :       tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
   25445                 :        7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   25446                 :             :                         ldmxcsr_update_call);
   25447                 :             :     }
   25448                 :        7054 :   tree atomic_feraiseexcept
   25449                 :        7054 :     = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
   25450                 :        7054 :   tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
   25451                 :             :                                                     1, exceptions_var);
   25452                 :        7054 :   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   25453                 :             :                     atomic_feraiseexcept_call);
   25454                 :             : }
   25455                 :             : 
   25456                 :             : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   25457                 :             : /* For i386, common symbol is local only for non-PIE binaries.  For
   25458                 :             :    x86-64, common symbol is local only for non-PIE binaries or linker
   25459                 :             :    supports copy reloc in PIE binaries.   */
   25460                 :             : 
   25461                 :             : static bool
   25462                 :   640375526 : ix86_binds_local_p (const_tree exp)
   25463                 :             : {
   25464                 :   640375526 :   bool direct_extern_access
   25465                 :   640375526 :     = (ix86_direct_extern_access
   25466                 :  1277299510 :        && !(VAR_OR_FUNCTION_DECL_P (exp)
   25467                 :   636923984 :             && lookup_attribute ("nodirect_extern_access",
   25468                 :   636923984 :                                  DECL_ATTRIBUTES (exp))));
   25469                 :   640375526 :   if (!direct_extern_access)
   25470                 :         950 :     ix86_has_no_direct_extern_access = true;
   25471                 :   640375526 :   return default_binds_local_p_3 (exp, flag_shlib != 0, true,
   25472                 :             :                                   direct_extern_access,
   25473                 :             :                                   (direct_extern_access
   25474                 :   640374576 :                                    && (!flag_pic
   25475                 :   124132620 :                                        || (TARGET_64BIT
   25476                 :   640375526 :                                            && HAVE_LD_PIE_COPYRELOC != 0))));
   25477                 :             : }
   25478                 :             : 
   25479                 :             : /* If flag_pic or ix86_direct_extern_access is false, then neither
   25480                 :             :    local nor global relocs should be placed in readonly memory.  */
   25481                 :             : 
   25482                 :             : static int
   25483                 :     5154843 : ix86_reloc_rw_mask (void)
   25484                 :             : {
   25485                 :     5154843 :   return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
   25486                 :             : }
   25487                 :             : #endif
   25488                 :             : 
   25489                 :             : /* Return true iff ADDR can be used as a symbolic base address.  */
   25490                 :             : 
   25491                 :             : static bool
   25492                 :        3885 : symbolic_base_address_p (rtx addr)
   25493                 :             : {
   25494                 :           0 :   if (GET_CODE (addr) == SYMBOL_REF)
   25495                 :             :     return true;
   25496                 :             : 
   25497                 :        3816 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
   25498                 :           0 :     return true;
   25499                 :             : 
   25500                 :             :   return false;
   25501                 :             : }
   25502                 :             : 
   25503                 :             : /* Return true iff ADDR can be used as a base address.  */
   25504                 :             : 
   25505                 :             : static bool
   25506                 :        6020 : base_address_p (rtx addr)
   25507                 :             : {
   25508                 :           0 :   if (REG_P (addr))
   25509                 :             :     return true;
   25510                 :             : 
   25511                 :        3660 :   if (symbolic_base_address_p (addr))
   25512                 :           0 :     return true;
   25513                 :             : 
   25514                 :             :   return false;
   25515                 :             : }
   25516                 :             : 
   25517                 :             : /* If MEM is in the form of [(base+symbase)+offset], extract the three
   25518                 :             :    parts of address and set to BASE, SYMBASE and OFFSET, otherwise
   25519                 :             :    return false.  */
   25520                 :             : 
   25521                 :             : static bool
   25522                 :        3671 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
   25523                 :             : {
   25524                 :        3671 :   rtx addr;
   25525                 :             : 
   25526                 :        3671 :   gcc_assert (MEM_P (mem));
   25527                 :             : 
   25528                 :        3671 :   addr = XEXP (mem, 0);
   25529                 :             :   
   25530                 :        3671 :   if (GET_CODE (addr) == CONST)
   25531                 :          52 :     addr = XEXP (addr, 0);
   25532                 :             : 
   25533                 :        3671 :   if (base_address_p (addr))
   25534                 :             :     {
   25535                 :        1322 :       *base = addr;
   25536                 :        1322 :       *symbase = const0_rtx;
   25537                 :        1322 :       *offset = const0_rtx;
   25538                 :        1322 :       return true;
   25539                 :             :     }
   25540                 :             : 
   25541                 :        2349 :   if (GET_CODE (addr) == PLUS
   25542                 :        2349 :       && base_address_p (XEXP (addr, 0)))
   25543                 :             :     {
   25544                 :        1103 :       rtx addend = XEXP (addr, 1);
   25545                 :             : 
   25546                 :        1103 :       if (GET_CODE (addend) == CONST)
   25547                 :           4 :         addend = XEXP (addend, 0);
   25548                 :             : 
   25549                 :        1103 :       if (CONST_INT_P (addend))
   25550                 :             :         {
   25551                 :         882 :           *base = XEXP (addr, 0);
   25552                 :         882 :           *symbase = const0_rtx;
   25553                 :         882 :           *offset = addend;
   25554                 :         882 :           return true;
   25555                 :             :         }
   25556                 :             : 
   25557                 :             :       /* Also accept REG + symbolic ref, with or without a CONST_INT
   25558                 :             :          offset.  */
   25559                 :         221 :       if (REG_P (XEXP (addr, 0)))
   25560                 :             :         {
   25561                 :         221 :           if (symbolic_base_address_p (addend))
   25562                 :             :             {
   25563                 :           0 :               *base = XEXP (addr, 0);
   25564                 :           0 :               *symbase = addend;
   25565                 :           0 :               *offset = const0_rtx;
   25566                 :           0 :               return true;
   25567                 :             :             }
   25568                 :             : 
   25569                 :         221 :           if (GET_CODE (addend) == PLUS
   25570                 :           4 :               && symbolic_base_address_p (XEXP (addend, 0))
   25571                 :         225 :               && CONST_INT_P (XEXP (addend, 1)))
   25572                 :             :             {
   25573                 :           4 :               *base = XEXP (addr, 0);
   25574                 :           4 :               *symbase = XEXP (addend, 0);
   25575                 :           4 :               *offset = XEXP (addend, 1);
   25576                 :           4 :               return true;
   25577                 :             :             }
   25578                 :             :         }
   25579                 :             :     }
   25580                 :             : 
   25581                 :             :   return false;
   25582                 :             : }
   25583                 :             : 
   25584                 :             : /* Given OPERANDS of consecutive load/store, check if we can merge
   25585                 :             :    them into move multiple.  LOAD is true if they are load instructions.
   25586                 :             :    MODE is the mode of memory operands.  */
   25587                 :             : 
   25588                 :             : bool
   25589                 :        1987 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
   25590                 :             :                                     machine_mode mode)
   25591                 :             : {
   25592                 :        1987 :   HOST_WIDE_INT offval_1, offval_2, msize;
   25593                 :        1987 :   rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
   25594                 :             :     symbase_1, symbase_2, offset_1, offset_2;
   25595                 :             : 
   25596                 :        1987 :   if (load)
   25597                 :             :     {
   25598                 :        1696 :       mem_1 = operands[1];
   25599                 :        1696 :       mem_2 = operands[3];
   25600                 :        1696 :       reg_1 = operands[0];
   25601                 :        1696 :       reg_2 = operands[2];
   25602                 :             :     }
   25603                 :             :   else
   25604                 :             :     {
   25605                 :         291 :       mem_1 = operands[0];
   25606                 :         291 :       mem_2 = operands[2];
   25607                 :         291 :       reg_1 = operands[1];
   25608                 :         291 :       reg_2 = operands[3];
   25609                 :             :     }
   25610                 :             : 
   25611                 :        1987 :   gcc_assert (REG_P (reg_1) && REG_P (reg_2));
   25612                 :             : 
   25613                 :        1987 :   if (REGNO (reg_1) != REGNO (reg_2))
   25614                 :             :     return false;
   25615                 :             : 
   25616                 :             :   /* Check if the addresses are in the form of [base+offset].  */
   25617                 :        1987 :   if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
   25618                 :             :     return false;
   25619                 :        1684 :   if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
   25620                 :             :     return false;
   25621                 :             : 
   25622                 :             :   /* Check if the bases are the same.  */
   25623                 :         524 :   if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
   25624                 :         106 :     return false;
   25625                 :             : 
   25626                 :         418 :   offval_1 = INTVAL (offset_1);
   25627                 :         418 :   offval_2 = INTVAL (offset_2);
   25628                 :         418 :   msize = GET_MODE_SIZE (mode);
   25629                 :             :   /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address.  */
   25630                 :         418 :   if (offval_1 + msize != offval_2)
   25631                 :             :     return false;
   25632                 :             : 
   25633                 :             :   return true;
   25634                 :             : }
   25635                 :             : 
   25636                 :             : /* Implement the TARGET_OPTAB_SUPPORTED_P hook.  */
   25637                 :             : 
   25638                 :             : static bool
   25639                 :      205413 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
   25640                 :             :                         optimization_type opt_type)
   25641                 :             : {
   25642                 :      205413 :   switch (op)
   25643                 :             :     {
   25644                 :         209 :     case asin_optab:
   25645                 :         209 :     case acos_optab:
   25646                 :         209 :     case log1p_optab:
   25647                 :         209 :     case exp_optab:
   25648                 :         209 :     case exp10_optab:
   25649                 :         209 :     case exp2_optab:
   25650                 :         209 :     case expm1_optab:
   25651                 :         209 :     case ldexp_optab:
   25652                 :         209 :     case scalb_optab:
   25653                 :         209 :     case round_optab:
   25654                 :         209 :     case lround_optab:
   25655                 :         209 :       return opt_type == OPTIMIZE_FOR_SPEED;
   25656                 :             : 
   25657                 :         264 :     case rint_optab:
   25658                 :         264 :       if (SSE_FLOAT_MODE_P (mode1)
   25659                 :         145 :           && TARGET_SSE_MATH
   25660                 :         129 :           && !flag_trapping_math
   25661                 :          21 :           && !TARGET_SSE4_1
   25662                 :             :           && mode1 != HFmode)
   25663                 :          21 :         return opt_type == OPTIMIZE_FOR_SPEED;
   25664                 :             :       return true;
   25665                 :             : 
   25666                 :        1787 :     case floor_optab:
   25667                 :        1787 :     case ceil_optab:
   25668                 :        1787 :     case btrunc_optab:
   25669                 :        1787 :       if (((SSE_FLOAT_MODE_P (mode1)
   25670                 :        1439 :             && TARGET_SSE_MATH
   25671                 :        1346 :             && TARGET_SSE4_1)
   25672                 :        1738 :            || mode1 == HFmode)
   25673                 :         118 :           && !flag_trapping_math)
   25674                 :             :         return true;
   25675                 :        1727 :       return opt_type == OPTIMIZE_FOR_SPEED;
   25676                 :             : 
   25677                 :          86 :     case rsqrt_optab:
   25678                 :          86 :       return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
   25679                 :             : 
   25680                 :             :     default:
   25681                 :             :       return true;
   25682                 :             :     }
   25683                 :             : }
   25684                 :             : 
   25685                 :             : /* Address space support.
   25686                 :             : 
   25687                 :             :    This is not "far pointers" in the 16-bit sense, but an easy way
   25688                 :             :    to use %fs and %gs segment prefixes.  Therefore:
   25689                 :             : 
   25690                 :             :     (a) All address spaces have the same modes,
   25691                 :             :     (b) All address spaces have the same addresss forms,
   25692                 :             :     (c) While %fs and %gs are technically subsets of the generic
   25693                 :             :         address space, they are probably not subsets of each other.
   25694                 :             :     (d) Since we have no access to the segment base register values
   25695                 :             :         without resorting to a system call, we cannot convert a
   25696                 :             :         non-default address space to a default address space.
   25697                 :             :         Therefore we do not claim %fs or %gs are subsets of generic.
   25698                 :             : 
   25699                 :             :    Therefore we can (mostly) use the default hooks.  */
   25700                 :             : 
   25701                 :             : /* All use of segmentation is assumed to make address 0 valid.  */
   25702                 :             : 
   25703                 :             : static bool
   25704                 :    55491842 : ix86_addr_space_zero_address_valid (addr_space_t as)
   25705                 :             : {
   25706                 :    55491842 :   return as != ADDR_SPACE_GENERIC;
   25707                 :             : }
   25708                 :             : 
   25709                 :             : static void
   25710                 :      773502 : ix86_init_libfuncs (void)
   25711                 :             : {
   25712                 :      773502 :   if (TARGET_64BIT)
   25713                 :             :     {
   25714                 :      758665 :       set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
   25715                 :      758665 :       set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
   25716                 :             :     }
   25717                 :             :   else
   25718                 :             :     {
   25719                 :       14837 :       set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
   25720                 :       14837 :       set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
   25721                 :             :     }
   25722                 :             : 
   25723                 :             : #if TARGET_MACHO
   25724                 :             :   darwin_rename_builtins ();
   25725                 :             : #endif
   25726                 :      773502 : }
   25727                 :             : 
   25728                 :             : /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
   25729                 :             :    FPU, assume that the fpcw is set to extended precision; when using
   25730                 :             :    only SSE, rounding is correct; when using both SSE and the FPU,
   25731                 :             :    the rounding precision is indeterminate, since either may be chosen
   25732                 :             :    apparently at random.  */
   25733                 :             : 
   25734                 :             : static enum flt_eval_method
   25735                 :    87182078 : ix86_get_excess_precision (enum excess_precision_type type)
   25736                 :             : {
   25737                 :    87182078 :   switch (type)
   25738                 :             :     {
   25739                 :    83472315 :       case EXCESS_PRECISION_TYPE_FAST:
   25740                 :             :         /* The fastest type to promote to will always be the native type,
   25741                 :             :            whether that occurs with implicit excess precision or
   25742                 :             :            otherwise.  */
   25743                 :    83472315 :         return TARGET_AVX512FP16
   25744                 :    83472315 :                ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
   25745                 :    83472315 :                : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   25746                 :     3709719 :       case EXCESS_PRECISION_TYPE_STANDARD:
   25747                 :     3709719 :       case EXCESS_PRECISION_TYPE_IMPLICIT:
   25748                 :             :         /* Otherwise, the excess precision we want when we are
   25749                 :             :            in a standards compliant mode, and the implicit precision we
   25750                 :             :            provide would be identical were it not for the unpredictable
   25751                 :             :            cases.  */
   25752                 :     3709719 :         if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
   25753                 :             :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   25754                 :     3705363 :         else if (!TARGET_80387)
   25755                 :             :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   25756                 :     3699555 :         else if (!TARGET_MIX_SSE_I387)
   25757                 :             :           {
   25758                 :     3699383 :             if (!(TARGET_SSE && TARGET_SSE_MATH))
   25759                 :             :               return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
   25760                 :     2712896 :             else if (TARGET_SSE2)
   25761                 :             :               return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   25762                 :             :           }
   25763                 :             : 
   25764                 :             :         /* If we are in standards compliant mode, but we know we will
   25765                 :             :            calculate in unpredictable precision, return
   25766                 :             :            FLT_EVAL_METHOD_FLOAT.  There is no reason to introduce explicit
   25767                 :             :            excess precision if the target can't guarantee it will honor
   25768                 :             :            it.  */
   25769                 :         322 :         return (type == EXCESS_PRECISION_TYPE_STANDARD
   25770                 :         322 :                 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
   25771                 :             :                 : FLT_EVAL_METHOD_UNPREDICTABLE);
   25772                 :          44 :       case EXCESS_PRECISION_TYPE_FLOAT16:
   25773                 :          44 :         if (TARGET_80387
   25774                 :          38 :             && !(TARGET_SSE_MATH && TARGET_SSE))
   25775                 :           4 :           error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
   25776                 :             :         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   25777                 :           0 :       default:
   25778                 :           0 :         gcc_unreachable ();
   25779                 :             :     }
   25780                 :             : 
   25781                 :             :   return FLT_EVAL_METHOD_UNPREDICTABLE;
   25782                 :             : }
   25783                 :             : 
   25784                 :             : /* Return true if _BitInt(N) is supported and fill its details into *INFO.  */
   25785                 :             : bool
   25786                 :     1718308 : ix86_bitint_type_info (int n, struct bitint_info *info)
   25787                 :             : {
   25788                 :     1718308 :   if (n <= 8)
   25789                 :        3565 :     info->limb_mode = QImode;
   25790                 :     1714743 :   else if (n <= 16)
   25791                 :         851 :     info->limb_mode = HImode;
   25792                 :     1713892 :   else if (n <= 32 || (!TARGET_64BIT && n > 64))
   25793                 :       18460 :     info->limb_mode = SImode;
   25794                 :             :   else
   25795                 :     1695432 :     info->limb_mode = DImode;
   25796                 :     1718308 :   info->abi_limb_mode = info->limb_mode;
   25797                 :     1718308 :   info->big_endian = false;
   25798                 :     1718308 :   info->extended = false;
   25799                 :     1718308 :   return true;
   25800                 :             : }
   25801                 :             : 
   25802                 :             : /* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
   25803                 :             :    decrements by exactly 2 no matter what the position was, there is no pushb.
   25804                 :             : 
   25805                 :             :    But as CIE data alignment factor on this arch is -4 for 32bit targets
   25806                 :             :    and -8 for 64bit targets, we need to make sure all stack pointer adjustments
   25807                 :             :    are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
   25808                 :             : 
   25809                 :             : poly_int64
   25810                 :   202567779 : ix86_push_rounding (poly_int64 bytes)
   25811                 :             : {
   25812                 :   262513701 :   return ROUND_UP (bytes, UNITS_PER_WORD);
   25813                 :             : }
   25814                 :             : 
   25815                 :             : /* Use 8 bits metadata start from bit48 for LAM_U48,
   25816                 :             :    6 bits metadat start from bit57 for LAM_U57.  */
   25817                 :             : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48             \
   25818                 :             :                            ? 48                                 \
   25819                 :             :                            : (ix86_lam_type == lam_u57 ? 57 : 0))
   25820                 :             : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48          \
   25821                 :             :                               ? 8                               \
   25822                 :             :                               : (ix86_lam_type == lam_u57 ? 6 : 0))
   25823                 :             : 
   25824                 :             : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  */
   25825                 :             : bool
   25826                 :     5849782 : ix86_memtag_can_tag_addresses ()
   25827                 :             : {
   25828                 :     5849782 :   return ix86_lam_type != lam_none && TARGET_LP64;
   25829                 :             : }
   25830                 :             : 
   25831                 :             : /* Implement TARGET_MEMTAG_TAG_SIZE.  */
   25832                 :             : unsigned char
   25833                 :         460 : ix86_memtag_tag_size ()
   25834                 :             : {
   25835                 :         460 :   return IX86_HWASAN_TAG_SIZE;
   25836                 :             : }
   25837                 :             : 
   25838                 :             : /* Implement TARGET_MEMTAG_SET_TAG.  */
   25839                 :             : rtx
   25840                 :         108 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
   25841                 :             : {
   25842                 :             :   /* default_memtag_insert_random_tag may
   25843                 :             :      generate tag with value more than 6 bits.  */
   25844                 :         108 :   if (ix86_lam_type == lam_u57)
   25845                 :             :     {
   25846                 :         108 :       unsigned HOST_WIDE_INT and_imm
   25847                 :             :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   25848                 :             : 
   25849                 :         108 :       emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
   25850                 :             :     }
   25851                 :         108 :   tag = expand_simple_binop (Pmode, ASHIFT, tag,
   25852                 :         108 :                              GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
   25853                 :             :                              /* unsignedp = */1, OPTAB_WIDEN);
   25854                 :         108 :   rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
   25855                 :             :                                  /* unsignedp = */1, OPTAB_DIRECT);
   25856                 :         108 :   return ret;
   25857                 :             : }
   25858                 :             : 
   25859                 :             : /* Implement TARGET_MEMTAG_EXTRACT_TAG.  */
   25860                 :             : rtx
   25861                 :         184 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
   25862                 :             : {
   25863                 :         184 :   rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
   25864                 :         184 :                                  GEN_INT (IX86_HWASAN_SHIFT), target,
   25865                 :             :                                  /* unsignedp = */0,
   25866                 :             :                                  OPTAB_DIRECT);
   25867                 :         184 :   rtx ret = gen_reg_rtx (QImode);
   25868                 :             :   /* Mask off bit63 when LAM_U57.  */
   25869                 :         184 :   if (ix86_lam_type == lam_u57)
   25870                 :             :     {
   25871                 :         184 :       unsigned HOST_WIDE_INT and_imm
   25872                 :             :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   25873                 :         184 :       emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
   25874                 :             :                              gen_int_mode (and_imm, QImode)));
   25875                 :             :     }
   25876                 :             :   else
   25877                 :           0 :     emit_move_insn (ret, gen_lowpart (QImode, tag));
   25878                 :         184 :   return ret;
   25879                 :             : }
   25880                 :             : 
   25881                 :             : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER.  */
   25882                 :             : rtx
   25883                 :         116 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
   25884                 :             : {
   25885                 :             :   /* Leave bit63 alone.  */
   25886                 :         116 :   rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
   25887                 :         116 :                                 + (HOST_WIDE_INT_1U << 63) - 1),
   25888                 :         116 :                                Pmode);
   25889                 :         116 :   rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
   25890                 :             :                                            tag_mask, target, true,
   25891                 :             :                                            OPTAB_DIRECT);
   25892                 :         116 :   gcc_assert (untagged_base);
   25893                 :         116 :   return untagged_base;
   25894                 :             : }
   25895                 :             : 
   25896                 :             : /* Implement TARGET_MEMTAG_ADD_TAG.  */
   25897                 :             : rtx
   25898                 :          92 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
   25899                 :             : {
   25900                 :          92 :   rtx base_tag = gen_reg_rtx (QImode);
   25901                 :          92 :   rtx base_addr = gen_reg_rtx (Pmode);
   25902                 :          92 :   rtx tagged_addr = gen_reg_rtx (Pmode);
   25903                 :          92 :   rtx new_tag = gen_reg_rtx (QImode);
   25904                 :         184 :   unsigned HOST_WIDE_INT and_imm
   25905                 :          92 :     = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
   25906                 :             : 
   25907                 :             :   /* When there's "overflow" in tag adding,
   25908                 :             :      need to mask the most significant bit off.  */
   25909                 :          92 :   emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
   25910                 :          92 :   emit_move_insn (base_addr,
   25911                 :             :                   ix86_memtag_untagged_pointer (base, NULL_RTX));
   25912                 :          92 :   emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
   25913                 :          92 :   emit_move_insn (new_tag, base_tag);
   25914                 :          92 :   emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
   25915                 :          92 :   emit_move_insn (tagged_addr,
   25916                 :             :                   ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
   25917                 :          92 :   return plus_constant (Pmode, tagged_addr, offset);
   25918                 :             : }
   25919                 :             : 
   25920                 :             : /* Target-specific selftests.  */
   25921                 :             : 
   25922                 :             : #if CHECKING_P
   25923                 :             : 
   25924                 :             : namespace selftest {
   25925                 :             : 
   25926                 :             : /* Verify that hard regs are dumped as expected (in compact mode).  */
   25927                 :             : 
   25928                 :             : static void
   25929                 :           4 : ix86_test_dumping_hard_regs ()
   25930                 :             : {
   25931                 :           4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
   25932                 :           4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
   25933                 :           4 : }
   25934                 :             : 
   25935                 :             : /* Test dumping an insn with repeated references to the same SCRATCH,
   25936                 :             :    to verify the rtx_reuse code.  */
   25937                 :             : 
   25938                 :             : static void
   25939                 :           4 : ix86_test_dumping_memory_blockage ()
   25940                 :             : {
   25941                 :           4 :   set_new_first_and_last_insn (NULL, NULL);
   25942                 :             : 
   25943                 :           4 :   rtx pat = gen_memory_blockage ();
   25944                 :           4 :   rtx_reuse_manager r;
   25945                 :           4 :   r.preprocess (pat);
   25946                 :             : 
   25947                 :             :   /* Verify that the repeated references to the SCRATCH show use
   25948                 :             :      reuse IDS.  The first should be prefixed with a reuse ID,
   25949                 :             :      and the second should be dumped as a "reuse_rtx" of that ID.
   25950                 :             :      The expected string assumes Pmode == DImode.  */
   25951                 :           4 :   if (Pmode == DImode)
   25952                 :           4 :     ASSERT_RTL_DUMP_EQ_WITH_REUSE
   25953                 :             :       ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0  A8])\n"
   25954                 :             :        "        (unspec:BLK [\n"
   25955                 :             :        "                (mem/v:BLK (reuse_rtx 0) [0  A8])\n"
   25956                 :             :        "            ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
   25957                 :           4 : }
   25958                 :             : 
   25959                 :             : /* Verify loading an RTL dump; specifically a dump of copying
   25960                 :             :    a param on x86_64 from a hard reg into the frame.
   25961                 :             :    This test is target-specific since the dump contains target-specific
   25962                 :             :    hard reg names.  */
   25963                 :             : 
   25964                 :             : static void
   25965                 :           4 : ix86_test_loading_dump_fragment_1 ()
   25966                 :             : {
   25967                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION,
   25968                 :           4 :                    locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
   25969                 :             : 
   25970                 :           4 :   rtx_insn *insn = get_insn_by_uid (1);
   25971                 :             : 
   25972                 :             :   /* The block structure and indentation here is purely for
   25973                 :             :      readability; it mirrors the structure of the rtx.  */
   25974                 :           4 :   tree mem_expr;
   25975                 :           4 :   {
   25976                 :           4 :     rtx pat = PATTERN (insn);
   25977                 :           4 :     ASSERT_EQ (SET, GET_CODE (pat));
   25978                 :           4 :     {
   25979                 :           4 :       rtx dest = SET_DEST (pat);
   25980                 :           4 :       ASSERT_EQ (MEM, GET_CODE (dest));
   25981                 :             :       /* Verify the "/c" was parsed.  */
   25982                 :           4 :       ASSERT_TRUE (RTX_FLAG (dest, call));
   25983                 :           4 :       ASSERT_EQ (SImode, GET_MODE (dest));
   25984                 :           4 :       {
   25985                 :           4 :         rtx addr = XEXP (dest, 0);
   25986                 :           4 :         ASSERT_EQ (PLUS, GET_CODE (addr));
   25987                 :           4 :         ASSERT_EQ (DImode, GET_MODE (addr));
   25988                 :           4 :         {
   25989                 :           4 :           rtx lhs = XEXP (addr, 0);
   25990                 :             :           /* Verify that the "frame" REG was consolidated.  */
   25991                 :           4 :           ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
   25992                 :             :         }
   25993                 :           4 :         {
   25994                 :           4 :           rtx rhs = XEXP (addr, 1);
   25995                 :           4 :           ASSERT_EQ (CONST_INT, GET_CODE (rhs));
   25996                 :           4 :           ASSERT_EQ (-4, INTVAL (rhs));
   25997                 :             :         }
   25998                 :             :       }
   25999                 :             :       /* Verify the "[1 i+0 S4 A32]" was parsed.  */
   26000                 :           4 :       ASSERT_EQ (1, MEM_ALIAS_SET (dest));
   26001                 :             :       /* "i" should have been handled by synthesizing a global int
   26002                 :             :          variable named "i".  */
   26003                 :           4 :       mem_expr = MEM_EXPR (dest);
   26004                 :           4 :       ASSERT_NE (mem_expr, NULL);
   26005                 :           4 :       ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
   26006                 :           4 :       ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
   26007                 :           4 :       ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
   26008                 :           4 :       ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
   26009                 :             :       /* "+0".  */
   26010                 :           4 :       ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
   26011                 :           4 :       ASSERT_EQ (0, MEM_OFFSET (dest));
   26012                 :             :       /* "S4".  */
   26013                 :           4 :       ASSERT_EQ (4, MEM_SIZE (dest));
   26014                 :             :       /* "A32.  */
   26015                 :           4 :       ASSERT_EQ (32, MEM_ALIGN (dest));
   26016                 :             :     }
   26017                 :           4 :     {
   26018                 :           4 :       rtx src = SET_SRC (pat);
   26019                 :           4 :       ASSERT_EQ (REG, GET_CODE (src));
   26020                 :           4 :       ASSERT_EQ (SImode, GET_MODE (src));
   26021                 :           4 :       ASSERT_EQ (5, REGNO (src));
   26022                 :           4 :       tree reg_expr = REG_EXPR (src);
   26023                 :             :       /* "i" here should point to the same var as for the MEM_EXPR.  */
   26024                 :           4 :       ASSERT_EQ (reg_expr, mem_expr);
   26025                 :             :     }
   26026                 :             :   }
   26027                 :           4 : }
   26028                 :             : 
   26029                 :             : /* Verify that the RTL loader copes with a call_insn dump.
   26030                 :             :    This test is target-specific since the dump contains a target-specific
   26031                 :             :    hard reg name.  */
   26032                 :             : 
   26033                 :             : static void
   26034                 :           4 : ix86_test_loading_call_insn ()
   26035                 :             : {
   26036                 :             :   /* The test dump includes register "xmm0", where requires TARGET_SSE
   26037                 :             :      to exist.  */
   26038                 :           4 :   if (!TARGET_SSE)
   26039                 :           0 :     return;
   26040                 :             : 
   26041                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
   26042                 :             : 
   26043                 :           4 :   rtx_insn *insn = get_insns ();
   26044                 :           4 :   ASSERT_EQ (CALL_INSN, GET_CODE (insn));
   26045                 :             : 
   26046                 :             :   /* "/j".  */
   26047                 :           4 :   ASSERT_TRUE (RTX_FLAG (insn, jump));
   26048                 :             : 
   26049                 :           4 :   rtx pat = PATTERN (insn);
   26050                 :           4 :   ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
   26051                 :             : 
   26052                 :             :   /* Verify REG_NOTES.  */
   26053                 :           4 :   {
   26054                 :             :     /* "(expr_list:REG_CALL_DECL".   */
   26055                 :           4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
   26056                 :           4 :     rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
   26057                 :           4 :     ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
   26058                 :             : 
   26059                 :             :     /* "(expr_list:REG_EH_REGION (const_int 0 [0])".  */
   26060                 :           4 :     rtx_expr_list *note1 = note0->next ();
   26061                 :           4 :     ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
   26062                 :             : 
   26063                 :           4 :     ASSERT_EQ (NULL, note1->next ());
   26064                 :             :   }
   26065                 :             : 
   26066                 :             :   /* Verify CALL_INSN_FUNCTION_USAGE.  */
   26067                 :           4 :   {
   26068                 :             :     /* "(expr_list:DF (use (reg:DF 21 xmm0))".  */
   26069                 :           4 :     rtx_expr_list *usage
   26070                 :           4 :       = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
   26071                 :           4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
   26072                 :           4 :     ASSERT_EQ (DFmode, GET_MODE (usage));
   26073                 :           4 :     ASSERT_EQ (USE, GET_CODE (usage->element ()));
   26074                 :           4 :     ASSERT_EQ (NULL, usage->next ());
   26075                 :             :   }
   26076                 :           4 : }
   26077                 :             : 
   26078                 :             : /* Verify that the RTL loader copes a dump from print_rtx_function.
   26079                 :             :    This test is target-specific since the dump contains target-specific
   26080                 :             :    hard reg names.  */
   26081                 :             : 
   26082                 :             : static void
   26083                 :           4 : ix86_test_loading_full_dump ()
   26084                 :             : {
   26085                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
   26086                 :             : 
   26087                 :           4 :   ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   26088                 :             : 
   26089                 :           4 :   rtx_insn *insn_1 = get_insn_by_uid (1);
   26090                 :           4 :   ASSERT_EQ (NOTE, GET_CODE (insn_1));
   26091                 :             : 
   26092                 :           4 :   rtx_insn *insn_7 = get_insn_by_uid (7);
   26093                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn_7));
   26094                 :           4 :   ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
   26095                 :             : 
   26096                 :           4 :   rtx_insn *insn_15 = get_insn_by_uid (15);
   26097                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn_15));
   26098                 :           4 :   ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
   26099                 :             : 
   26100                 :             :   /* Verify crtl->return_rtx.  */
   26101                 :           4 :   ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
   26102                 :           4 :   ASSERT_EQ (0, REGNO (crtl->return_rtx));
   26103                 :           4 :   ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
   26104                 :           4 : }
   26105                 :             : 
   26106                 :             : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
   26107                 :             :    In particular, verify that it correctly loads the 2nd operand.
   26108                 :             :    This test is target-specific since these are machine-specific
   26109                 :             :    operands (and enums).  */
   26110                 :             : 
   26111                 :             : static void
   26112                 :           4 : ix86_test_loading_unspec ()
   26113                 :             : {
   26114                 :           4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
   26115                 :             : 
   26116                 :           4 :   ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   26117                 :             : 
   26118                 :           4 :   ASSERT_TRUE (cfun);
   26119                 :             : 
   26120                 :             :   /* Test of an UNSPEC.  */
   26121                 :           4 :    rtx_insn *insn = get_insns ();
   26122                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   26123                 :           4 :   rtx set = single_set (insn);
   26124                 :           4 :   ASSERT_NE (NULL, set);
   26125                 :           4 :   rtx dst = SET_DEST (set);
   26126                 :           4 :   ASSERT_EQ (MEM, GET_CODE (dst));
   26127                 :           4 :   rtx src = SET_SRC (set);
   26128                 :           4 :   ASSERT_EQ (UNSPEC, GET_CODE (src));
   26129                 :           4 :   ASSERT_EQ (BLKmode, GET_MODE (src));
   26130                 :           4 :   ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
   26131                 :             : 
   26132                 :           4 :   rtx v0 = XVECEXP (src, 0, 0);
   26133                 :             : 
   26134                 :             :   /* Verify that the two uses of the first SCRATCH have pointer
   26135                 :             :      equality.  */
   26136                 :           4 :   rtx scratch_a = XEXP (dst, 0);
   26137                 :           4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
   26138                 :             : 
   26139                 :           4 :   rtx scratch_b = XEXP (v0, 0);
   26140                 :           4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
   26141                 :             : 
   26142                 :           4 :   ASSERT_EQ (scratch_a, scratch_b);
   26143                 :             : 
   26144                 :             :   /* Verify that the two mems are thus treated as equal.  */
   26145                 :           4 :   ASSERT_TRUE (rtx_equal_p (dst, v0));
   26146                 :             : 
   26147                 :             :   /* Verify that the insn is recognized.  */
   26148                 :           4 :   ASSERT_NE(-1, recog_memoized (insn));
   26149                 :             : 
   26150                 :             :   /* Test of an UNSPEC_VOLATILE, which has its own enum values.  */
   26151                 :           4 :   insn = NEXT_INSN (insn);
   26152                 :           4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   26153                 :             : 
   26154                 :           4 :   set = single_set (insn);
   26155                 :           4 :   ASSERT_NE (NULL, set);
   26156                 :             : 
   26157                 :           4 :   src = SET_SRC (set);
   26158                 :           4 :   ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
   26159                 :           4 :   ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
   26160                 :           4 : }
   26161                 :             : 
   26162                 :             : /* Run all target-specific selftests.  */
   26163                 :             : 
   26164                 :             : static void
   26165                 :           4 : ix86_run_selftests (void)
   26166                 :             : {
   26167                 :           4 :   ix86_test_dumping_hard_regs ();
   26168                 :           4 :   ix86_test_dumping_memory_blockage ();
   26169                 :             : 
   26170                 :             :   /* Various tests of loading RTL dumps, here because they contain
   26171                 :             :      ix86-isms (e.g. names of hard regs).  */
   26172                 :           4 :   ix86_test_loading_dump_fragment_1 ();
   26173                 :           4 :   ix86_test_loading_call_insn ();
   26174                 :           4 :   ix86_test_loading_full_dump ();
   26175                 :           4 :   ix86_test_loading_unspec ();
   26176                 :           4 : }
   26177                 :             : 
   26178                 :             : } // namespace selftest
   26179                 :             : 
   26180                 :             : #endif /* CHECKING_P */
   26181                 :             : 
   26182                 :             : static const scoped_attribute_specs *const ix86_attribute_table[] =
   26183                 :             : {
   26184                 :             :   &ix86_gnu_attribute_table
   26185                 :             : };
   26186                 :             : 
   26187                 :             : /* Initialize the GCC target structure.  */
   26188                 :             : #undef TARGET_RETURN_IN_MEMORY
   26189                 :             : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
   26190                 :             : 
   26191                 :             : #undef TARGET_LEGITIMIZE_ADDRESS
   26192                 :             : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
   26193                 :             : 
   26194                 :             : #undef TARGET_ATTRIBUTE_TABLE
   26195                 :             : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
   26196                 :             : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
   26197                 :             : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
   26198                 :             : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   26199                 :             : #  undef TARGET_MERGE_DECL_ATTRIBUTES
   26200                 :             : #  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
   26201                 :             : #endif
   26202                 :             : 
   26203                 :             : #undef TARGET_INVALID_CONVERSION
   26204                 :             : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
   26205                 :             : 
   26206                 :             : #undef TARGET_INVALID_UNARY_OP
   26207                 :             : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
   26208                 :             : 
   26209                 :             : #undef TARGET_INVALID_BINARY_OP
   26210                 :             : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
   26211                 :             : 
   26212                 :             : #undef TARGET_COMP_TYPE_ATTRIBUTES
   26213                 :             : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
   26214                 :             : 
   26215                 :             : #undef TARGET_INIT_BUILTINS
   26216                 :             : #define TARGET_INIT_BUILTINS ix86_init_builtins
   26217                 :             : #undef TARGET_BUILTIN_DECL
   26218                 :             : #define TARGET_BUILTIN_DECL ix86_builtin_decl
   26219                 :             : #undef TARGET_EXPAND_BUILTIN
   26220                 :             : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
   26221                 :             : 
   26222                 :             : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
   26223                 :             : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
   26224                 :             :   ix86_builtin_vectorized_function
   26225                 :             : 
   26226                 :             : #undef TARGET_VECTORIZE_BUILTIN_GATHER
   26227                 :             : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
   26228                 :             : 
   26229                 :             : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
   26230                 :             : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
   26231                 :             : 
   26232                 :             : #undef TARGET_BUILTIN_RECIPROCAL
   26233                 :             : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
   26234                 :             : 
   26235                 :             : #undef TARGET_ASM_FUNCTION_EPILOGUE
   26236                 :             : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
   26237                 :             : 
   26238                 :             : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
   26239                 :             : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
   26240                 :             :   ix86_print_patchable_function_entry
   26241                 :             : 
   26242                 :             : #undef TARGET_ENCODE_SECTION_INFO
   26243                 :             : #ifndef SUBTARGET_ENCODE_SECTION_INFO
   26244                 :             : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
   26245                 :             : #else
   26246                 :             : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
   26247                 :             : #endif
   26248                 :             : 
   26249                 :             : #undef TARGET_ASM_OPEN_PAREN
   26250                 :             : #define TARGET_ASM_OPEN_PAREN ""
   26251                 :             : #undef TARGET_ASM_CLOSE_PAREN
   26252                 :             : #define TARGET_ASM_CLOSE_PAREN ""
   26253                 :             : 
   26254                 :             : #undef TARGET_ASM_BYTE_OP
   26255                 :             : #define TARGET_ASM_BYTE_OP ASM_BYTE
   26256                 :             : 
   26257                 :             : #undef TARGET_ASM_ALIGNED_HI_OP
   26258                 :             : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
   26259                 :             : #undef TARGET_ASM_ALIGNED_SI_OP
   26260                 :             : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
   26261                 :             : #ifdef ASM_QUAD
   26262                 :             : #undef TARGET_ASM_ALIGNED_DI_OP
   26263                 :             : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
   26264                 :             : #endif
   26265                 :             : 
   26266                 :             : #undef TARGET_PROFILE_BEFORE_PROLOGUE
   26267                 :             : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
   26268                 :             : 
   26269                 :             : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
   26270                 :             : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
   26271                 :             : 
   26272                 :             : #undef TARGET_ASM_UNALIGNED_HI_OP
   26273                 :             : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
   26274                 :             : #undef TARGET_ASM_UNALIGNED_SI_OP
   26275                 :             : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
   26276                 :             : #undef TARGET_ASM_UNALIGNED_DI_OP
   26277                 :             : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
   26278                 :             : 
   26279                 :             : #undef TARGET_PRINT_OPERAND
   26280                 :             : #define TARGET_PRINT_OPERAND ix86_print_operand
   26281                 :             : #undef TARGET_PRINT_OPERAND_ADDRESS
   26282                 :             : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
   26283                 :             : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   26284                 :             : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
   26285                 :             : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
   26286                 :             : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
   26287                 :             : 
   26288                 :             : #undef TARGET_SCHED_INIT_GLOBAL
   26289                 :             : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
   26290                 :             : #undef TARGET_SCHED_ADJUST_COST
   26291                 :             : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
   26292                 :             : #undef TARGET_SCHED_ISSUE_RATE
   26293                 :             : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
   26294                 :             : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   26295                 :             : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   26296                 :             :   ia32_multipass_dfa_lookahead
   26297                 :             : #undef TARGET_SCHED_MACRO_FUSION_P
   26298                 :             : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
   26299                 :             : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
   26300                 :             : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
   26301                 :             : 
   26302                 :             : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   26303                 :             : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
   26304                 :             : 
   26305                 :             : #undef TARGET_MEMMODEL_CHECK
   26306                 :             : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
   26307                 :             : 
   26308                 :             : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   26309                 :             : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
   26310                 :             : 
   26311                 :             : #ifdef HAVE_AS_TLS
   26312                 :             : #undef TARGET_HAVE_TLS
   26313                 :             : #define TARGET_HAVE_TLS true
   26314                 :             : #endif
   26315                 :             : #undef TARGET_CANNOT_FORCE_CONST_MEM
   26316                 :             : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
   26317                 :             : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   26318                 :             : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   26319                 :             : 
   26320                 :             : #undef TARGET_DELEGITIMIZE_ADDRESS
   26321                 :             : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
   26322                 :             : 
   26323                 :             : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
   26324                 :             : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
   26325                 :             : 
   26326                 :             : #undef TARGET_MS_BITFIELD_LAYOUT_P
   26327                 :             : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
   26328                 :             : 
   26329                 :             : #if TARGET_MACHO
   26330                 :             : #undef TARGET_BINDS_LOCAL_P
   26331                 :             : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
   26332                 :             : #else
   26333                 :             : #undef TARGET_BINDS_LOCAL_P
   26334                 :             : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
   26335                 :             : #endif
   26336                 :             : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   26337                 :             : #undef TARGET_BINDS_LOCAL_P
   26338                 :             : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
   26339                 :             : #endif
   26340                 :             : 
   26341                 :             : #undef TARGET_ASM_OUTPUT_MI_THUNK
   26342                 :             : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
   26343                 :             : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   26344                 :             : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
   26345                 :             : 
   26346                 :             : #undef TARGET_ASM_FILE_START
   26347                 :             : #define TARGET_ASM_FILE_START x86_file_start
   26348                 :             : 
   26349                 :             : #undef TARGET_OPTION_OVERRIDE
   26350                 :             : #define TARGET_OPTION_OVERRIDE ix86_option_override
   26351                 :             : 
   26352                 :             : #undef TARGET_REGISTER_MOVE_COST
   26353                 :             : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
   26354                 :             : #undef TARGET_MEMORY_MOVE_COST
   26355                 :             : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
   26356                 :             : #undef TARGET_RTX_COSTS
   26357                 :             : #define TARGET_RTX_COSTS ix86_rtx_costs
   26358                 :             : #undef TARGET_ADDRESS_COST
   26359                 :             : #define TARGET_ADDRESS_COST ix86_address_cost
   26360                 :             : 
   26361                 :             : #undef TARGET_OVERLAP_OP_BY_PIECES_P
   26362                 :             : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
   26363                 :             : 
   26364                 :             : #undef TARGET_FLAGS_REGNUM
   26365                 :             : #define TARGET_FLAGS_REGNUM FLAGS_REG
   26366                 :             : #undef TARGET_FIXED_CONDITION_CODE_REGS
   26367                 :             : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
   26368                 :             : #undef TARGET_CC_MODES_COMPATIBLE
   26369                 :             : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
   26370                 :             : 
   26371                 :             : #undef TARGET_MACHINE_DEPENDENT_REORG
   26372                 :             : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
   26373                 :             : 
   26374                 :             : #undef TARGET_BUILD_BUILTIN_VA_LIST
   26375                 :             : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
   26376                 :             : 
   26377                 :             : #undef TARGET_FOLD_BUILTIN
   26378                 :             : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
   26379                 :             : 
   26380                 :             : #undef TARGET_GIMPLE_FOLD_BUILTIN
   26381                 :             : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
   26382                 :             : 
   26383                 :             : #undef TARGET_COMPARE_VERSION_PRIORITY
   26384                 :             : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
   26385                 :             : 
   26386                 :             : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
   26387                 :             : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
   26388                 :             :   ix86_generate_version_dispatcher_body
   26389                 :             : 
   26390                 :             : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
   26391                 :             : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
   26392                 :             :   ix86_get_function_versions_dispatcher
   26393                 :             : 
   26394                 :             : #undef TARGET_ENUM_VA_LIST_P
   26395                 :             : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
   26396                 :             : 
   26397                 :             : #undef TARGET_FN_ABI_VA_LIST
   26398                 :             : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
   26399                 :             : 
   26400                 :             : #undef TARGET_CANONICAL_VA_LIST_TYPE
   26401                 :             : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
   26402                 :             : 
   26403                 :             : #undef TARGET_EXPAND_BUILTIN_VA_START
   26404                 :             : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
   26405                 :             : 
   26406                 :             : #undef TARGET_MD_ASM_ADJUST
   26407                 :             : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
   26408                 :             : 
   26409                 :             : #undef TARGET_C_EXCESS_PRECISION
   26410                 :             : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
   26411                 :             : #undef TARGET_C_BITINT_TYPE_INFO
   26412                 :             : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
   26413                 :             : #undef TARGET_PROMOTE_PROTOTYPES
   26414                 :             : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
   26415                 :             : #undef TARGET_PUSH_ARGUMENT
   26416                 :             : #define TARGET_PUSH_ARGUMENT ix86_push_argument
   26417                 :             : #undef TARGET_SETUP_INCOMING_VARARGS
   26418                 :             : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
   26419                 :             : #undef TARGET_MUST_PASS_IN_STACK
   26420                 :             : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
   26421                 :             : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
   26422                 :             : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
   26423                 :             : #undef TARGET_FUNCTION_ARG_ADVANCE
   26424                 :             : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
   26425                 :             : #undef TARGET_FUNCTION_ARG
   26426                 :             : #define TARGET_FUNCTION_ARG ix86_function_arg
   26427                 :             : #undef TARGET_INIT_PIC_REG
   26428                 :             : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
   26429                 :             : #undef TARGET_USE_PSEUDO_PIC_REG
   26430                 :             : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
   26431                 :             : #undef TARGET_FUNCTION_ARG_BOUNDARY
   26432                 :             : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
   26433                 :             : #undef TARGET_PASS_BY_REFERENCE
   26434                 :             : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
   26435                 :             : #undef TARGET_INTERNAL_ARG_POINTER
   26436                 :             : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
   26437                 :             : #undef TARGET_UPDATE_STACK_BOUNDARY
   26438                 :             : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
   26439                 :             : #undef TARGET_GET_DRAP_RTX
   26440                 :             : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
   26441                 :             : #undef TARGET_STRICT_ARGUMENT_NAMING
   26442                 :             : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   26443                 :             : #undef TARGET_STATIC_CHAIN
   26444                 :             : #define TARGET_STATIC_CHAIN ix86_static_chain
   26445                 :             : #undef TARGET_TRAMPOLINE_INIT
   26446                 :             : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
   26447                 :             : #undef TARGET_RETURN_POPS_ARGS
   26448                 :             : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
   26449                 :             : 
   26450                 :             : #undef TARGET_WARN_FUNC_RETURN
   26451                 :             : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
   26452                 :             : 
   26453                 :             : #undef TARGET_LEGITIMATE_COMBINED_INSN
   26454                 :             : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
   26455                 :             : 
   26456                 :             : #undef TARGET_ASAN_SHADOW_OFFSET
   26457                 :             : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
   26458                 :             : 
   26459                 :             : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
   26460                 :             : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
   26461                 :             : 
   26462                 :             : #undef TARGET_SCALAR_MODE_SUPPORTED_P
   26463                 :             : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
   26464                 :             : 
   26465                 :             : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
   26466                 :             : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
   26467                 :             : ix86_libgcc_floating_mode_supported_p
   26468                 :             : 
   26469                 :             : #undef TARGET_VECTOR_MODE_SUPPORTED_P
   26470                 :             : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
   26471                 :             : 
   26472                 :             : #undef TARGET_C_MODE_FOR_SUFFIX
   26473                 :             : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
   26474                 :             : 
   26475                 :             : #ifdef HAVE_AS_TLS
   26476                 :             : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   26477                 :             : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
   26478                 :             : #endif
   26479                 :             : 
   26480                 :             : #ifdef SUBTARGET_INSERT_ATTRIBUTES
   26481                 :             : #undef TARGET_INSERT_ATTRIBUTES
   26482                 :             : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
   26483                 :             : #endif
   26484                 :             : 
   26485                 :             : #undef TARGET_MANGLE_TYPE
   26486                 :             : #define TARGET_MANGLE_TYPE ix86_mangle_type
   26487                 :             : 
   26488                 :             : #undef TARGET_EMIT_SUPPORT_TINFOS
   26489                 :             : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
   26490                 :             : 
   26491                 :             : #undef TARGET_STACK_PROTECT_GUARD
   26492                 :             : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
   26493                 :             : 
   26494                 :             : #if !TARGET_MACHO
   26495                 :             : #undef TARGET_STACK_PROTECT_FAIL
   26496                 :             : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
   26497                 :             : #endif
   26498                 :             : 
   26499                 :             : #undef TARGET_FUNCTION_VALUE
   26500                 :             : #define TARGET_FUNCTION_VALUE ix86_function_value
   26501                 :             : 
   26502                 :             : #undef TARGET_FUNCTION_VALUE_REGNO_P
   26503                 :             : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
   26504                 :             : 
   26505                 :             : #undef TARGET_ZERO_CALL_USED_REGS
   26506                 :             : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
   26507                 :             : 
   26508                 :             : #undef TARGET_PROMOTE_FUNCTION_MODE
   26509                 :             : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
   26510                 :             : 
   26511                 :             : #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
   26512                 :             : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
   26513                 :             : 
   26514                 :             : #undef TARGET_MEMBER_TYPE_FORCES_BLK
   26515                 :             : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
   26516                 :             : 
   26517                 :             : #undef TARGET_INSTANTIATE_DECLS
   26518                 :             : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
   26519                 :             : 
   26520                 :             : #undef TARGET_SECONDARY_RELOAD
   26521                 :             : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
   26522                 :             : #undef TARGET_SECONDARY_MEMORY_NEEDED
   26523                 :             : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
   26524                 :             : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
   26525                 :             : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
   26526                 :             : 
   26527                 :             : #undef TARGET_CLASS_MAX_NREGS
   26528                 :             : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
   26529                 :             : 
   26530                 :             : #undef TARGET_PREFERRED_RELOAD_CLASS
   26531                 :             : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
   26532                 :             : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
   26533                 :             : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
   26534                 :             : #undef TARGET_CLASS_LIKELY_SPILLED_P
   26535                 :             : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
   26536                 :             : 
   26537                 :             : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
   26538                 :             : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   26539                 :             :   ix86_builtin_vectorization_cost
   26540                 :             : #undef TARGET_VECTORIZE_VEC_PERM_CONST
   26541                 :             : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
   26542                 :             : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
   26543                 :             : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
   26544                 :             :   ix86_preferred_simd_mode
   26545                 :             : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
   26546                 :             : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
   26547                 :             :   ix86_split_reduction
   26548                 :             : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
   26549                 :             : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
   26550                 :             :   ix86_autovectorize_vector_modes
   26551                 :             : #undef TARGET_VECTORIZE_GET_MASK_MODE
   26552                 :             : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
   26553                 :             : #undef TARGET_VECTORIZE_CREATE_COSTS
   26554                 :             : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
   26555                 :             : 
   26556                 :             : #undef TARGET_SET_CURRENT_FUNCTION
   26557                 :             : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
   26558                 :             : 
   26559                 :             : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
   26560                 :             : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
   26561                 :             : 
   26562                 :             : #undef TARGET_OPTION_SAVE
   26563                 :             : #define TARGET_OPTION_SAVE ix86_function_specific_save
   26564                 :             : 
   26565                 :             : #undef TARGET_OPTION_RESTORE
   26566                 :             : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
   26567                 :             : 
   26568                 :             : #undef TARGET_OPTION_POST_STREAM_IN
   26569                 :             : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
   26570                 :             : 
   26571                 :             : #undef TARGET_OPTION_PRINT
   26572                 :             : #define TARGET_OPTION_PRINT ix86_function_specific_print
   26573                 :             : 
   26574                 :             : #undef TARGET_OPTION_FUNCTION_VERSIONS
   26575                 :             : #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
   26576                 :             : 
   26577                 :             : #undef TARGET_CAN_INLINE_P
   26578                 :             : #define TARGET_CAN_INLINE_P ix86_can_inline_p
   26579                 :             : 
   26580                 :             : #undef TARGET_LEGITIMATE_ADDRESS_P
   26581                 :             : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
   26582                 :             : 
   26583                 :             : #undef TARGET_REGISTER_PRIORITY
   26584                 :             : #define TARGET_REGISTER_PRIORITY ix86_register_priority
   26585                 :             : 
   26586                 :             : #undef TARGET_REGISTER_USAGE_LEVELING_P
   26587                 :             : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
   26588                 :             : 
   26589                 :             : #undef TARGET_LEGITIMATE_CONSTANT_P
   26590                 :             : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
   26591                 :             : 
   26592                 :             : #undef TARGET_COMPUTE_FRAME_LAYOUT
   26593                 :             : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
   26594                 :             : 
   26595                 :             : #undef TARGET_FRAME_POINTER_REQUIRED
   26596                 :             : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
   26597                 :             : 
   26598                 :             : #undef TARGET_CAN_ELIMINATE
   26599                 :             : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
   26600                 :             : 
   26601                 :             : #undef TARGET_EXTRA_LIVE_ON_ENTRY
   26602                 :             : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
   26603                 :             : 
   26604                 :             : #undef TARGET_ASM_CODE_END
   26605                 :             : #define TARGET_ASM_CODE_END ix86_code_end
   26606                 :             : 
   26607                 :             : #undef TARGET_CONDITIONAL_REGISTER_USAGE
   26608                 :             : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
   26609                 :             : 
   26610                 :             : #undef TARGET_CANONICALIZE_COMPARISON
   26611                 :             : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
   26612                 :             : 
   26613                 :             : #undef TARGET_LOOP_UNROLL_ADJUST
   26614                 :             : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
   26615                 :             : 
   26616                 :             : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   26617                 :             : #undef TARGET_SPILL_CLASS
   26618                 :             : #define TARGET_SPILL_CLASS ix86_spill_class
   26619                 :             : 
   26620                 :             : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
   26621                 :             : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
   26622                 :             :   ix86_simd_clone_compute_vecsize_and_simdlen
   26623                 :             : 
   26624                 :             : #undef TARGET_SIMD_CLONE_ADJUST
   26625                 :             : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
   26626                 :             : 
   26627                 :             : #undef TARGET_SIMD_CLONE_USABLE
   26628                 :             : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
   26629                 :             : 
   26630                 :             : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
   26631                 :             : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
   26632                 :             : 
   26633                 :             : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
   26634                 :             : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
   26635                 :             :   ix86_float_exceptions_rounding_supported_p
   26636                 :             : 
   26637                 :             : #undef TARGET_MODE_EMIT
   26638                 :             : #define TARGET_MODE_EMIT ix86_emit_mode_set
   26639                 :             : 
   26640                 :             : #undef TARGET_MODE_NEEDED
   26641                 :             : #define TARGET_MODE_NEEDED ix86_mode_needed
   26642                 :             : 
   26643                 :             : #undef TARGET_MODE_AFTER
   26644                 :             : #define TARGET_MODE_AFTER ix86_mode_after
   26645                 :             : 
   26646                 :             : #undef TARGET_MODE_ENTRY
   26647                 :             : #define TARGET_MODE_ENTRY ix86_mode_entry
   26648                 :             : 
   26649                 :             : #undef TARGET_MODE_EXIT
   26650                 :             : #define TARGET_MODE_EXIT ix86_mode_exit
   26651                 :             : 
   26652                 :             : #undef TARGET_MODE_PRIORITY
   26653                 :             : #define TARGET_MODE_PRIORITY ix86_mode_priority
   26654                 :             : 
   26655                 :             : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
   26656                 :             : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
   26657                 :             : 
   26658                 :             : #undef TARGET_OFFLOAD_OPTIONS
   26659                 :             : #define TARGET_OFFLOAD_OPTIONS \
   26660                 :             :   ix86_offload_options
   26661                 :             : 
   26662                 :             : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
   26663                 :             : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
   26664                 :             : 
   26665                 :             : #undef TARGET_OPTAB_SUPPORTED_P
   26666                 :             : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
   26667                 :             : 
   26668                 :             : #undef TARGET_HARD_REGNO_SCRATCH_OK
   26669                 :             : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
   26670                 :             : 
   26671                 :             : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
   26672                 :             : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
   26673                 :             : 
   26674                 :             : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
   26675                 :             : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
   26676                 :             : 
   26677                 :             : #undef TARGET_INIT_LIBFUNCS
   26678                 :             : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
   26679                 :             : 
   26680                 :             : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
   26681                 :             : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
   26682                 :             : 
   26683                 :             : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
   26684                 :             : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
   26685                 :             : 
   26686                 :             : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
   26687                 :             : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
   26688                 :             : 
   26689                 :             : #undef TARGET_HARD_REGNO_NREGS
   26690                 :             : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
   26691                 :             : #undef TARGET_HARD_REGNO_MODE_OK
   26692                 :             : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
   26693                 :             : 
   26694                 :             : #undef TARGET_MODES_TIEABLE_P
   26695                 :             : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
   26696                 :             : 
   26697                 :             : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
   26698                 :             : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
   26699                 :             :   ix86_hard_regno_call_part_clobbered
   26700                 :             : 
   26701                 :             : #undef TARGET_INSN_CALLEE_ABI
   26702                 :             : #define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi
   26703                 :             : 
   26704                 :             : #undef TARGET_CAN_CHANGE_MODE_CLASS
   26705                 :             : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
   26706                 :             : 
   26707                 :             : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
   26708                 :             : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
   26709                 :             : 
   26710                 :             : #undef TARGET_STATIC_RTX_ALIGNMENT
   26711                 :             : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
   26712                 :             : #undef TARGET_CONSTANT_ALIGNMENT
   26713                 :             : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
   26714                 :             : 
   26715                 :             : #undef TARGET_EMPTY_RECORD_P
   26716                 :             : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
   26717                 :             : 
   26718                 :             : #undef TARGET_WARN_PARAMETER_PASSING_ABI
   26719                 :             : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
   26720                 :             : 
   26721                 :             : #undef TARGET_GET_MULTILIB_ABI_NAME
   26722                 :             : #define TARGET_GET_MULTILIB_ABI_NAME \
   26723                 :             :   ix86_get_multilib_abi_name
   26724                 :             : 
   26725                 :             : #undef TARGET_IFUNC_REF_LOCAL_OK
   26726                 :             : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
   26727                 :             : 
   26728                 :             : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   26729                 :             : # undef TARGET_ASM_RELOC_RW_MASK
   26730                 :             : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
   26731                 :             : #endif
   26732                 :             : 
   26733                 :             : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
   26734                 :             : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
   26735                 :             : 
   26736                 :             : #undef TARGET_MEMTAG_ADD_TAG
   26737                 :             : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
   26738                 :             : 
   26739                 :             : #undef TARGET_MEMTAG_SET_TAG
   26740                 :             : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
   26741                 :             : 
   26742                 :             : #undef TARGET_MEMTAG_EXTRACT_TAG
   26743                 :             : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
   26744                 :             : 
   26745                 :             : #undef TARGET_MEMTAG_UNTAGGED_POINTER
   26746                 :             : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
   26747                 :             : 
   26748                 :             : #undef TARGET_MEMTAG_TAG_SIZE
   26749                 :             : #define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size
   26750                 :             : 
   26751                 :             : static bool
   26752                 :       68272 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
   26753                 :             : {
   26754                 :             : #ifdef OPTION_GLIBC
   26755                 :       68272 :   if (OPTION_GLIBC)
   26756                 :       68272 :     return (built_in_function)fcode == BUILT_IN_MEMPCPY;
   26757                 :             :   else
   26758                 :             :     return false;
   26759                 :             : #else
   26760                 :             :   return false;
   26761                 :             : #endif
   26762                 :             : }
   26763                 :             : 
   26764                 :             : #undef TARGET_LIBC_HAS_FAST_FUNCTION
   26765                 :             : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
   26766                 :             : 
   26767                 :             : static unsigned
   26768                 :       72079 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
   26769                 :             :                               bool boundary_p)
   26770                 :             : {
   26771                 :             : #ifdef OPTION_GLIBC
   26772                 :       72079 :   bool glibc_p = OPTION_GLIBC;
   26773                 :             : #else
   26774                 :             :   bool glibc_p = false;
   26775                 :             : #endif
   26776                 :       72079 :   if (glibc_p)
   26777                 :             :     {
   26778                 :             :       /* If __FAST_MATH__ is defined, glibc provides libmvec.  */
   26779                 :       72079 :       unsigned int libmvec_ret = 0;
   26780                 :       72079 :       if (!flag_trapping_math
   26781                 :        7809 :           && flag_unsafe_math_optimizations
   26782                 :        3024 :           && flag_finite_math_only
   26783                 :        2998 :           && !flag_signed_zeros
   26784                 :        2998 :           && !flag_errno_math)
   26785                 :        2998 :         switch (cfn)
   26786                 :             :           {
   26787                 :        1308 :           CASE_CFN_COS:
   26788                 :        1308 :           CASE_CFN_COS_FN:
   26789                 :        1308 :           CASE_CFN_SIN:
   26790                 :        1308 :           CASE_CFN_SIN_FN:
   26791                 :        1308 :             if (!boundary_p)
   26792                 :             :               {
   26793                 :             :                 /* With non-default rounding modes, libmvec provides
   26794                 :             :                    complete garbage in results.  E.g.
   26795                 :             :                    _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
   26796                 :             :                    returns 0.00333309174f rather than 1.40129846e-45f.  */
   26797                 :         543 :                 if (flag_rounding_math)
   26798                 :             :                   return ~0U;
   26799                 :             :                 /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
   26800                 :             :                    claims libmvec maximum error is 4ulps.
   26801                 :             :                    My own random testing indicates 2ulps for SFmode and
   26802                 :             :                    0.5ulps for DFmode, but let's go with the 4ulps.  */
   26803                 :             :                 libmvec_ret = 4;
   26804                 :             :               }
   26805                 :             :             break;
   26806                 :             :           default:
   26807                 :             :             break;
   26808                 :             :           }
   26809                 :       72079 :       unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
   26810                 :             :                                                               boundary_p);
   26811                 :       72079 :       return MAX (ret, libmvec_ret);
   26812                 :             :     }
   26813                 :           0 :   return default_libm_function_max_error (cfn, mode, boundary_p);
   26814                 :             : }
   26815                 :             : 
   26816                 :             : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
   26817                 :             : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
   26818                 :             : 
   26819                 :             : #if CHECKING_P
   26820                 :             : #undef TARGET_RUN_TARGET_SELFTESTS
   26821                 :             : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
   26822                 :             : #endif /* #if CHECKING_P */
   26823                 :             : 
   26824                 :             : struct gcc_target targetm = TARGET_INITIALIZER;
   26825                 :             : 
   26826                 :             : #include "gt-i386.h"
        

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.