aarch64 - Set the mode for the unspec in speculation_tracker insn.
[platform/upstream/linaro-gcc.git] / gcc / optabs-libfuncs.c
1 /* Mapping from optabs to underlying library functions
2    Copyright (C) 1987-2016 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
193   if (GET_MODE_CLASS (mode) != MODE_INT)
194     return;
195   if (maxsize < LONG_LONG_TYPE_SIZE)
196     maxsize = LONG_LONG_TYPE_SIZE;
197   if (minsize > INT_TYPE_SIZE
198       && (trapv_binoptab_p (optable)
199           || trapv_unoptab_p (optable)))
200     minsize = INT_TYPE_SIZE;
201   if (GET_MODE_BITSIZE (mode) < minsize
202       || GET_MODE_BITSIZE (mode) > maxsize)
203     return;
204   gen_libfunc (optable, opname, suffix, mode);
205 }
206
207 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed.  */
208
209 void
210 gen_fp_libfunc (optab optable, const char *opname, char suffix,
211                 machine_mode mode)
212 {
213   char *dec_opname;
214
215   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
216     gen_libfunc (optable, opname, suffix, mode);
217   if (DECIMAL_FLOAT_MODE_P (mode))
218     {
219       dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
220       /* For BID support, change the name to have either a bid_ or dpd_ prefix
221          depending on the low level floating format used.  */
222       memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
223       strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
224       gen_libfunc (optable, dec_opname, suffix, mode);
225     }
226 }
227
228 /* Like gen_libfunc, but verify that fixed-point operation is involved.  */
229
230 void
231 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
232                    machine_mode mode)
233 {
234   if (!ALL_FIXED_POINT_MODE_P (mode))
235     return;
236   gen_libfunc (optable, opname, suffix, mode);
237 }
238
239 /* Like gen_libfunc, but verify that signed fixed-point operation is
240    involved.  */
241
242 void
243 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
244                           machine_mode mode)
245 {
246   if (!SIGNED_FIXED_POINT_MODE_P (mode))
247     return;
248   gen_libfunc (optable, opname, suffix, mode);
249 }
250
251 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
252    involved.  */
253
254 void
255 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
256                             machine_mode mode)
257 {
258   if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
259     return;
260   gen_libfunc (optable, opname, suffix, mode);
261 }
262
263 /* Like gen_libfunc, but verify that FP or INT operation is involved.  */
264
265 void
266 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
267                     machine_mode mode)
268 {
269   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
270     gen_fp_libfunc (optable, name, suffix, mode);
271   if (INTEGRAL_MODE_P (mode))
272     gen_int_libfunc (optable, name, suffix, mode);
273 }
274
275 /* Like gen_libfunc, but verify that FP or INT operation is involved
276    and add 'v' suffix for integer operation.  */
277
278 void
279 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
280                      machine_mode mode)
281 {
282   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
283     gen_fp_libfunc (optable, name, suffix, mode);
284   if (GET_MODE_CLASS (mode) == MODE_INT)
285     {
286       int len = strlen (name);
287       char *v_name = XALLOCAVEC (char, len + 2);
288       strcpy (v_name, name);
289       v_name[len] = 'v';
290       v_name[len + 1] = 0;
291       gen_int_libfunc (optable, v_name, suffix, mode);
292     }
293 }
294
295 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
296    involved.  */
297
298 void
299 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
300                           machine_mode mode)
301 {
302   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
303     gen_fp_libfunc (optable, name, suffix, mode);
304   if (INTEGRAL_MODE_P (mode))
305     gen_int_libfunc (optable, name, suffix, mode);
306   if (ALL_FIXED_POINT_MODE_P (mode))
307     gen_fixed_libfunc (optable, name, suffix, mode);
308 }
309
310 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
311    involved.  */
312
313 void
314 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
315                                  machine_mode mode)
316 {
317   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
318     gen_fp_libfunc (optable, name, suffix, mode);
319   if (INTEGRAL_MODE_P (mode))
320     gen_int_libfunc (optable, name, suffix, mode);
321   if (SIGNED_FIXED_POINT_MODE_P (mode))
322     gen_signed_fixed_libfunc (optable, name, suffix, mode);
323 }
324
325 /* Like gen_libfunc, but verify that INT or FIXED operation is
326    involved.  */
327
328 void
329 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
330                        machine_mode mode)
331 {
332   if (INTEGRAL_MODE_P (mode))
333     gen_int_libfunc (optable, name, suffix, mode);
334   if (ALL_FIXED_POINT_MODE_P (mode))
335     gen_fixed_libfunc (optable, name, suffix, mode);
336 }
337
338 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
339    involved.  */
340
341 void
342 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
343                               machine_mode mode)
344 {
345   if (INTEGRAL_MODE_P (mode))
346     gen_int_libfunc (optable, name, suffix, mode);
347   if (SIGNED_FIXED_POINT_MODE_P (mode))
348     gen_signed_fixed_libfunc (optable, name, suffix, mode);
349 }
350
351 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
352    involved.  */
353
354 void
355 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
356                                 machine_mode mode)
357 {
358   if (INTEGRAL_MODE_P (mode))
359     gen_int_libfunc (optable, name, suffix, mode);
360   if (UNSIGNED_FIXED_POINT_MODE_P (mode))
361     gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
362 }
363
364 /* Initialize the libfunc fields of an entire group of entries of an
365    inter-mode-class conversion optab.  The string formation rules are
366    similar to the ones for init_libfuncs, above, but instead of having
367    a mode name and an operand count these functions have two mode names
368    and no operand count.  */
369
370 void
371 gen_interclass_conv_libfunc (convert_optab tab,
372                              const char *opname,
373                              machine_mode tmode,
374                              machine_mode fmode)
375 {
376   size_t opname_len = strlen (opname);
377   size_t mname_len = 0;
378
379   const char *fname, *tname;
380   const char *q;
381   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
382   char *libfunc_name, *suffix;
383   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
384   char *p;
385
386   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
387      depends on which underlying decimal floating point format is used.  */
388   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
389
390   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
391
392   nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1);
393   nondec_name[0] = '_';
394   nondec_name[1] = '_';
395   if (targetm.libfunc_gnu_prefix)
396     {
397       nondec_name[2] = 'g';
398       nondec_name[3] = 'n';
399       nondec_name[4] = 'u';
400       nondec_name[5] = '_';
401     }
402
403   memcpy (&nondec_name[prefix_len], opname, opname_len);
404   nondec_suffix = nondec_name + opname_len + prefix_len;
405
406   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
407   dec_name[0] = '_';
408   dec_name[1] = '_';
409   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
410   memcpy (&dec_name[2+dec_len], opname, opname_len);
411   dec_suffix = dec_name + dec_len + opname_len + 2;
412
413   fname = GET_MODE_NAME (fmode);
414   tname = GET_MODE_NAME (tmode);
415
416   if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
417     {
418       libfunc_name = dec_name;
419       suffix = dec_suffix;
420     }
421   else
422     {
423       libfunc_name = nondec_name;
424       suffix = nondec_suffix;
425     }
426
427   p = suffix;
428   for (q = fname; *q; p++, q++)
429     *p = TOLOWER (*q);
430   for (q = tname; *q; p++, q++)
431     *p = TOLOWER (*q);
432
433   *p = '\0';
434
435   set_conv_libfunc (tab, tmode, fmode,
436                     ggc_alloc_string (libfunc_name, p - libfunc_name));
437 }
438
439 /* Same as gen_interclass_conv_libfunc but verify that we are producing
440    int->fp conversion.  */
441
442 void
443 gen_int_to_fp_conv_libfunc (convert_optab tab,
444                             const char *opname,
445                             machine_mode tmode,
446                             machine_mode fmode)
447 {
448   if (GET_MODE_CLASS (fmode) != MODE_INT)
449     return;
450   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
451     return;
452   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
453 }
454
455 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
456    naming scheme.  */
457
458 void
459 gen_ufloat_conv_libfunc (convert_optab tab,
460                          const char *opname ATTRIBUTE_UNUSED,
461                          machine_mode tmode,
462                          machine_mode fmode)
463 {
464   if (DECIMAL_FLOAT_MODE_P (tmode))
465     gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
466   else
467     gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
468 }
469
470 /* Same as gen_interclass_conv_libfunc but verify that we are producing
471    fp->int conversion.  */
472
473 void
474 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
475                                        const char *opname,
476                                        machine_mode tmode,
477                                        machine_mode fmode)
478 {
479   if (GET_MODE_CLASS (fmode) != MODE_INT)
480     return;
481   if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
482     return;
483   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
484 }
485
486 /* Same as gen_interclass_conv_libfunc but verify that we are producing
487    fp->int conversion with no decimal floating point involved.  */
488
489 void
490 gen_fp_to_int_conv_libfunc (convert_optab tab,
491                             const char *opname,
492                             machine_mode tmode,
493                             machine_mode fmode)
494 {
495   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
496     return;
497   if (GET_MODE_CLASS (tmode) != MODE_INT)
498     return;
499   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
500 }
501
502 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
503    The string formation rules are
504    similar to the ones for init_libfunc, above.  */
505
506 void
507 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
508                              machine_mode tmode, machine_mode fmode)
509 {
510   size_t opname_len = strlen (opname);
511   size_t mname_len = 0;
512
513   const char *fname, *tname;
514   const char *q;
515   int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2;
516   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
517   char *libfunc_name, *suffix;
518   char *p;
519
520   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
521      depends on which underlying decimal floating point format is used.  */
522   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
523
524   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
525
526   nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
527   nondec_name[0] = '_';
528   nondec_name[1] = '_';
529   if (targetm.libfunc_gnu_prefix)
530     {
531       nondec_name[2] = 'g';
532       nondec_name[3] = 'n';
533       nondec_name[4] = 'u';
534       nondec_name[5] = '_';
535     }
536   memcpy (&nondec_name[prefix_len], opname, opname_len);
537   nondec_suffix = nondec_name + opname_len + prefix_len;
538
539   dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
540   dec_name[0] = '_';
541   dec_name[1] = '_';
542   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
543   memcpy (&dec_name[2 + dec_len], opname, opname_len);
544   dec_suffix = dec_name + dec_len + opname_len + 2;
545
546   fname = GET_MODE_NAME (fmode);
547   tname = GET_MODE_NAME (tmode);
548
549   if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode))
550     {
551       libfunc_name = dec_name;
552       suffix = dec_suffix;
553     }
554   else
555     {
556       libfunc_name = nondec_name;
557       suffix = nondec_suffix;
558     }
559
560   p = suffix;
561   for (q = fname; *q; p++, q++)
562     *p = TOLOWER (*q);
563   for (q = tname; *q; p++, q++)
564     *p = TOLOWER (*q);
565
566   *p++ = '2';
567   *p = '\0';
568
569   set_conv_libfunc (tab, tmode, fmode,
570                     ggc_alloc_string (libfunc_name, p - libfunc_name));
571 }
572
573 /* Pick proper libcall for trunc_optab.  We need to chose if we do
574    truncation or extension and interclass or intraclass.  */
575
576 void
577 gen_trunc_conv_libfunc (convert_optab tab,
578                         const char *opname,
579                         machine_mode tmode,
580                         machine_mode fmode)
581 {
582   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
583     return;
584   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
585     return;
586   if (tmode == fmode)
587     return;
588
589   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
590       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
591      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
592
593   if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
594     return;
595
596   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
597        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
598       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
599     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
600 }
601
602 /* Pick proper libcall for extend_optab.  We need to chose if we do
603    truncation or extension and interclass or intraclass.  */
604
605 void
606 gen_extend_conv_libfunc (convert_optab tab,
607                          const char *opname ATTRIBUTE_UNUSED,
608                          machine_mode tmode,
609                          machine_mode fmode)
610 {
611   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
612     return;
613   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
614     return;
615   if (tmode == fmode)
616     return;
617
618   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
619       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
620      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
621
622   if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
623     return;
624
625   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
626        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
627       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
628     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
629 }
630
631 /* Pick proper libcall for fract_optab.  We need to chose if we do
632    interclass or intraclass.  */
633
634 void
635 gen_fract_conv_libfunc (convert_optab tab,
636                         const char *opname,
637                         machine_mode tmode,
638                         machine_mode fmode)
639 {
640   if (tmode == fmode)
641     return;
642   if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
643     return;
644
645   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
646     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
647   else
648     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
649 }
650
651 /* Pick proper libcall for fractuns_optab.  */
652
653 void
654 gen_fractuns_conv_libfunc (convert_optab tab,
655                            const char *opname,
656                            machine_mode tmode,
657                            machine_mode fmode)
658 {
659   if (tmode == fmode)
660     return;
661   /* One mode must be a fixed-point mode, and the other must be an integer
662      mode.  */
663   if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
664         || (ALL_FIXED_POINT_MODE_P (fmode)
665             && GET_MODE_CLASS (tmode) == MODE_INT)))
666     return;
667
668   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
669 }
670
671 /* Pick proper libcall for satfract_optab.  We need to chose if we do
672    interclass or intraclass.  */
673
674 void
675 gen_satfract_conv_libfunc (convert_optab tab,
676                            const char *opname,
677                            machine_mode tmode,
678                            machine_mode fmode)
679 {
680   if (tmode == fmode)
681     return;
682   /* TMODE must be a fixed-point mode.  */
683   if (!ALL_FIXED_POINT_MODE_P (tmode))
684     return;
685
686   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
687     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
688   else
689     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
690 }
691
692 /* Pick proper libcall for satfractuns_optab.  */
693
694 void
695 gen_satfractuns_conv_libfunc (convert_optab tab,
696                               const char *opname,
697                               machine_mode tmode,
698                               machine_mode fmode)
699 {
700   if (tmode == fmode)
701     return;
702   /* TMODE must be a fixed-point mode, and FMODE must be an integer mode.  */
703   if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
704     return;
705
706   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
707 }
708
709 /* Hashtable callbacks for libfunc_decls.  */
710
711 struct libfunc_decl_hasher : ggc_ptr_hash<tree_node>
712 {
713   static hashval_t
714   hash (tree entry)
715   {
716     return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
717   }
718
719   static bool
720   equal (tree decl, tree name)
721   {
722     return DECL_NAME (decl) == name;
723   }
724 };
725
726 /* A table of previously-created libfuncs, hashed by name.  */
727 static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
728
729 /* Build a decl for a libfunc named NAME.  */
730
731 tree
732 build_libfunc_function (const char *name)
733 {
734   tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
735                           get_identifier (name),
736                           build_function_type (integer_type_node, NULL_TREE));
737   /* ??? We don't have any type information except for this is
738      a function.  Pretend this is "int foo ()".  */
739   DECL_ARTIFICIAL (decl) = 1;
740   DECL_EXTERNAL (decl) = 1;
741   TREE_PUBLIC (decl) = 1;
742   gcc_assert (DECL_ASSEMBLER_NAME (decl));
743
744   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
745      are the flags assigned by targetm.encode_section_info.  */
746   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
747
748   return decl;
749 }
750
751 /* Return a libfunc for NAME, creating one if we don't already have one.
752    The returned rtx is a SYMBOL_REF.  */
753
754 rtx
755 init_one_libfunc (const char *name)
756 {
757   tree id, decl;
758   hashval_t hash;
759
760   if (libfunc_decls == NULL)
761     libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
762
763   /* See if we have already created a libfunc decl for this function.  */
764   id = get_identifier (name);
765   hash = IDENTIFIER_HASH_VALUE (id);
766   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
767   decl = *slot;
768   if (decl == NULL)
769     {
770       /* Create a new decl, so that it can be passed to
771          targetm.encode_section_info.  */
772       decl = build_libfunc_function (name);
773       *slot = decl;
774     }
775   return XEXP (DECL_RTL (decl), 0);
776 }
777
778 /* Adjust the assembler name of libfunc NAME to ASMSPEC.  */
779
780 rtx
781 set_user_assembler_libfunc (const char *name, const char *asmspec)
782 {
783   tree id, decl;
784   hashval_t hash;
785
786   id = get_identifier (name);
787   hash = IDENTIFIER_HASH_VALUE (id);
788   tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
789   gcc_assert (slot);
790   decl = (tree) *slot;
791   set_user_assembler_name (decl, asmspec);
792   return XEXP (DECL_RTL (decl), 0);
793 }
794
795 /* Call this to reset the function entry for one optab (OPTABLE) in mode
796    MODE to NAME, which should be either 0 or a string constant.  */
797
798 void
799 set_optab_libfunc (optab op, machine_mode mode, const char *name)
800 {
801   rtx val;
802   struct libfunc_entry e;
803   struct libfunc_entry **slot;
804
805   e.op = op;
806   e.mode1 = mode;
807   e.mode2 = VOIDmode;
808
809   if (name)
810     val = init_one_libfunc (name);
811   else
812     val = 0;
813   slot = libfunc_hash->find_slot (&e, INSERT);
814   if (*slot == NULL)
815     *slot = ggc_alloc<libfunc_entry> ();
816   (*slot)->op = op;
817   (*slot)->mode1 = mode;
818   (*slot)->mode2 = VOIDmode;
819   (*slot)->libfunc = val;
820 }
821
822 /* Call this to reset the function entry for one conversion optab
823    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
824    either 0 or a string constant.  */
825
826 void
827 set_conv_libfunc (convert_optab optab, machine_mode tmode,
828                   machine_mode fmode, const char *name)
829 {
830   rtx val;
831   struct libfunc_entry e;
832   struct libfunc_entry **slot;
833
834   e.op = optab;
835   e.mode1 = tmode;
836   e.mode2 = fmode;
837
838   if (name)
839     val = init_one_libfunc (name);
840   else
841     val = 0;
842   slot = libfunc_hash->find_slot (&e, INSERT);
843   if (*slot == NULL)
844     *slot = ggc_alloc<libfunc_entry> ();
845   (*slot)->op = optab;
846   (*slot)->mode1 = tmode;
847   (*slot)->mode2 = fmode;
848   (*slot)->libfunc = val;
849 }
850
851 /* Call this to initialize the contents of the optabs
852    appropriately for the current target machine.  */
853
854 void
855 init_optabs (void)
856 {
857   if (libfunc_hash)
858     libfunc_hash->empty ();
859   else
860     libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
861
862   /* Fill in the optabs with the insns we support.  */
863   init_all_optabs (this_fn_optabs);
864
865   /* The ffs function operates on `int'.  Fall back on it if we do not
866      have a libgcc2 function for that width.  */
867   if (INT_TYPE_SIZE < BITS_PER_WORD)
868     set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
869                        "ffs");
870
871   /* Explicitly initialize the bswap libfuncs since we need them to be
872      valid for things other than word_mode.  */
873   if (targetm.libfunc_gnu_prefix)
874     {
875       set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2");
876       set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2");
877     }
878   else
879     {
880       set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
881       set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
882     }
883
884   /* Use cabs for double complex abs, since systems generally have cabs.
885      Don't define any libcall for float complex, so that cabs will be used.  */
886   if (complex_double_type_node)
887     set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
888                        "cabs");
889
890   abort_libfunc = init_one_libfunc ("abort");
891   memcpy_libfunc = init_one_libfunc ("memcpy");
892   memmove_libfunc = init_one_libfunc ("memmove");
893   memcmp_libfunc = init_one_libfunc ("memcmp");
894   memset_libfunc = init_one_libfunc ("memset");
895   setbits_libfunc = init_one_libfunc ("__setbits");
896
897 #ifndef DONT_USE_BUILTIN_SETJMP
898   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
899   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
900 #else
901   setjmp_libfunc = init_one_libfunc ("setjmp");
902   longjmp_libfunc = init_one_libfunc ("longjmp");
903 #endif
904   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
905   unwind_sjlj_unregister_libfunc
906     = init_one_libfunc ("_Unwind_SjLj_Unregister");
907
908   /* For function entry/exit instrumentation.  */
909   profile_function_entry_libfunc
910     = init_one_libfunc ("__cyg_profile_func_enter");
911   profile_function_exit_libfunc
912     = init_one_libfunc ("__cyg_profile_func_exit");
913
914   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
915
916   /* Allow the target to add more libcalls or rename some, etc.  */
917   targetm.init_libfuncs ();
918 }
919
920 /* A helper function for init_sync_libfuncs.  Using the basename BASE,
921    install libfuncs into TAB for BASE_N for 1 <= N <= MAX.  */
922
923 static void
924 init_sync_libfuncs_1 (optab tab, const char *base, int max)
925 {
926   machine_mode mode;
927   char buf[64];
928   size_t len = strlen (base);
929   int i;
930
931   gcc_assert (max <= 8);
932   gcc_assert (len + 3 < sizeof (buf));
933
934   memcpy (buf, base, len);
935   buf[len] = '_';
936   buf[len + 1] = '0';
937   buf[len + 2] = '\0';
938
939   mode = QImode;
940   for (i = 1; i <= max; i *= 2)
941     {
942       buf[len + 1] = '0' + i;
943       set_optab_libfunc (tab, mode, buf);
944       mode = GET_MODE_2XWIDER_MODE (mode);
945     }
946 }
947
948 void
949 init_sync_libfuncs (int max)
950 {
951   if (!flag_sync_libcalls)
952     return;
953
954   init_sync_libfuncs_1 (sync_compare_and_swap_optab,
955                         "__sync_val_compare_and_swap", max);
956   init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
957                         "__sync_lock_test_and_set", max);
958
959   init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
960   init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
961   init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
962   init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
963   init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
964   init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
965
966   init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
967   init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
968   init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
969   init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
970   init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
971   init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
972 }
973
974 #include "gt-optabs-libfuncs.h"