Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / gcc / optabs-libfuncs.c
1 /* Mapping from optabs to underlying library functions
2    Copyright (C) 1987-2018 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 libfunc_hasher::hash (libfunc_entry *e)
54 {
55   return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
56 }
57
58 /* Used for libfunc_hash.  */
59
60 bool
61 libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2)
62 {
63   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 convert_optab_libfunc (convert_optab optab, machine_mode mode1,
71                        machine_mode mode2)
72 {
73   struct libfunc_entry e;
74   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   if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
80     return NULL_RTX;
81
82   e.op = optab;
83   e.mode1 = mode1;
84   e.mode2 = mode2;
85   slot = libfunc_hash->find_slot (&e, NO_INSERT);
86   if (!slot)
87     {
88       const struct convert_optab_libcall_d *d
89         = &convlib_def[optab - FIRST_CONV_OPTAB];
90
91       if (d->libcall_gen == NULL)
92         return NULL;
93
94       d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
95       slot = libfunc_hash->find_slot (&e, NO_INSERT);
96       if (!slot)
97         return NULL;
98     }
99   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 optab_libfunc (optab optab, machine_mode mode)
107 {
108   struct libfunc_entry e;
109   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   if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
115     return NULL_RTX;
116
117   e.op = optab;
118   e.mode1 = mode;
119   e.mode2 = VOIDmode;
120   slot = libfunc_hash->find_slot (&e, NO_INSERT);
121   if (!slot)
122     {
123       const struct optab_libcall_d *d
124         = &normlib_def[optab - FIRST_NORM_OPTAB];
125
126       if (d->libcall_gen == NULL)
127         return NULL;
128
129       d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
130       slot = libfunc_hash->find_slot (&e, NO_INSERT);
131       if (!slot)
132         return NULL;
133     }
134   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 gen_libfunc (optab optable, const char *opname, int suffix,
152              machine_mode mode)
153 {
154   unsigned opname_len = strlen (opname);
155   const char *mname = GET_MODE_NAME (mode);
156   unsigned mname_len = strlen (mname);
157   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
158   int len = prefix_len + opname_len + mname_len + 1 + 1;
159   char *libfunc_name = XALLOCAVEC (char, len);
160   char *p;
161   const char *q;
162
163   p = libfunc_name;
164   *p++ = '_';
165   *p++ = '_';
166   if (targetm.libfunc_gnu_prefix)
167     {
168       *p++ = 'g';
169       *p++ = 'n';
170       *p++ = 'u';
171       *p++ = '_';
172     }
173   for (q = opname; *q;)
174     *p++ = *q++;
175   for (q = mname; *q; q++)
176     *p++ = TOLOWER (*q);
177   *p++ = suffix;
178   *p = '\0';
179
180   set_optab_libfunc (optable, mode,
181                      ggc_alloc_string (libfunc_name, p - libfunc_name));
182 }
183
184 /* Like gen_libfunc, but verify that integer operation is involved.  */
185
186 void
187 gen_int_libfunc (optab optable, const char *opname, char suffix,
188                  machine_mode mode)
189 {
190   int maxsize = 2 * BITS_PER_WORD;
191   int minsize = BITS_PER_WORD;
192   scalar_int_mode int_mode;
193
194   if (!is_int_mode (mode, &int_mode))
195     return;
196   if (maxsize < LONG_LONG_TYPE_SIZE)
197     maxsize = LONG_LONG_TYPE_SIZE;
198   if (minsize > INT_TYPE_SIZE
199       && (trapv_binoptab_p (optable)
200           || trapv_unoptab_p (optable)))
201     minsize = INT_TYPE_SIZE;
202   if (GET_MODE_BITSIZE (int_mode) < minsize
203       || GET_MODE_BITSIZE (int_mode) > maxsize)
204     return;
205   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 gen_fp_libfunc (optab optable, const char *opname, char suffix,
212                 machine_mode mode)
213 {
214   char *dec_opname;
215
216   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
217     gen_libfunc (optable, opname, suffix, mode);
218   if (DECIMAL_FLOAT_MODE_P (mode))
219     {
220       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       memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
224       strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
225       gen_libfunc (optable, dec_opname, suffix, mode);
226     }
227 }
228
229 /* Like gen_libfunc, but verify that fixed-point operation is involved.  */
230
231 void
232 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
233                    machine_mode mode)
234 {
235   if (!ALL_FIXED_POINT_MODE_P (mode))
236     return;
237   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 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
245                           machine_mode mode)
246 {
247   if (!SIGNED_FIXED_POINT_MODE_P (mode))
248     return;
249   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 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
257                             machine_mode mode)
258 {
259   if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
260     return;
261   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 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
268                     machine_mode mode)
269 {
270   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
271     gen_fp_libfunc (optable, name, suffix, mode);
272   if (INTEGRAL_MODE_P (mode))
273     gen_int_libfunc (optable, name, suffix, mode);
274 }
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 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
281                      machine_mode mode)
282 {
283   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
284     gen_fp_libfunc (optable, name, suffix, mode);
285   if (GET_MODE_CLASS (mode) == MODE_INT)
286     {
287       int len = strlen (name);
288       char *v_name = XALLOCAVEC (char, len + 2);
289       strcpy (v_name, name);
290       v_name[len] = 'v';
291       v_name[len + 1] = 0;
292       gen_int_libfunc (optable, v_name, suffix, mode);
293     }
294 }
295
296 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
297    involved.  */
298
299 void
300 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
301                           machine_mode mode)
302 {
303   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
304     gen_fp_libfunc (optable, name, suffix, mode);
305   if (INTEGRAL_MODE_P (mode))
306     gen_int_libfunc (optable, name, suffix, mode);
307   if (ALL_FIXED_POINT_MODE_P (mode))
308     gen_fixed_libfunc (optable, name, suffix, mode);
309 }
310
311 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
312    involved.  */
313
314 void
315 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
316                                  machine_mode mode)
317 {
318   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
319     gen_fp_libfunc (optable, name, suffix, mode);
320   if (INTEGRAL_MODE_P (mode))
321     gen_int_libfunc (optable, name, suffix, mode);
322   if (SIGNED_FIXED_POINT_MODE_P (mode))
323     gen_signed_fixed_libfunc (optable, name, suffix, mode);
324 }
325
326 /* Like gen_libfunc, but verify that INT or FIXED operation is
327    involved.  */
328
329 void
330 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
331                        machine_mode mode)
332 {
333   if (INTEGRAL_MODE_P (mode))
334     gen_int_libfunc (optable, name, suffix, mode);
335   if (ALL_FIXED_POINT_MODE_P (mode))
336     gen_fixed_libfunc (optable, name, suffix, mode);
337 }
338
339 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
340    involved.  */
341
342 void
343 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
344                               machine_mode mode)
345 {
346   if (INTEGRAL_MODE_P (mode))
347     gen_int_libfunc (optable, name, suffix, mode);
348   if (SIGNED_FIXED_POINT_MODE_P (mode))
349     gen_signed_fixed_libfunc (optable, name, suffix, mode);
350 }
351
352 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
353    involved.  */
354
355 void
356 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
357                                 machine_mode mode)
358 {
359   if (INTEGRAL_MODE_P (mode))
360     gen_int_libfunc (optable, name, suffix, mode);
361   if (UNSIGNED_FIXED_POINT_MODE_P (mode))
362     gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
363 }
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 gen_interclass_conv_libfunc (convert_optab tab,
373                              const char *opname,
374                              machine_mode tmode,
375                              machine_mode fmode)
376 {
377   size_t opname_len = strlen (opname);
378   size_t mname_len = 0;
379
380   const char *fname, *tname;
381   const char *q;
382   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
383   char *libfunc_name, *suffix;
384   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
385   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   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
390
391   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
392
393   nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
394   nondec_name[0] = '_';
395   nondec_name[1] = '_';
396   if (targetm.libfunc_gnu_prefix)
397     {
398       nondec_name[2] = 'g';
399       nondec_name[3] = 'n';
400       nondec_name[4] = 'u';
401       nondec_name[5] = '_';
402     }
403
404   memcpy (&nondec_name[prefix_len], opname, opname_len);
405   nondec_suffix = nondec_name + opname_len + prefix_len;
406
407   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
408   dec_name[0] = '_';
409   dec_name[1] = '_';
410   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
411   memcpy (&dec_name[2+dec_len], opname, opname_len);
412   dec_suffix = dec_name + dec_len + opname_len + 2;
413
414   fname = GET_MODE_NAME (fmode);
415   tname = GET_MODE_NAME (tmode);
416
417   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       libfunc_name = nondec_name;
425       suffix = nondec_suffix;
426     }
427
428   p = suffix;
429   for (q = fname; *q; p++, q++)
430     *p = TOLOWER (*q);
431   for (q = tname; *q; p++, q++)
432     *p = TOLOWER (*q);
433
434   *p = '\0';
435
436   set_conv_libfunc (tab, tmode, fmode,
437                     ggc_alloc_string (libfunc_name, p - libfunc_name));
438 }
439
440 /* Same as gen_interclass_conv_libfunc but verify that we are producing
441    int->fp conversion.  */
442
443 void
444 gen_int_to_fp_conv_libfunc (convert_optab tab,
445                             const char *opname,
446                             machine_mode tmode,
447                             machine_mode fmode)
448 {
449   if (GET_MODE_CLASS (fmode) != MODE_INT)
450     return;
451   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
452     return;
453   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 gen_ufloat_conv_libfunc (convert_optab tab,
461                          const char *opname ATTRIBUTE_UNUSED,
462                          machine_mode tmode,
463                          machine_mode fmode)
464 {
465   if (DECIMAL_FLOAT_MODE_P (tmode))
466     gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
467   else
468     gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
469 }
470
471 /* Same as gen_interclass_conv_libfunc but verify that we are producing
472    fp->int conversion.  */
473
474 void
475 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
476                                        const char *opname,
477                                        machine_mode tmode,
478                                        machine_mode fmode)
479 {
480   if (GET_MODE_CLASS (fmode) != MODE_INT)
481     return;
482   if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
483     return;
484   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 gen_fp_to_int_conv_libfunc (convert_optab tab,
492                             const char *opname,
493                             machine_mode tmode,
494                             machine_mode fmode)
495 {
496   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
497     return;
498   if (GET_MODE_CLASS (tmode) != MODE_INT)
499     return;
500   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 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
509                              machine_mode tmode, machine_mode fmode)
510 {
511   size_t opname_len = strlen (opname);
512   size_t mname_len = 0;
513
514   const char *fname, *tname;
515   const char *q;
516   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
517   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
518   char *libfunc_name, *suffix;
519   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   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
524
525   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
526
527   nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
528   nondec_name[0] = '_';
529   nondec_name[1] = '_';
530   if (targetm.libfunc_gnu_prefix)
531     {
532       nondec_name[2] = 'g';
533       nondec_name[3] = 'n';
534       nondec_name[4] = 'u';
535       nondec_name[5] = '_';
536     }
537   memcpy (&nondec_name[prefix_len], opname, opname_len);
538   nondec_suffix = nondec_name + opname_len + prefix_len;
539
540   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
541   dec_name[0] = '_';
542   dec_name[1] = '_';
543   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
544   memcpy (&dec_name[2 + dec_len], opname, opname_len);
545   dec_suffix = dec_name + dec_len + opname_len + 2;
546
547   fname = GET_MODE_NAME (fmode);
548   tname = GET_MODE_NAME (tmode);
549
550   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       libfunc_name = nondec_name;
558       suffix = nondec_suffix;
559     }
560
561   p = suffix;
562   for (q = fname; *q; p++, q++)
563     *p = TOLOWER (*q);
564   for (q = tname; *q; p++, q++)
565     *p = TOLOWER (*q);
566
567   *p++ = '2';
568   *p = '\0';
569
570   set_conv_libfunc (tab, tmode, fmode,
571                     ggc_alloc_string (libfunc_name, p - libfunc_name));
572 }
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 gen_trunc_conv_libfunc (convert_optab tab,
579                         const char *opname,
580                         machine_mode tmode,
581                         machine_mode fmode)
582 {
583   scalar_float_mode float_tmode, float_fmode;
584   if (!is_a <scalar_float_mode> (fmode, &float_fmode)
585       || !is_a <scalar_float_mode> (tmode, &float_tmode)
586       || float_tmode == float_fmode)
587     return;
588
589   if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
590     gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
591
592   if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode))
593     return;
594
595   if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
596     gen_intraclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
597 }
598
599 /* Pick proper libcall for extend_optab.  We need to chose if we do
600    truncation or extension and interclass or intraclass.  */
601
602 void
603 gen_extend_conv_libfunc (convert_optab tab,
604                          const char *opname ATTRIBUTE_UNUSED,
605                          machine_mode tmode,
606                          machine_mode fmode)
607 {
608   scalar_float_mode float_tmode, float_fmode;
609   if (!is_a <scalar_float_mode> (fmode, &float_fmode)
610       || !is_a <scalar_float_mode> (tmode, &float_tmode)
611       || float_tmode == float_fmode)
612     return;
613
614   if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
615     gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
616
617   if (GET_MODE_PRECISION (float_fmode) > GET_MODE_PRECISION (float_tmode))
618     return;
619
620   if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
621     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
622 }
623
624 /* Pick proper libcall for fract_optab.  We need to chose if we do
625    interclass or intraclass.  */
626
627 void
628 gen_fract_conv_libfunc (convert_optab tab,
629                         const char *opname,
630                         machine_mode tmode,
631                         machine_mode fmode)
632 {
633   if (tmode == fmode)
634     return;
635   if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
636     return;
637
638   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
639     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
640   else
641     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
642 }
643
644 /* Pick proper libcall for fractuns_optab.  */
645
646 void
647 gen_fractuns_conv_libfunc (convert_optab tab,
648                            const char *opname,
649                            machine_mode tmode,
650                            machine_mode fmode)
651 {
652   if (tmode == fmode)
653     return;
654   /* One mode must be a fixed-point mode, and the other must be an integer
655      mode.  */
656   if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
657         || (ALL_FIXED_POINT_MODE_P (fmode)
658             && GET_MODE_CLASS (tmode) == MODE_INT)))
659     return;
660
661   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
662 }
663
664 /* Pick proper libcall for satfract_optab.  We need to chose if we do
665    interclass or intraclass.  */
666
667 void
668 gen_satfract_conv_libfunc (convert_optab tab,
669                            const char *opname,
670                            machine_mode tmode,
671                            machine_mode fmode)
672 {
673   if (tmode == fmode)
674     return;
675   /* TMODE must be a fixed-point mode.  */
676   if (!ALL_FIXED_POINT_MODE_P (tmode))
677     return;
678
679   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
680     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
681   else
682     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
683 }
684
685 /* Pick proper libcall for satfractuns_optab.  */
686
687 void
688 gen_satfractuns_conv_libfunc (convert_optab tab,
689                               const char *opname,
690                               machine_mode tmode,
691                               machine_mode fmode)
692 {
693   if (tmode == fmode)
694     return;
695   /* TMODE must be a fixed-point mode, and FMODE must be an integer mode.  */
696   if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
697     return;
698
699   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
700 }
701
702 /* Hashtable callbacks for libfunc_decls.  */
703
704 struct libfunc_decl_hasher : ggc_ptr_hash<tree_node>
705 {
706   static hashval_t
707   hash (tree entry)
708   {
709     return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
710   }
711
712   static bool
713   equal (tree decl, tree name)
714   {
715     return DECL_NAME (decl) == name;
716   }
717 };
718
719 /* A table of previously-created libfuncs, hashed by name.  */
720 static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
721
722 /* Build a decl for a libfunc named NAME.  */
723
724 tree
725 build_libfunc_function (const char *name)
726 {
727   /* ??? We don't have any type information; pretend this is "int foo ()".  */
728   tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
729                           get_identifier (name),
730                           build_function_type (integer_type_node, NULL_TREE));
731   DECL_EXTERNAL (decl) = 1;
732   TREE_PUBLIC (decl) = 1;
733   DECL_ARTIFICIAL (decl) = 1;
734   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
735   DECL_VISIBILITY_SPECIFIED (decl) = 1;
736   gcc_assert (DECL_ASSEMBLER_NAME (decl));
737
738   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
739      are the flags assigned by targetm.encode_section_info.  */
740   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
741
742   return decl;
743 }
744
745 /* Return a libfunc for NAME, creating one if we don't already have one.
746    The returned rtx is a SYMBOL_REF.  */
747
748 rtx
749 init_one_libfunc (const char *name)
750 {
751   tree id, decl;
752   hashval_t hash;
753
754   if (libfunc_decls == NULL)
755     libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
756
757   /* See if we have already created a libfunc decl for this function.  */
758   id = get_identifier (name);
759   hash = IDENTIFIER_HASH_VALUE (id);
760   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
761   decl = *slot;
762   if (decl == NULL)
763     {
764       /* Create a new decl, so that it can be passed to
765          targetm.encode_section_info.  */
766       decl = build_libfunc_function (name);
767       *slot = decl;
768     }
769   return XEXP (DECL_RTL (decl), 0);
770 }
771
772 /* Adjust the assembler name of libfunc NAME to ASMSPEC.  */
773
774 rtx
775 set_user_assembler_libfunc (const char *name, const char *asmspec)
776 {
777   tree id, decl;
778   hashval_t hash;
779
780   id = get_identifier (name);
781   hash = IDENTIFIER_HASH_VALUE (id);
782   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
783   gcc_assert (slot);
784   decl = (tree) *slot;
785   set_user_assembler_name (decl, asmspec);
786   return XEXP (DECL_RTL (decl), 0);
787 }
788
789 /* Call this to reset the function entry for one optab (OPTABLE) in mode
790    MODE to NAME, which should be either 0 or a string constant.  */
791
792 void
793 set_optab_libfunc (optab op, machine_mode mode, const char *name)
794 {
795   rtx val;
796   struct libfunc_entry e;
797   struct libfunc_entry **slot;
798
799   e.op = op;
800   e.mode1 = mode;
801   e.mode2 = VOIDmode;
802
803   if (name)
804     val = init_one_libfunc (name);
805   else
806     val = 0;
807   slot = libfunc_hash->find_slot (&e, INSERT);
808   if (*slot == NULL)
809     *slot = ggc_alloc<libfunc_entry> ();
810   (*slot)->op = op;
811   (*slot)->mode1 = mode;
812   (*slot)->mode2 = VOIDmode;
813   (*slot)->libfunc = val;
814 }
815
816 /* Call this to reset the function entry for one conversion optab
817    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
818    either 0 or a string constant.  */
819
820 void
821 set_conv_libfunc (convert_optab optab, machine_mode tmode,
822                   machine_mode fmode, const char *name)
823 {
824   rtx val;
825   struct libfunc_entry e;
826   struct libfunc_entry **slot;
827
828   e.op = optab;
829   e.mode1 = tmode;
830   e.mode2 = fmode;
831
832   if (name)
833     val = init_one_libfunc (name);
834   else
835     val = 0;
836   slot = libfunc_hash->find_slot (&e, INSERT);
837   if (*slot == NULL)
838     *slot = ggc_alloc<libfunc_entry> ();
839   (*slot)->op = optab;
840   (*slot)->mode1 = tmode;
841   (*slot)->mode2 = fmode;
842   (*slot)->libfunc = val;
843 }
844
845 /* Call this to initialize the contents of the optabs
846    appropriately for the current target machine.  */
847
848 void
849 init_optabs (void)
850 {
851   if (libfunc_hash)
852     libfunc_hash->empty ();
853   else
854     libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
855
856   /* Fill in the optabs with the insns we support.  */
857   init_all_optabs (this_fn_optabs);
858
859   /* The ffs function operates on `int'.  Fall back on it if we do not
860      have a libgcc2 function for that width.  */
861   if (INT_TYPE_SIZE < BITS_PER_WORD)
862     {
863       scalar_int_mode mode = int_mode_for_size (INT_TYPE_SIZE, 0).require ();
864       set_optab_libfunc (ffs_optab, mode, "ffs");
865     }
866
867   /* Explicitly initialize the bswap libfuncs since we need them to be
868      valid for things other than word_mode.  */
869   if (targetm.libfunc_gnu_prefix)
870     {
871       set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
872       set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
873     }
874   else
875     {
876       set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
877       set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
878     }
879
880   /* Use cabs for double complex abs, since systems generally have cabs.
881      Don't define any libcall for float complex, so that cabs will be used.  */
882   if (complex_double_type_node)
883     set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
884                        "cabs");
885
886   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
887   unwind_sjlj_unregister_libfunc
888     = init_one_libfunc ("_Unwind_SjLj_Unregister");
889
890   /* Allow the target to add more libcalls or rename some, etc.  */
891   targetm.init_libfuncs ();
892 }
893
894 /* A helper function for init_sync_libfuncs.  Using the basename BASE,
895    install libfuncs into TAB for BASE_N for 1 <= N <= MAX.  */
896
897 static void
898 init_sync_libfuncs_1 (optab tab, const char *base, int max)
899 {
900   machine_mode mode;
901   char buf[64];
902   size_t len = strlen (base);
903   int i;
904
905   gcc_assert (max <= 8);
906   gcc_assert (len + 3 < sizeof (buf));
907
908   memcpy (buf, base, len);
909   buf[len] = '_';
910   buf[len + 1] = '0';
911   buf[len + 2] = '\0';
912
913   mode = QImode;
914   for (i = 1; i <= max; i *= 2)
915     {
916       if (i > 1)
917         mode = GET_MODE_2XWIDER_MODE (mode).require ();
918       buf[len + 1] = '0' + i;
919       set_optab_libfunc (tab, mode, buf);
920     }
921 }
922
923 void
924 init_sync_libfuncs (int max)
925 {
926   if (!flag_sync_libcalls)
927     return;
928
929   init_sync_libfuncs_1 (sync_compare_and_swap_optab,
930                         "__sync_val_compare_and_swap", max);
931   init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
932                         "__sync_lock_test_and_set", max);
933
934   init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
935   init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
936   init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
937   init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
938   init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
939   init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
940
941   init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
942   init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
943   init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
944   init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
945   init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
946   init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
947 }
948
949 #include "gt-optabs-libfuncs.h"