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
hash(libfunc_entry * e)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
equal(libfunc_entry * e1,libfunc_entry * e2)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
convert_optab_libfunc(convert_optab optab,machine_mode mode1,machine_mode mode2)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
optab_libfunc(optab optab,machine_mode mode)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
gen_libfunc(optab optable,const char * opname,int suffix,machine_mode mode)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
gen_int_libfunc(optab optable,const char * opname,char suffix,machine_mode mode)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
gen_fp_libfunc(optab optable,const char * opname,char suffix,machine_mode mode)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
gen_fixed_libfunc(optab optable,const char * opname,char suffix,machine_mode mode)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
gen_signed_fixed_libfunc(optab optable,const char * opname,char suffix,machine_mode mode)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
gen_unsigned_fixed_libfunc(optab optable,const char * opname,char suffix,machine_mode mode)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
gen_int_fp_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_intv_fp_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_int_fp_fixed_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_int_fp_signed_fixed_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_int_fixed_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_int_signed_fixed_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_int_unsigned_fixed_libfunc(optab optable,const char * name,char suffix,machine_mode mode)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
gen_interclass_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_int_to_fp_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_ufloat_conv_libfunc(convert_optab tab,const char * opname ATTRIBUTE_UNUSED,machine_mode tmode,machine_mode fmode)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
gen_int_to_fp_nondecimal_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_fp_to_int_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_intraclass_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_trunc_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_extend_conv_libfunc(convert_optab tab,const char * opname ATTRIBUTE_UNUSED,machine_mode tmode,machine_mode fmode)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
gen_fract_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_fractuns_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_satfract_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
gen_satfractuns_conv_libfunc(convert_optab tab,const char * opname,machine_mode tmode,machine_mode fmode)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
hashlibfunc_decl_hasher714   hash (tree entry)
715   {
716     return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
717   }
718 
719   static bool
equallibfunc_decl_hasher720   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
build_libfunc_function(const char * name)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
init_one_libfunc(const char * name)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
set_user_assembler_libfunc(const char * name,const char * asmspec)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
set_optab_libfunc(optab op,machine_mode mode,const char * name)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
set_conv_libfunc(convert_optab optab,machine_mode tmode,machine_mode fmode,const char * name)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
init_optabs(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
init_sync_libfuncs_1(optab tab,const char * base,int max)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
init_sync_libfuncs(int max)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"
975