LCOV - code coverage report
Current view: top level - gcc - optabs-libfuncs.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 77.9 % 421 328
Test Date: 2025-03-15 13:07:15 Functions: 73.2 % 41 30
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Mapping from optabs to underlying library functions
       2                 :             :    Copyright (C) 1987-2025 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : 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                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "target.h"
      25                 :             : #include "insn-codes.h"
      26                 :             : #include "optabs-libfuncs.h"
      27                 :             : #include "libfuncs.h"
      28                 :             : #include "optabs-query.h"
      29                 :             : #include "tree.h"
      30                 :             : #include "stringpool.h"
      31                 :             : #include "varasm.h"
      32                 :             : #include "stor-layout.h"
      33                 :             : #include "rtl.h"
      34                 :             : 
      35                 :             : struct target_libfuncs default_target_libfuncs;
      36                 :             : #if SWITCHABLE_TARGET
      37                 :             : struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
      38                 :             : #endif
      39                 :             : 
      40                 :             : #define libfunc_hash \
      41                 :             :   (this_target_libfuncs->x_libfunc_hash)
      42                 :             : 
      43                 :             : /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
      44                 :             : #if ENABLE_DECIMAL_BID_FORMAT
      45                 :             : #define DECIMAL_PREFIX "bid_"
      46                 :             : #else
      47                 :             : #define DECIMAL_PREFIX "dpd_"
      48                 :             : #endif
      49                 :             : 
      50                 :             : /* Used for libfunc_hash.  */
      51                 :             : 
      52                 :             : hashval_t
      53                 :    31908905 : libfunc_hasher::hash (libfunc_entry *e)
      54                 :             : {
      55                 :    31908905 :   return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
      56                 :             : }
      57                 :             : 
      58                 :             : /* Used for libfunc_hash.  */
      59                 :             : 
      60                 :             : bool
      61                 :    28503794 : libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2)
      62                 :             : {
      63                 :    28503794 :   return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
      64                 :             : }
      65                 :             : 
      66                 :             : /* Return libfunc corresponding operation defined by OPTAB converting
      67                 :             :    from MODE2 to MODE1.  Trigger lazy initialization if needed, return NULL
      68                 :             :    if no libfunc is available.  */
      69                 :             : rtx
      70                 :       38587 : convert_optab_libfunc (convert_optab optab, machine_mode mode1,
      71                 :             :                        machine_mode mode2)
      72                 :             : {
      73                 :       38587 :   struct libfunc_entry e;
      74                 :       38587 :   struct libfunc_entry **slot;
      75                 :             : 
      76                 :             :   /* ??? This ought to be an assert, but not all of the places
      77                 :             :      that we expand optabs know about the optabs that got moved
      78                 :             :      to being direct.  */
      79                 :       38587 :   if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
      80                 :             :     return NULL_RTX;
      81                 :             : 
      82                 :       38587 :   e.op = optab;
      83                 :       38587 :   e.mode1 = mode1;
      84                 :       38587 :   e.mode2 = mode2;
      85                 :       38587 :   slot = libfunc_hash->find_slot (&e, NO_INSERT);
      86                 :       38587 :   if (!slot)
      87                 :             :     {
      88                 :        3175 :       const struct convert_optab_libcall_d *d
      89                 :        3175 :         = &convlib_def[optab - FIRST_CONV_OPTAB];
      90                 :             : 
      91                 :        3175 :       if (d->libcall_gen == NULL)
      92                 :             :         return NULL;
      93                 :             : 
      94                 :        3175 :       d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
      95                 :        3175 :       slot = libfunc_hash->find_slot (&e, NO_INSERT);
      96                 :        3175 :       if (!slot)
      97                 :             :         return NULL;
      98                 :             :     }
      99                 :       38587 :   return (*slot)->libfunc;
     100                 :             : }
     101                 :             : 
     102                 :             : /* Return libfunc corresponding operation defined by OPTAB in MODE.
     103                 :             :    Trigger lazy initialization if needed, return NULL if no libfunc is
     104                 :             :    available.  */
     105                 :             : rtx
     106                 :     1929591 : optab_libfunc (optab optab, machine_mode mode)
     107                 :             : {
     108                 :     1929591 :   struct libfunc_entry e;
     109                 :     1929591 :   struct libfunc_entry **slot;
     110                 :             : 
     111                 :             :   /* ??? This ought to be an assert, but not all of the places
     112                 :             :      that we expand optabs know about the optabs that got moved
     113                 :             :      to being direct.  */
     114                 :     1929591 :   if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
     115                 :             :     return NULL_RTX;
     116                 :             : 
     117                 :     1378227 :   e.op = optab;
     118                 :     1378227 :   e.mode1 = mode;
     119                 :     1378227 :   e.mode2 = VOIDmode;
     120                 :     1378227 :   slot = libfunc_hash->find_slot (&e, NO_INSERT);
     121                 :     1378227 :   if (!slot)
     122                 :             :     {
     123                 :     1236722 :       const struct optab_libcall_d *d
     124                 :     1236722 :         = &normlib_def[optab - FIRST_NORM_OPTAB];
     125                 :             : 
     126                 :     1236722 :       if (d->libcall_gen == NULL)
     127                 :             :         return NULL;
     128                 :             : 
     129                 :     1015477 :       d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
     130                 :     1015477 :       slot = libfunc_hash->find_slot (&e, NO_INSERT);
     131                 :     1015477 :       if (!slot)
     132                 :             :         return NULL;
     133                 :             :     }
     134                 :      158494 :   return (*slot)->libfunc;
     135                 :             : }
     136                 :             : 
     137                 :             : /* Initialize the libfunc fields of an entire group of entries in some
     138                 :             :    optab.  Each entry is set equal to a string consisting of a leading
     139                 :             :    pair of underscores followed by a generic operation name followed by
     140                 :             :    a mode name (downshifted to lowercase) followed by a single character
     141                 :             :    representing the number of operands for the given operation (which is
     142                 :             :    usually one of the characters '2', '3', or '4').
     143                 :             : 
     144                 :             :    OPTABLE is the table in which libfunc fields are to be initialized.
     145                 :             :    OPNAME is the generic (string) name of the operation.
     146                 :             :    SUFFIX is the character which specifies the number of operands for
     147                 :             :      the given generic operation.
     148                 :             :    MODE is the mode to generate for.  */
     149                 :             : 
     150                 :             : static void
     151                 :       16989 : gen_libfunc (optab optable, const char *opname, int suffix,
     152                 :             :              machine_mode mode)
     153                 :             : {
     154                 :       16989 :   unsigned opname_len = strlen (opname);
     155                 :       16989 :   const char *mname = GET_MODE_NAME (mode);
     156                 :       16989 :   unsigned mname_len = strlen (mname);
     157                 :       16989 :   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
     158                 :       16989 :   int len = prefix_len + opname_len + mname_len + 1 + 1;
     159                 :       16989 :   char *libfunc_name = XALLOCAVEC (char, len);
     160                 :       16989 :   char *p;
     161                 :       16989 :   const char *q;
     162                 :             : 
     163                 :       16989 :   p = libfunc_name;
     164                 :       16989 :   *p++ = '_';
     165                 :       16989 :   *p++ = '_';
     166                 :       16989 :   if (targetm.libfunc_gnu_prefix)
     167                 :             :     {
     168                 :           0 :       *p++ = 'g';
     169                 :           0 :       *p++ = 'n';
     170                 :           0 :       *p++ = 'u';
     171                 :           0 :       *p++ = '_';
     172                 :             :     }
     173                 :       80792 :   for (q = opname; *q;)
     174                 :       63803 :     *p++ = *q++;
     175                 :       50967 :   for (q = mname; *q; q++)
     176                 :       33978 :     *p++ = TOLOWER (*q);
     177                 :       16989 :   *p++ = suffix;
     178                 :       16989 :   *p = '\0';
     179                 :             : 
     180                 :       16989 :   set_optab_libfunc (optable, mode,
     181                 :       16989 :                      ggc_alloc_string (libfunc_name, p - libfunc_name));
     182                 :       16989 : }
     183                 :             : 
     184                 :             : /* Like gen_libfunc, but verify that integer operation is involved.  */
     185                 :             : 
     186                 :             : void
     187                 :     1008308 : gen_int_libfunc (optab optable, const char *opname, char suffix,
     188                 :             :                  machine_mode mode)
     189                 :             : {
     190                 :     1008308 :   int maxsize = 2 * BITS_PER_WORD;
     191                 :     1008308 :   int minsize = BITS_PER_WORD;
     192                 :     1008308 :   scalar_int_mode int_mode;
     193                 :             : 
     194                 :     1008308 :   if (!is_int_mode (mode, &int_mode))
     195                 :     1008308 :     return;
     196                 :       37588 :   if (maxsize < LONG_LONG_TYPE_SIZE)
     197                 :             :     maxsize = LONG_LONG_TYPE_SIZE;
     198                 :       37588 :   if (minsize > INT_TYPE_SIZE
     199                 :       37588 :       && (trapv_binoptab_p (optable)
     200                 :       36526 :           || trapv_unoptab_p (optable)))
     201                 :             :     minsize = INT_TYPE_SIZE;
     202                 :       37588 :   if (GET_MODE_BITSIZE (int_mode) < minsize
     203                 :       49040 :       || GET_MODE_BITSIZE (int_mode) > maxsize)
     204                 :             :     return;
     205                 :       11452 :   gen_libfunc (optable, opname, suffix, int_mode);
     206                 :             : }
     207                 :             : 
     208                 :             : /* Like gen_libfunc, but verify that FP and set decimal prefix if needed.  */
     209                 :             : 
     210                 :             : void
     211                 :        5537 : gen_fp_libfunc (optab optable, const char *opname, char suffix,
     212                 :             :                 machine_mode mode)
     213                 :             : {
     214                 :        5537 :   char *dec_opname;
     215                 :             : 
     216                 :        5537 :   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
     217                 :        3727 :     gen_libfunc (optable, opname, suffix, mode);
     218                 :        5537 :   if (DECIMAL_FLOAT_MODE_P (mode))
     219                 :             :     {
     220                 :        1810 :       dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
     221                 :             :       /* For BID support, change the name to have either a bid_ or dpd_ prefix
     222                 :             :          depending on the low level floating format used.  */
     223                 :        1810 :       memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
     224                 :        1810 :       strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
     225                 :        1810 :       gen_libfunc (optable, dec_opname, suffix, mode);
     226                 :             :     }
     227                 :        5537 : }
     228                 :             : 
     229                 :             : /* Like gen_libfunc, but verify that fixed-point operation is involved.  */
     230                 :             : 
     231                 :             : void
     232                 :           0 : gen_fixed_libfunc (optab optable, const char *opname, char suffix,
     233                 :             :                    machine_mode mode)
     234                 :             : {
     235                 :           0 :   if (!ALL_FIXED_POINT_MODE_P (mode))
     236                 :             :     return;
     237                 :           0 :   gen_libfunc (optable, opname, suffix, mode);
     238                 :             : }
     239                 :             : 
     240                 :             : /* Like gen_libfunc, but verify that signed fixed-point operation is
     241                 :             :    involved.  */
     242                 :             : 
     243                 :             : void
     244                 :           0 : gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
     245                 :             :                           machine_mode mode)
     246                 :             : {
     247                 :           0 :   if (!SIGNED_FIXED_POINT_MODE_P (mode))
     248                 :             :     return;
     249                 :           0 :   gen_libfunc (optable, opname, suffix, mode);
     250                 :             : }
     251                 :             : 
     252                 :             : /* Like gen_libfunc, but verify that unsigned fixed-point operation is
     253                 :             :    involved.  */
     254                 :             : 
     255                 :             : void
     256                 :           0 : gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
     257                 :             :                             machine_mode mode)
     258                 :             : {
     259                 :           0 :   if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
     260                 :             :     return;
     261                 :           0 :   gen_libfunc (optable, opname, suffix, mode);
     262                 :             : }
     263                 :             : 
     264                 :             : /* Like gen_libfunc, but verify that FP or INT operation is involved.  */
     265                 :             : 
     266                 :             : void
     267                 :        8168 : gen_int_fp_libfunc (optab optable, const char *name, char suffix,
     268                 :             :                     machine_mode mode)
     269                 :             : {
     270                 :        8168 :   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
     271                 :          27 :     gen_fp_libfunc (optable, name, suffix, mode);
     272                 :        8168 :   if (INTEGRAL_MODE_P (mode))
     273                 :        8141 :     gen_int_libfunc (optable, name, suffix, mode);
     274                 :        8168 : }
     275                 :             : 
     276                 :             : /* Like gen_libfunc, but verify that FP or INT operation is involved
     277                 :             :    and add 'v' suffix for integer operation.  */
     278                 :             : 
     279                 :             : void
     280                 :         117 : gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
     281                 :             :                      machine_mode mode)
     282                 :             : {
     283                 :         117 :   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
     284                 :           0 :     gen_fp_libfunc (optable, name, suffix, mode);
     285                 :         117 :   if (GET_MODE_CLASS (mode) == MODE_INT)
     286                 :             :     {
     287                 :         117 :       int len = strlen (name);
     288                 :         117 :       char *v_name = XALLOCAVEC (char, len + 2);
     289                 :         117 :       strcpy (v_name, name);
     290                 :         117 :       v_name[len] = 'v';
     291                 :         117 :       v_name[len + 1] = 0;
     292                 :         117 :       gen_int_libfunc (optable, v_name, suffix, mode);
     293                 :             :     }
     294                 :         117 : }
     295                 :             : 
     296                 :             : /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
     297                 :             :    involved.  */
     298                 :             : 
     299                 :             : void
     300                 :      674408 : gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
     301                 :             :                           machine_mode mode)
     302                 :             : {
     303                 :      674408 :   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
     304                 :        1846 :     gen_fp_libfunc (optable, name, suffix, mode);
     305                 :      674408 :   if (INTEGRAL_MODE_P (mode))
     306                 :      671098 :     gen_int_libfunc (optable, name, suffix, mode);
     307                 :      674408 :   if (ALL_FIXED_POINT_MODE_P (mode))
     308                 :           0 :     gen_fixed_libfunc (optable, name, suffix, mode);
     309                 :      674408 : }
     310                 :             : 
     311                 :             : /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
     312                 :             :    involved.  */
     313                 :             : 
     314                 :             : void
     315                 :       33221 : gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
     316                 :             :                                  machine_mode mode)
     317                 :             : {
     318                 :       33221 :   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
     319                 :         350 :     gen_fp_libfunc (optable, name, suffix, mode);
     320                 :       33221 :   if (INTEGRAL_MODE_P (mode))
     321                 :       32862 :     gen_int_libfunc (optable, name, suffix, mode);
     322                 :       33221 :   if (SIGNED_FIXED_POINT_MODE_P (mode))
     323                 :           0 :     gen_signed_fixed_libfunc (optable, name, suffix, mode);
     324                 :       33221 : }
     325                 :             : 
     326                 :             : /* Like gen_libfunc, but verify that INT or FIXED operation is
     327                 :             :    involved.  */
     328                 :             : 
     329                 :             : void
     330                 :      206741 : gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
     331                 :             :                        machine_mode mode)
     332                 :             : {
     333                 :      206741 :   if (INTEGRAL_MODE_P (mode))
     334                 :      206741 :     gen_int_libfunc (optable, name, suffix, mode);
     335                 :      206741 :   if (ALL_FIXED_POINT_MODE_P (mode))
     336                 :           0 :     gen_fixed_libfunc (optable, name, suffix, mode);
     337                 :      206741 : }
     338                 :             : 
     339                 :             : /* Like gen_libfunc, but verify that INT or signed FIXED operation is
     340                 :             :    involved.  */
     341                 :             : 
     342                 :             : void
     343                 :         352 : gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
     344                 :             :                               machine_mode mode)
     345                 :             : {
     346                 :         352 :   if (INTEGRAL_MODE_P (mode))
     347                 :         220 :     gen_int_libfunc (optable, name, suffix, mode);
     348                 :         352 :   if (SIGNED_FIXED_POINT_MODE_P (mode))
     349                 :           0 :     gen_signed_fixed_libfunc (optable, name, suffix, mode);
     350                 :         352 : }
     351                 :             : 
     352                 :             : /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
     353                 :             :    involved.  */
     354                 :             : 
     355                 :             : void
     356                 :       30456 : gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
     357                 :             :                                 machine_mode mode)
     358                 :             : {
     359                 :       30456 :   if (INTEGRAL_MODE_P (mode))
     360                 :       30429 :     gen_int_libfunc (optable, name, suffix, mode);
     361                 :       30456 :   if (UNSIGNED_FIXED_POINT_MODE_P (mode))
     362                 :           0 :     gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
     363                 :       30456 : }
     364                 :             : 
     365                 :             : /* Initialize the libfunc fields of an entire group of entries of an
     366                 :             :    inter-mode-class conversion optab.  The string formation rules are
     367                 :             :    similar to the ones for init_libfuncs, above, but instead of having
     368                 :             :    a mode name and an operand count these functions have two mode names
     369                 :             :    and no operand count.  */
     370                 :             : 
     371                 :             : void
     372                 :        2076 : gen_interclass_conv_libfunc (convert_optab tab,
     373                 :             :                              const char *opname,
     374                 :             :                              machine_mode tmode,
     375                 :             :                              machine_mode fmode)
     376                 :             : {
     377                 :        2076 :   size_t opname_len = strlen (opname);
     378                 :        2076 :   size_t mname_len = 0;
     379                 :             : 
     380                 :        2076 :   const char *fname, *tname;
     381                 :        2076 :   const char *q;
     382                 :        2076 :   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
     383                 :        2076 :   char *libfunc_name, *suffix;
     384                 :        2076 :   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
     385                 :        2076 :   char *p;
     386                 :             : 
     387                 :             :   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
     388                 :             :      depends on which underlying decimal floating point format is used.  */
     389                 :        2076 :   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
     390                 :             : 
     391                 :        2076 :   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
     392                 :             : 
     393                 :        2076 :   nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
     394                 :        2076 :   nondec_name[0] = '_';
     395                 :        2076 :   nondec_name[1] = '_';
     396                 :        2076 :   if (targetm.libfunc_gnu_prefix)
     397                 :             :     {
     398                 :           0 :       nondec_name[2] = 'g';
     399                 :           0 :       nondec_name[3] = 'n';
     400                 :           0 :       nondec_name[4] = 'u';
     401                 :           0 :       nondec_name[5] = '_';
     402                 :             :     }
     403                 :             : 
     404                 :        2076 :   memcpy (&nondec_name[prefix_len], opname, opname_len);
     405                 :        2076 :   nondec_suffix = nondec_name + opname_len + prefix_len;
     406                 :             : 
     407                 :        2076 :   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
     408                 :        2076 :   dec_name[0] = '_';
     409                 :        2076 :   dec_name[1] = '_';
     410                 :        2076 :   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
     411                 :        2076 :   memcpy (&dec_name[2+dec_len], opname, opname_len);
     412                 :        2076 :   dec_suffix = dec_name + dec_len + opname_len + 2;
     413                 :             : 
     414                 :        2076 :   fname = GET_MODE_NAME (fmode);
     415                 :        2076 :   tname = GET_MODE_NAME (tmode);
     416                 :             : 
     417                 :        2076 :   if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
     418                 :             :     {
     419                 :             :       libfunc_name = dec_name;
     420                 :             :       suffix = dec_suffix;
     421                 :             :     }
     422                 :             :   else
     423                 :             :     {
     424                 :        2076 :       libfunc_name = nondec_name;
     425                 :        2076 :       suffix = nondec_suffix;
     426                 :             :     }
     427                 :             : 
     428                 :        2076 :   p = suffix;
     429                 :        6228 :   for (q = fname; *q; p++, q++)
     430                 :        4152 :     *p = TOLOWER (*q);
     431                 :        6228 :   for (q = tname; *q; p++, q++)
     432                 :        4152 :     *p = TOLOWER (*q);
     433                 :             : 
     434                 :        2076 :   *p = '\0';
     435                 :             : 
     436                 :        2076 :   set_conv_libfunc (tab, tmode, fmode,
     437                 :        2076 :                     ggc_alloc_string (libfunc_name, p - libfunc_name));
     438                 :        2076 : }
     439                 :             : 
     440                 :             : /* Same as gen_interclass_conv_libfunc but verify that we are producing
     441                 :             :    int->fp conversion.  */
     442                 :             : 
     443                 :             : void
     444                 :         734 : gen_int_to_fp_conv_libfunc (convert_optab tab,
     445                 :             :                             const char *opname,
     446                 :             :                             machine_mode tmode,
     447                 :             :                             machine_mode fmode)
     448                 :             : {
     449                 :         734 :   if (GET_MODE_CLASS (fmode) != MODE_INT)
     450                 :             :     return;
     451                 :         734 :   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
     452                 :             :     return;
     453                 :         734 :   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     454                 :             : }
     455                 :             : 
     456                 :             : /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
     457                 :             :    naming scheme.  */
     458                 :             : 
     459                 :             : void
     460                 :         265 : gen_ufloat_conv_libfunc (convert_optab tab,
     461                 :             :                          const char *opname ATTRIBUTE_UNUSED,
     462                 :             :                          machine_mode tmode,
     463                 :             :                          machine_mode fmode)
     464                 :             : {
     465                 :         265 :   if (DECIMAL_FLOAT_MODE_P (tmode))
     466                 :          79 :     gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
     467                 :             :   else
     468                 :         186 :     gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
     469                 :         265 : }
     470                 :             : 
     471                 :             : /* Same as gen_interclass_conv_libfunc but verify that we are producing
     472                 :             :    fp->int conversion.  */
     473                 :             : 
     474                 :             : void
     475                 :           0 : gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
     476                 :             :                                        const char *opname,
     477                 :             :                                        machine_mode tmode,
     478                 :             :                                        machine_mode fmode)
     479                 :             : {
     480                 :           0 :   if (GET_MODE_CLASS (fmode) != MODE_INT)
     481                 :             :     return;
     482                 :           0 :   if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
     483                 :             :     return;
     484                 :           0 :   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     485                 :             : }
     486                 :             : 
     487                 :             : /* Same as gen_interclass_conv_libfunc but verify that we are producing
     488                 :             :    fp->int conversion with no decimal floating point involved.  */
     489                 :             : 
     490                 :             : void
     491                 :         717 : gen_fp_to_int_conv_libfunc (convert_optab tab,
     492                 :             :                             const char *opname,
     493                 :             :                             machine_mode tmode,
     494                 :             :                             machine_mode fmode)
     495                 :             : {
     496                 :         717 :   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
     497                 :             :     return;
     498                 :         717 :   if (GET_MODE_CLASS (tmode) != MODE_INT)
     499                 :             :     return;
     500                 :         717 :   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     501                 :             : }
     502                 :             : 
     503                 :             : /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
     504                 :             :    The string formation rules are
     505                 :             :    similar to the ones for init_libfunc, above.  */
     506                 :             : 
     507                 :             : void
     508                 :        1099 : gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
     509                 :             :                              machine_mode tmode, machine_mode fmode)
     510                 :             : {
     511                 :        1099 :   size_t opname_len = strlen (opname);
     512                 :        1099 :   size_t mname_len = 0;
     513                 :             : 
     514                 :        1099 :   const char *fname, *tname;
     515                 :        1099 :   const char *q;
     516                 :        1099 :   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
     517                 :        1099 :   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
     518                 :        1099 :   char *libfunc_name, *suffix;
     519                 :        1099 :   char *p;
     520                 :             : 
     521                 :             :   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
     522                 :             :      depends on which underlying decimal floating point format is used.  */
     523                 :        1099 :   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
     524                 :             : 
     525                 :        1099 :   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
     526                 :             : 
     527                 :        1099 :   nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
     528                 :        1099 :   nondec_name[0] = '_';
     529                 :        1099 :   nondec_name[1] = '_';
     530                 :        1099 :   if (targetm.libfunc_gnu_prefix)
     531                 :             :     {
     532                 :           0 :       nondec_name[2] = 'g';
     533                 :           0 :       nondec_name[3] = 'n';
     534                 :           0 :       nondec_name[4] = 'u';
     535                 :           0 :       nondec_name[5] = '_';
     536                 :             :     }
     537                 :        1099 :   memcpy (&nondec_name[prefix_len], opname, opname_len);
     538                 :        1099 :   nondec_suffix = nondec_name + opname_len + prefix_len;
     539                 :             : 
     540                 :        1099 :   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
     541                 :        1099 :   dec_name[0] = '_';
     542                 :        1099 :   dec_name[1] = '_';
     543                 :        1099 :   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
     544                 :        1099 :   memcpy (&dec_name[2 + dec_len], opname, opname_len);
     545                 :        1099 :   dec_suffix = dec_name + dec_len + opname_len + 2;
     546                 :             : 
     547                 :        1099 :   fname = GET_MODE_NAME (fmode);
     548                 :        1099 :   tname = GET_MODE_NAME (tmode);
     549                 :             : 
     550                 :        1099 :   if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
     551                 :             :     {
     552                 :             :       libfunc_name = dec_name;
     553                 :             :       suffix = dec_suffix;
     554                 :             :     }
     555                 :             :   else
     556                 :             :     {
     557                 :        1099 :       libfunc_name = nondec_name;
     558                 :        1099 :       suffix = nondec_suffix;
     559                 :             :     }
     560                 :             : 
     561                 :        1099 :   p = suffix;
     562                 :        3297 :   for (q = fname; *q; p++, q++)
     563                 :        2198 :     *p = TOLOWER (*q);
     564                 :        3297 :   for (q = tname; *q; p++, q++)
     565                 :        2198 :     *p = TOLOWER (*q);
     566                 :             : 
     567                 :        1099 :   *p++ = '2';
     568                 :        1099 :   *p = '\0';
     569                 :             : 
     570                 :        1099 :   set_conv_libfunc (tab, tmode, fmode,
     571                 :        1099 :                     ggc_alloc_string (libfunc_name, p - libfunc_name));
     572                 :        1099 : }
     573                 :             : 
     574                 :             : /* Pick proper libcall for trunc_optab.  We need to chose if we do
     575                 :             :    truncation or extension and interclass or intraclass.  */
     576                 :             : 
     577                 :             : void
     578                 :         838 : gen_trunc_conv_libfunc (convert_optab tab,
     579                 :             :                         const char *opname,
     580                 :             :                         machine_mode tmode,
     581                 :             :                         machine_mode fmode)
     582                 :             : {
     583                 :         838 :   scalar_float_mode float_tmode, float_fmode;
     584                 :         838 :   if (!is_a <scalar_float_mode> (fmode, &float_fmode)
     585                 :        1676 :       || !is_a <scalar_float_mode> (tmode, &float_tmode)
     586                 :         838 :       || float_tmode == float_fmode)
     587                 :         838 :     return;
     588                 :             : 
     589                 :         838 :   if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
     590                 :         328 :     gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
     591                 :             : 
     592                 :         838 :   if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)
     593                 :          87 :       && (REAL_MODE_FORMAT (float_tmode) != &arm_bfloat_half_format
     594                 :           1 :           || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format)
     595                 :          86 :       && (REAL_MODE_FORMAT (float_tmode) != &ieee_quad_format
     596                 :           0 :           || REAL_MODE_FORMAT (float_fmode) != &ibm_extended_format))
     597                 :             :     return;
     598                 :             : 
     599                 :         752 :   if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
     600                 :         510 :     gen_intraclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
     601                 :             : }
     602                 :             : 
     603                 :             : /* Pick proper libcall for extend_optab.  We need to chose if we do
     604                 :             :    truncation or extension and interclass or intraclass.  */
     605                 :             : 
     606                 :             : void
     607                 :         886 : gen_extend_conv_libfunc (convert_optab tab,
     608                 :             :                          const char *opname ATTRIBUTE_UNUSED,
     609                 :             :                          machine_mode tmode,
     610                 :             :                          machine_mode fmode)
     611                 :             : {
     612                 :         886 :   scalar_float_mode float_tmode, float_fmode;
     613                 :         886 :   if (!is_a <scalar_float_mode> (fmode, &float_fmode)
     614                 :        1772 :       || !is_a <scalar_float_mode> (tmode, &float_tmode)
     615                 :         886 :       || float_tmode == float_fmode)
     616                 :         886 :     return;
     617                 :             : 
     618                 :         886 :   if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
     619                 :         297 :     gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
     620                 :             : 
     621                 :         886 :   if (GET_MODE_PRECISION (float_fmode) > GET_MODE_PRECISION (float_tmode))
     622                 :             :     return;
     623                 :             : 
     624                 :         886 :   if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
     625                 :         589 :     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
     626                 :             : }
     627                 :             : 
     628                 :             : /* Pick proper libcall for fract_optab.  We need to chose if we do
     629                 :             :    interclass or intraclass.  */
     630                 :             : 
     631                 :             : void
     632                 :           0 : gen_fract_conv_libfunc (convert_optab tab,
     633                 :             :                         const char *opname,
     634                 :             :                         machine_mode tmode,
     635                 :             :                         machine_mode fmode)
     636                 :             : {
     637                 :           0 :   if (tmode == fmode)
     638                 :             :     return;
     639                 :           0 :   if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
     640                 :             :     return;
     641                 :             : 
     642                 :           0 :   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
     643                 :           0 :     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
     644                 :             :   else
     645                 :           0 :     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     646                 :             : }
     647                 :             : 
     648                 :             : /* Pick proper libcall for fractuns_optab.  */
     649                 :             : 
     650                 :             : void
     651                 :           0 : gen_fractuns_conv_libfunc (convert_optab tab,
     652                 :             :                            const char *opname,
     653                 :             :                            machine_mode tmode,
     654                 :             :                            machine_mode fmode)
     655                 :             : {
     656                 :           0 :   if (tmode == fmode)
     657                 :             :     return;
     658                 :             :   /* One mode must be a fixed-point mode, and the other must be an integer
     659                 :             :      mode.  */
     660                 :           0 :   if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
     661                 :           0 :         || (ALL_FIXED_POINT_MODE_P (fmode)
     662                 :           0 :             && GET_MODE_CLASS (tmode) == MODE_INT)))
     663                 :             :     return;
     664                 :             : 
     665                 :           0 :   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     666                 :             : }
     667                 :             : 
     668                 :             : /* Pick proper libcall for satfract_optab.  We need to chose if we do
     669                 :             :    interclass or intraclass.  */
     670                 :             : 
     671                 :             : void
     672                 :           0 : gen_satfract_conv_libfunc (convert_optab tab,
     673                 :             :                            const char *opname,
     674                 :             :                            machine_mode tmode,
     675                 :             :                            machine_mode fmode)
     676                 :             : {
     677                 :           0 :   if (tmode == fmode)
     678                 :             :     return;
     679                 :             :   /* TMODE must be a fixed-point mode.  */
     680                 :           0 :   if (!ALL_FIXED_POINT_MODE_P (tmode))
     681                 :             :     return;
     682                 :             : 
     683                 :           0 :   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
     684                 :           0 :     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
     685                 :             :   else
     686                 :           0 :     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     687                 :             : }
     688                 :             : 
     689                 :             : /* Pick proper libcall for satfractuns_optab.  */
     690                 :             : 
     691                 :             : void
     692                 :           0 : gen_satfractuns_conv_libfunc (convert_optab tab,
     693                 :             :                               const char *opname,
     694                 :             :                               machine_mode tmode,
     695                 :             :                               machine_mode fmode)
     696                 :             : {
     697                 :           0 :   if (tmode == fmode)
     698                 :             :     return;
     699                 :             :   /* TMODE must be a fixed-point mode, and FMODE must be an integer mode.  */
     700                 :           0 :   if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
     701                 :             :     return;
     702                 :             : 
     703                 :           0 :   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
     704                 :             : }
     705                 :             : 
     706                 :             : /* Hashtable callbacks for libfunc_decls.  */
     707                 :             : 
     708                 :             : struct libfunc_decl_hasher : ggc_ptr_hash<tree_node>
     709                 :             : {
     710                 :             :   static hashval_t
     711                 :     4667824 :   hash (tree entry)
     712                 :             :   {
     713                 :     4667824 :     return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
     714                 :             :   }
     715                 :             : 
     716                 :             :   static bool
     717                 :     9387971 :   equal (tree decl, tree name)
     718                 :             :   {
     719                 :     9387971 :     return DECL_NAME (decl) == name;
     720                 :             :   }
     721                 :             : };
     722                 :             : 
     723                 :             : /* A table of previously-created libfuncs, hashed by name.  */
     724                 :             : static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
     725                 :             : 
     726                 :             : /* Build a decl for a libfunc named NAME with visibility VIS.  */
     727                 :             : 
     728                 :             : tree
     729                 :     2227192 : build_libfunc_function_visibility (const char *name, symbol_visibility vis)
     730                 :             : {
     731                 :             :   /* ??? We don't have any type information; pretend this is "int foo ()".  */
     732                 :     2227192 :   tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
     733                 :             :                           get_identifier (name),
     734                 :             :                           build_function_type (integer_type_node, NULL_TREE));
     735                 :     2227192 :   DECL_EXTERNAL (decl) = 1;
     736                 :     2227192 :   TREE_PUBLIC (decl) = 1;
     737                 :     2227192 :   DECL_ARTIFICIAL (decl) = 1;
     738                 :     2227192 :   DECL_VISIBILITY (decl) = vis;
     739                 :     2227192 :   DECL_VISIBILITY_SPECIFIED (decl) = 1;
     740                 :     2227192 :   gcc_assert (DECL_ASSEMBLER_NAME (decl));
     741                 :             : 
     742                 :     2227192 :   return decl;
     743                 :             : }
     744                 :             : 
     745                 :             : /* Build a decl for a libfunc named NAME.  */
     746                 :             : 
     747                 :             : tree
     748                 :           0 : build_libfunc_function (const char *name)
     749                 :             : {
     750                 :           0 :   return build_libfunc_function_visibility (name, VISIBILITY_DEFAULT);
     751                 :             : }
     752                 :             : 
     753                 :             : /* Return a libfunc for NAME, creating one if we don't already have one.
     754                 :             :    The decl is given visibility VIS.  The returned rtx is a SYMBOL_REF.  */
     755                 :             : 
     756                 :             : rtx
     757                 :     6658638 : init_one_libfunc_visibility (const char *name, symbol_visibility vis)
     758                 :             : {
     759                 :     6658638 :   tree id, decl;
     760                 :     6658638 :   hashval_t hash;
     761                 :             : 
     762                 :     6658638 :   if (libfunc_decls == NULL)
     763                 :      276515 :     libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
     764                 :             : 
     765                 :             :   /* See if we have already created a libfunc decl for this function.  */
     766                 :     6658638 :   id = get_identifier (name);
     767                 :     6658638 :   hash = IDENTIFIER_HASH_VALUE (id);
     768                 :     6658638 :   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
     769                 :     6658638 :   decl = *slot;
     770                 :     6658638 :   if (decl == NULL)
     771                 :             :     {
     772                 :             :       /* Create a new decl, so that it can be passed to
     773                 :             :          targetm.encode_section_info.  */
     774                 :     2227192 :       decl = build_libfunc_function_visibility (name, vis);
     775                 :     2227192 :       *slot = decl;
     776                 :             :     }
     777                 :     6658638 :   return XEXP (DECL_RTL (decl), 0);
     778                 :             : }
     779                 :             : 
     780                 :             : rtx
     781                 :     6658638 : init_one_libfunc (const char *name)
     782                 :             : {
     783                 :     6658638 :   return init_one_libfunc_visibility (name, VISIBILITY_DEFAULT);
     784                 :             : }
     785                 :             : 
     786                 :             : /* Adjust the assembler name of libfunc NAME to ASMSPEC.  */
     787                 :             : 
     788                 :             : rtx
     789                 :           1 : set_user_assembler_libfunc (const char *name, const char *asmspec)
     790                 :             : {
     791                 :           1 :   tree id, decl;
     792                 :           1 :   hashval_t hash;
     793                 :             : 
     794                 :           1 :   id = get_identifier (name);
     795                 :           1 :   hash = IDENTIFIER_HASH_VALUE (id);
     796                 :           1 :   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
     797                 :           1 :   gcc_assert (slot);
     798                 :           1 :   decl = (tree) *slot;
     799                 :           1 :   set_user_assembler_name (decl, asmspec);
     800                 :           1 :   return XEXP (DECL_RTL (decl), 0);
     801                 :             : }
     802                 :             : 
     803                 :             : /* Call this to reset the function entry for one optab (OPTABLE) in mode
     804                 :             :    MODE to NAME, which should be either 0 or a string constant.  */
     805                 :             : 
     806                 :             : void
     807                 :     4989000 : set_optab_libfunc (optab op, machine_mode mode, const char *name)
     808                 :             : {
     809                 :     4989000 :   rtx val;
     810                 :     4989000 :   struct libfunc_entry e;
     811                 :     4989000 :   struct libfunc_entry **slot;
     812                 :             : 
     813                 :     4989000 :   e.op = op;
     814                 :     4989000 :   e.mode1 = mode;
     815                 :     4989000 :   e.mode2 = VOIDmode;
     816                 :             : 
     817                 :     4989000 :   if (name)
     818                 :     4989000 :     val = init_one_libfunc (name);
     819                 :             :   else
     820                 :             :     val = 0;
     821                 :     4989000 :   slot = libfunc_hash->find_slot (&e, INSERT);
     822                 :     4989000 :   if (*slot == NULL)
     823                 :     4988999 :     *slot = ggc_alloc<libfunc_entry> ();
     824                 :     4989000 :   (*slot)->op = op;
     825                 :     4989000 :   (*slot)->mode1 = mode;
     826                 :     4989000 :   (*slot)->mode2 = VOIDmode;
     827                 :     4989000 :   (*slot)->libfunc = val;
     828                 :     4989000 : }
     829                 :             : 
     830                 :             : /* Call this to reset the function entry for one conversion optab
     831                 :             :    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
     832                 :             :    either 0 or a string constant.  */
     833                 :             : 
     834                 :             : void
     835                 :        3175 : set_conv_libfunc (convert_optab optab, machine_mode tmode,
     836                 :             :                   machine_mode fmode, const char *name)
     837                 :             : {
     838                 :        3175 :   rtx val;
     839                 :        3175 :   struct libfunc_entry e;
     840                 :        3175 :   struct libfunc_entry **slot;
     841                 :             : 
     842                 :        3175 :   e.op = optab;
     843                 :        3175 :   e.mode1 = tmode;
     844                 :        3175 :   e.mode2 = fmode;
     845                 :             : 
     846                 :        3175 :   if (name)
     847                 :        3175 :     val = init_one_libfunc (name);
     848                 :             :   else
     849                 :             :     val = 0;
     850                 :        3175 :   slot = libfunc_hash->find_slot (&e, INSERT);
     851                 :        3175 :   if (*slot == NULL)
     852                 :        3175 :     *slot = ggc_alloc<libfunc_entry> ();
     853                 :        3175 :   (*slot)->op = optab;
     854                 :        3175 :   (*slot)->mode1 = tmode;
     855                 :        3175 :   (*slot)->mode2 = fmode;
     856                 :        3175 :   (*slot)->libfunc = val;
     857                 :        3175 : }
     858                 :             : 
     859                 :             : /* Call this to initialize the contents of the optabs
     860                 :             :    appropriately for the current target machine.  */
     861                 :             : 
     862                 :             : void
     863                 :      831223 : init_optabs (void)
     864                 :             : {
     865                 :      831223 :   if (libfunc_hash)
     866                 :           0 :     libfunc_hash->empty ();
     867                 :             :   else
     868                 :      831223 :     libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
     869                 :             : 
     870                 :             :   /* Fill in the optabs with the insns we support.  */
     871                 :      831223 :   init_all_optabs (this_fn_optabs);
     872                 :             : 
     873                 :             :   /* The ffs function operates on `int'.  Fall back on it if we do not
     874                 :             :      have a libgcc2 function for that width.  */
     875                 :      831223 :   if (INT_TYPE_SIZE < BITS_PER_WORD)
     876                 :             :     {
     877                 :      815895 :       scalar_int_mode mode = int_mode_for_size (INT_TYPE_SIZE, 0).require ();
     878                 :      815895 :       set_optab_libfunc (ffs_optab, mode, "ffs");
     879                 :             :     }
     880                 :             : 
     881                 :             :   /* Explicitly initialize the bswap libfuncs since we need them to be
     882                 :             :      valid for things other than word_mode.  */
     883                 :      831223 :   if (targetm.libfunc_gnu_prefix)
     884                 :             :     {
     885                 :           0 :       set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
     886                 :           0 :       set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
     887                 :             :     }
     888                 :             :   else
     889                 :             :     {
     890                 :      831223 :       set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
     891                 :      831223 :       set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
     892                 :             :     }
     893                 :             : 
     894                 :             :   /* Use cabs for double complex abs, since systems generally have cabs.
     895                 :             :      Don't define any libcall for float complex, so that cabs will be used.  */
     896                 :      831223 :   if (complex_double_type_node)
     897                 :      831223 :     set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
     898                 :             :                        "cabs");
     899                 :             : 
     900                 :      831223 :   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
     901                 :      831223 :   unwind_sjlj_unregister_libfunc
     902                 :      831223 :     = init_one_libfunc ("_Unwind_SjLj_Unregister");
     903                 :             : 
     904                 :             :   /* Allow the target to add more libcalls or rename some, etc.  */
     905                 :      831223 :   targetm.init_libfuncs ();
     906                 :      831223 : }
     907                 :             : 
     908                 :             : /* A helper function for init_sync_libfuncs.  Using the basename BASE,
     909                 :             :    install libfuncs into TAB for BASE_N for 1 <= N <= MAX.  */
     910                 :             : 
     911                 :             : static void
     912                 :           0 : init_sync_libfuncs_1 (optab tab, const char *base, int max)
     913                 :             : {
     914                 :           0 :   machine_mode mode;
     915                 :           0 :   char buf[64];
     916                 :           0 :   size_t len = strlen (base);
     917                 :           0 :   int i;
     918                 :             : 
     919                 :           0 :   gcc_assert (max <= 8);
     920                 :           0 :   gcc_assert (len + 3 < sizeof (buf));
     921                 :             : 
     922                 :           0 :   memcpy (buf, base, len);
     923                 :           0 :   buf[len] = '_';
     924                 :           0 :   buf[len + 1] = '0';
     925                 :           0 :   buf[len + 2] = '\0';
     926                 :             : 
     927                 :           0 :   mode = QImode;
     928                 :           0 :   for (i = 1; i <= max; i *= 2)
     929                 :             :     {
     930                 :           0 :       if (i > 1)
     931                 :           0 :         mode = GET_MODE_2XWIDER_MODE (mode).require ();
     932                 :           0 :       buf[len + 1] = '0' + i;
     933                 :           0 :       set_optab_libfunc (tab, mode, buf);
     934                 :             :     }
     935                 :           0 : }
     936                 :             : 
     937                 :             : void
     938                 :           0 : init_sync_libfuncs (int max)
     939                 :             : {
     940                 :           0 :   if (!flag_sync_libcalls)
     941                 :             :     return;
     942                 :             : 
     943                 :           0 :   init_sync_libfuncs_1 (sync_compare_and_swap_optab,
     944                 :             :                         "__sync_val_compare_and_swap", max);
     945                 :           0 :   init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
     946                 :             :                         "__sync_lock_test_and_set", max);
     947                 :             : 
     948                 :           0 :   init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
     949                 :           0 :   init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
     950                 :           0 :   init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
     951                 :           0 :   init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
     952                 :           0 :   init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
     953                 :           0 :   init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
     954                 :             : 
     955                 :           0 :   init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
     956                 :           0 :   init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
     957                 :           0 :   init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
     958                 :           0 :   init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
     959                 :           0 :   init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
     960                 :           0 :   init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
     961                 :             : }
     962                 :             : 
     963                 :             : #include "gt-optabs-libfuncs.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.