]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/optabs-libfuncs.c
Update copyright years.
[thirdparty/gcc.git] / gcc / optabs-libfuncs.c
CommitLineData
385399a8 1/* Mapping from optabs to underlying library functions
818ab71a 2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
385399a8
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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
35struct target_libfuncs default_target_libfuncs;
36#if SWITCHABLE_TARGET
37struct 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
52hashval_t
53libfunc_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
60bool
61libfunc_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. */
69rtx
70convert_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. */
105rtx
106optab_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
150static void
151gen_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
186void
187gen_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
209void
210gen_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
230void
231gen_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
242void
243gen_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
254void
255gen_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
265void
266gen_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
278void
279gen_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
298void
299gen_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
313void
314gen_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
328void
329gen_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
341void
342gen_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
354void
355gen_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
370void
371gen_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
442void
443gen_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
458void
459gen_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
473void
474gen_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
489void
490gen_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
506void
507gen_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
576void
577gen_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
605void
606gen_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
634void
635gen_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
653void
654gen_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
674void
675gen_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
694void
695gen_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
711struct 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. */
727static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
728
729/* Build a decl for a libfunc named NAME. */
730
731tree
732build_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
754rtx
755init_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
780rtx
781set_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
798void
799set_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
826void
827set_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
854void
855init_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
923static void
924init_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
948void
949init_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"