1 /* Mapping from optabs to underlying library functions
2 Copyright (C) 1987-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
25 #include "insn-codes.h"
26 #include "optabs-libfuncs.h"
28 #include "optabs-query.h"
30 #include "stringpool.h"
32 #include "stor-layout.h"
35 struct target_libfuncs default_target_libfuncs
;
37 struct target_libfuncs
*this_target_libfuncs
= &default_target_libfuncs
;
40 #define libfunc_hash \
41 (this_target_libfuncs->x_libfunc_hash)
43 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
44 #if ENABLE_DECIMAL_BID_FORMAT
45 #define DECIMAL_PREFIX "bid_"
47 #define DECIMAL_PREFIX "dpd_"
50 /* Used for libfunc_hash. */
53 libfunc_hasher::hash (libfunc_entry
*e
)
55 return ((e
->mode1
+ e
->mode2
* NUM_MACHINE_MODES
) ^ e
->op
);
58 /* Used for libfunc_hash. */
61 libfunc_hasher::equal (libfunc_entry
*e1
, libfunc_entry
*e2
)
63 return e1
->op
== e2
->op
&& e1
->mode1
== e2
->mode1
&& e1
->mode2
== e2
->mode2
;
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. */
70 convert_optab_libfunc (convert_optab optab
, machine_mode mode1
,
73 struct libfunc_entry e
;
74 struct libfunc_entry
**slot
;
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
79 if (!(optab
>= FIRST_CONV_OPTAB
&& optab
<= LAST_CONVLIB_OPTAB
))
85 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
88 const struct convert_optab_libcall_d
*d
89 = &convlib_def
[optab
- FIRST_CONV_OPTAB
];
91 if (d
->libcall_gen
== NULL
)
94 d
->libcall_gen (optab
, d
->libcall_basename
, mode1
, mode2
);
95 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
99 return (*slot
)->libfunc
;
102 /* Return libfunc corresponding operation defined by OPTAB in MODE.
103 Trigger lazy initialization if needed, return NULL if no libfunc is
106 optab_libfunc (optab optab
, machine_mode mode
)
108 struct libfunc_entry e
;
109 struct libfunc_entry
**slot
;
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
114 if (!(optab
>= FIRST_NORM_OPTAB
&& optab
<= LAST_NORMLIB_OPTAB
))
120 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
123 const struct optab_libcall_d
*d
124 = &normlib_def
[optab
- FIRST_NORM_OPTAB
];
126 if (d
->libcall_gen
== NULL
)
129 d
->libcall_gen (optab
, d
->libcall_basename
, d
->libcall_suffix
, mode
);
130 slot
= libfunc_hash
->find_slot (&e
, NO_INSERT
);
134 return (*slot
)->libfunc
;
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').
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. */
151 gen_libfunc (optab optable
, const char *opname
, int suffix
,
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
);
166 if (targetm
.libfunc_gnu_prefix
)
173 for (q
= opname
; *q
;)
175 for (q
= mname
; *q
; q
++)
180 set_optab_libfunc (optable
, mode
,
181 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
184 /* Like gen_libfunc, but verify that integer operation is involved. */
187 gen_int_libfunc (optab optable
, const char *opname
, char suffix
,
190 int maxsize
= 2 * BITS_PER_WORD
;
191 int minsize
= BITS_PER_WORD
;
193 if (GET_MODE_CLASS (mode
) != MODE_INT
)
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
)
204 gen_libfunc (optable
, opname
, suffix
, mode
);
207 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
210 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
215 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
216 gen_libfunc (optable
, opname
, suffix
, mode
);
217 if (DECIMAL_FLOAT_MODE_P (mode
))
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
);
228 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
231 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
234 if (!ALL_FIXED_POINT_MODE_P (mode
))
236 gen_libfunc (optable
, opname
, suffix
, mode
);
239 /* Like gen_libfunc, but verify that signed fixed-point operation is
243 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
246 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
248 gen_libfunc (optable
, opname
, suffix
, mode
);
251 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
255 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
258 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
260 gen_libfunc (optable
, opname
, suffix
, mode
);
263 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
266 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
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
);
275 /* Like gen_libfunc, but verify that FP or INT operation is involved
276 and add 'v' suffix for integer operation. */
279 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
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
)
286 int len
= strlen (name
);
287 char *v_name
= XALLOCAVEC (char, len
+ 2);
288 strcpy (v_name
, name
);
291 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
295 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
299 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
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
);
310 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
314 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
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
);
325 /* Like gen_libfunc, but verify that INT or FIXED operation is
329 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
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
);
338 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
342 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
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
);
351 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
355 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
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
);
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. */
371 gen_interclass_conv_libfunc (convert_optab tab
,
376 size_t opname_len
= strlen (opname
);
377 size_t mname_len
= 0;
379 const char *fname
, *tname
;
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
;
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;
390 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
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
)
397 nondec_name
[2] = 'g';
398 nondec_name
[3] = 'n';
399 nondec_name
[4] = 'u';
400 nondec_name
[5] = '_';
403 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
404 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
406 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 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;
413 fname
= GET_MODE_NAME (fmode
);
414 tname
= GET_MODE_NAME (tmode
);
416 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
418 libfunc_name
= dec_name
;
423 libfunc_name
= nondec_name
;
424 suffix
= nondec_suffix
;
428 for (q
= fname
; *q
; p
++, q
++)
430 for (q
= tname
; *q
; p
++, q
++)
435 set_conv_libfunc (tab
, tmode
, fmode
,
436 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
439 /* Same as gen_interclass_conv_libfunc but verify that we are producing
440 int->fp conversion. */
443 gen_int_to_fp_conv_libfunc (convert_optab tab
,
448 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
450 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
452 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
455 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
459 gen_ufloat_conv_libfunc (convert_optab tab
,
460 const char *opname ATTRIBUTE_UNUSED
,
464 if (DECIMAL_FLOAT_MODE_P (tmode
))
465 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
467 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
470 /* Same as gen_interclass_conv_libfunc but verify that we are producing
471 fp->int conversion. */
474 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
479 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
481 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
483 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
486 /* Same as gen_interclass_conv_libfunc but verify that we are producing
487 fp->int conversion with no decimal floating point involved. */
490 gen_fp_to_int_conv_libfunc (convert_optab tab
,
495 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
497 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
499 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
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. */
507 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
508 machine_mode tmode
, machine_mode fmode
)
510 size_t opname_len
= strlen (opname
);
511 size_t mname_len
= 0;
513 const char *fname
, *tname
;
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
;
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;
524 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
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
)
531 nondec_name
[2] = 'g';
532 nondec_name
[3] = 'n';
533 nondec_name
[4] = 'u';
534 nondec_name
[5] = '_';
536 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
537 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
539 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 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;
546 fname
= GET_MODE_NAME (fmode
);
547 tname
= GET_MODE_NAME (tmode
);
549 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
551 libfunc_name
= dec_name
;
556 libfunc_name
= nondec_name
;
557 suffix
= nondec_suffix
;
561 for (q
= fname
; *q
; p
++, q
++)
563 for (q
= tname
; *q
; p
++, q
++)
569 set_conv_libfunc (tab
, tmode
, fmode
,
570 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
573 /* Pick proper libcall for trunc_optab. We need to chose if we do
574 truncation or extension and interclass or intraclass. */
577 gen_trunc_conv_libfunc (convert_optab tab
,
582 scalar_float_mode float_tmode
, float_fmode
;
583 if (!is_a
<scalar_float_mode
> (fmode
, &float_fmode
)
584 || !is_a
<scalar_float_mode
> (tmode
, &float_tmode
)
585 || float_tmode
== float_fmode
)
588 if (GET_MODE_CLASS (float_tmode
) != GET_MODE_CLASS (float_fmode
))
589 gen_interclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
591 if (GET_MODE_PRECISION (float_fmode
) <= GET_MODE_PRECISION (float_tmode
))
594 if (GET_MODE_CLASS (float_tmode
) == GET_MODE_CLASS (float_fmode
))
595 gen_intraclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
598 /* Pick proper libcall for extend_optab. We need to chose if we do
599 truncation or extension and interclass or intraclass. */
602 gen_extend_conv_libfunc (convert_optab tab
,
603 const char *opname ATTRIBUTE_UNUSED
,
607 scalar_float_mode float_tmode
, float_fmode
;
608 if (!is_a
<scalar_float_mode
> (fmode
, &float_fmode
)
609 || !is_a
<scalar_float_mode
> (tmode
, &float_tmode
)
610 || float_tmode
== float_fmode
)
613 if (GET_MODE_CLASS (float_tmode
) != GET_MODE_CLASS (float_fmode
))
614 gen_interclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
616 if (GET_MODE_PRECISION (float_fmode
) > GET_MODE_PRECISION (float_tmode
))
619 if (GET_MODE_CLASS (float_tmode
) == GET_MODE_CLASS (float_fmode
))
620 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
623 /* Pick proper libcall for fract_optab. We need to chose if we do
624 interclass or intraclass. */
627 gen_fract_conv_libfunc (convert_optab tab
,
634 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
637 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
638 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
640 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
643 /* Pick proper libcall for fractuns_optab. */
646 gen_fractuns_conv_libfunc (convert_optab tab
,
653 /* One mode must be a fixed-point mode, and the other must be an integer
655 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
656 || (ALL_FIXED_POINT_MODE_P (fmode
)
657 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
660 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
663 /* Pick proper libcall for satfract_optab. We need to chose if we do
664 interclass or intraclass. */
667 gen_satfract_conv_libfunc (convert_optab tab
,
674 /* TMODE must be a fixed-point mode. */
675 if (!ALL_FIXED_POINT_MODE_P (tmode
))
678 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
679 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
681 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
684 /* Pick proper libcall for satfractuns_optab. */
687 gen_satfractuns_conv_libfunc (convert_optab tab
,
694 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
695 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
698 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
701 /* Hashtable callbacks for libfunc_decls. */
703 struct libfunc_decl_hasher
: ggc_ptr_hash
<tree_node
>
708 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry
));
712 equal (tree decl
, tree name
)
714 return DECL_NAME (decl
) == name
;
718 /* A table of previously-created libfuncs, hashed by name. */
719 static GTY (()) hash_table
<libfunc_decl_hasher
> *libfunc_decls
;
721 /* Build a decl for a libfunc named NAME. */
724 build_libfunc_function (const char *name
)
726 /* ??? We don't have any type information; pretend this is "int foo ()". */
727 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
728 get_identifier (name
),
729 build_function_type (integer_type_node
, NULL_TREE
));
730 DECL_EXTERNAL (decl
) = 1;
731 TREE_PUBLIC (decl
) = 1;
732 DECL_ARTIFICIAL (decl
) = 1;
733 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
734 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
735 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
737 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
738 are the flags assigned by targetm.encode_section_info. */
739 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl
), 0), NULL
);
744 /* Return a libfunc for NAME, creating one if we don't already have one.
745 The returned rtx is a SYMBOL_REF. */
748 init_one_libfunc (const char *name
)
753 if (libfunc_decls
== NULL
)
754 libfunc_decls
= hash_table
<libfunc_decl_hasher
>::create_ggc (37);
756 /* See if we have already created a libfunc decl for this function. */
757 id
= get_identifier (name
);
758 hash
= IDENTIFIER_HASH_VALUE (id
);
759 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, INSERT
);
763 /* Create a new decl, so that it can be passed to
764 targetm.encode_section_info. */
765 decl
= build_libfunc_function (name
);
768 return XEXP (DECL_RTL (decl
), 0);
771 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
774 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
779 id
= get_identifier (name
);
780 hash
= IDENTIFIER_HASH_VALUE (id
);
781 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, NO_INSERT
);
784 set_user_assembler_name (decl
, asmspec
);
785 return XEXP (DECL_RTL (decl
), 0);
788 /* Call this to reset the function entry for one optab (OPTABLE) in mode
789 MODE to NAME, which should be either 0 or a string constant. */
792 set_optab_libfunc (optab op
, machine_mode mode
, const char *name
)
795 struct libfunc_entry e
;
796 struct libfunc_entry
**slot
;
803 val
= init_one_libfunc (name
);
806 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
808 *slot
= ggc_alloc
<libfunc_entry
> ();
810 (*slot
)->mode1
= mode
;
811 (*slot
)->mode2
= VOIDmode
;
812 (*slot
)->libfunc
= val
;
815 /* Call this to reset the function entry for one conversion optab
816 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
817 either 0 or a string constant. */
820 set_conv_libfunc (convert_optab optab
, machine_mode tmode
,
821 machine_mode fmode
, const char *name
)
824 struct libfunc_entry e
;
825 struct libfunc_entry
**slot
;
832 val
= init_one_libfunc (name
);
835 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
837 *slot
= ggc_alloc
<libfunc_entry
> ();
839 (*slot
)->mode1
= tmode
;
840 (*slot
)->mode2
= fmode
;
841 (*slot
)->libfunc
= val
;
844 /* Call this to initialize the contents of the optabs
845 appropriately for the current target machine. */
851 libfunc_hash
->empty ();
853 libfunc_hash
= hash_table
<libfunc_hasher
>::create_ggc (10);
855 /* Fill in the optabs with the insns we support. */
856 init_all_optabs (this_fn_optabs
);
858 /* The ffs function operates on `int'. Fall back on it if we do not
859 have a libgcc2 function for that width. */
860 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
861 set_optab_libfunc (ffs_optab
, mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0),
864 /* Explicitly initialize the bswap libfuncs since we need them to be
865 valid for things other than word_mode. */
866 if (targetm
.libfunc_gnu_prefix
)
868 set_optab_libfunc (bswap_optab
, SImode
, "__gnu_bswapsi2");
869 set_optab_libfunc (bswap_optab
, DImode
, "__gnu_bswapdi2");
873 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
874 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
877 /* Use cabs for double complex abs, since systems generally have cabs.
878 Don't define any libcall for float complex, so that cabs will be used. */
879 if (complex_double_type_node
)
880 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
),
883 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
884 unwind_sjlj_unregister_libfunc
885 = init_one_libfunc ("_Unwind_SjLj_Unregister");
887 /* Allow the target to add more libcalls or rename some, etc. */
888 targetm
.init_libfuncs ();
891 /* A helper function for init_sync_libfuncs. Using the basename BASE,
892 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
895 init_sync_libfuncs_1 (optab tab
, const char *base
, int max
)
899 size_t len
= strlen (base
);
902 gcc_assert (max
<= 8);
903 gcc_assert (len
+ 3 < sizeof (buf
));
905 memcpy (buf
, base
, len
);
911 for (i
= 1; i
<= max
; i
*= 2)
914 mode
= GET_MODE_2XWIDER_MODE (mode
).require ();
915 buf
[len
+ 1] = '0' + i
;
916 set_optab_libfunc (tab
, mode
, buf
);
921 init_sync_libfuncs (int max
)
923 if (!flag_sync_libcalls
)
926 init_sync_libfuncs_1 (sync_compare_and_swap_optab
,
927 "__sync_val_compare_and_swap", max
);
928 init_sync_libfuncs_1 (sync_lock_test_and_set_optab
,
929 "__sync_lock_test_and_set", max
);
931 init_sync_libfuncs_1 (sync_old_add_optab
, "__sync_fetch_and_add", max
);
932 init_sync_libfuncs_1 (sync_old_sub_optab
, "__sync_fetch_and_sub", max
);
933 init_sync_libfuncs_1 (sync_old_ior_optab
, "__sync_fetch_and_or", max
);
934 init_sync_libfuncs_1 (sync_old_and_optab
, "__sync_fetch_and_and", max
);
935 init_sync_libfuncs_1 (sync_old_xor_optab
, "__sync_fetch_and_xor", max
);
936 init_sync_libfuncs_1 (sync_old_nand_optab
, "__sync_fetch_and_nand", max
);
938 init_sync_libfuncs_1 (sync_new_add_optab
, "__sync_add_and_fetch", max
);
939 init_sync_libfuncs_1 (sync_new_sub_optab
, "__sync_sub_and_fetch", max
);
940 init_sync_libfuncs_1 (sync_new_ior_optab
, "__sync_or_and_fetch", max
);
941 init_sync_libfuncs_1 (sync_new_and_optab
, "__sync_and_and_fetch", max
);
942 init_sync_libfuncs_1 (sync_new_xor_optab
, "__sync_xor_and_fetch", max
);
943 init_sync_libfuncs_1 (sync_new_nand_optab
, "__sync_nand_and_fetch", max
);
946 #include "gt-optabs-libfuncs.h"