1 /* Mapping from optabs to underlying library functions
2 Copyright (C) 1987-2022 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
;
192 scalar_int_mode int_mode
;
194 if (!is_int_mode (mode
, &int_mode
))
196 if (maxsize
< LONG_LONG_TYPE_SIZE
)
197 maxsize
= LONG_LONG_TYPE_SIZE
;
198 if (minsize
> INT_TYPE_SIZE
199 && (trapv_binoptab_p (optable
)
200 || trapv_unoptab_p (optable
)))
201 minsize
= INT_TYPE_SIZE
;
202 if (GET_MODE_BITSIZE (int_mode
) < minsize
203 || GET_MODE_BITSIZE (int_mode
) > maxsize
)
205 gen_libfunc (optable
, opname
, suffix
, int_mode
);
208 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
211 gen_fp_libfunc (optab optable
, const char *opname
, char suffix
,
216 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
217 gen_libfunc (optable
, opname
, suffix
, mode
);
218 if (DECIMAL_FLOAT_MODE_P (mode
))
220 dec_opname
= XALLOCAVEC (char, sizeof (DECIMAL_PREFIX
) + strlen (opname
));
221 /* For BID support, change the name to have either a bid_ or dpd_ prefix
222 depending on the low level floating format used. */
223 memcpy (dec_opname
, DECIMAL_PREFIX
, sizeof (DECIMAL_PREFIX
) - 1);
224 strcpy (dec_opname
+ sizeof (DECIMAL_PREFIX
) - 1, opname
);
225 gen_libfunc (optable
, dec_opname
, suffix
, mode
);
229 /* Like gen_libfunc, but verify that fixed-point operation is involved. */
232 gen_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
235 if (!ALL_FIXED_POINT_MODE_P (mode
))
237 gen_libfunc (optable
, opname
, suffix
, mode
);
240 /* Like gen_libfunc, but verify that signed fixed-point operation is
244 gen_signed_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
247 if (!SIGNED_FIXED_POINT_MODE_P (mode
))
249 gen_libfunc (optable
, opname
, suffix
, mode
);
252 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
256 gen_unsigned_fixed_libfunc (optab optable
, const char *opname
, char suffix
,
259 if (!UNSIGNED_FIXED_POINT_MODE_P (mode
))
261 gen_libfunc (optable
, opname
, suffix
, mode
);
264 /* Like gen_libfunc, but verify that FP or INT operation is involved. */
267 gen_int_fp_libfunc (optab optable
, const char *name
, char suffix
,
270 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
271 gen_fp_libfunc (optable
, name
, suffix
, mode
);
272 if (INTEGRAL_MODE_P (mode
))
273 gen_int_libfunc (optable
, name
, suffix
, mode
);
276 /* Like gen_libfunc, but verify that FP or INT operation is involved
277 and add 'v' suffix for integer operation. */
280 gen_intv_fp_libfunc (optab optable
, const char *name
, char suffix
,
283 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
284 gen_fp_libfunc (optable
, name
, suffix
, mode
);
285 if (GET_MODE_CLASS (mode
) == MODE_INT
)
287 int len
= strlen (name
);
288 char *v_name
= XALLOCAVEC (char, len
+ 2);
289 strcpy (v_name
, name
);
292 gen_int_libfunc (optable
, v_name
, suffix
, mode
);
296 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
300 gen_int_fp_fixed_libfunc (optab optable
, const char *name
, char suffix
,
303 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
304 gen_fp_libfunc (optable
, name
, suffix
, mode
);
305 if (INTEGRAL_MODE_P (mode
))
306 gen_int_libfunc (optable
, name
, suffix
, mode
);
307 if (ALL_FIXED_POINT_MODE_P (mode
))
308 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
311 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
315 gen_int_fp_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
318 if (DECIMAL_FLOAT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_FLOAT
)
319 gen_fp_libfunc (optable
, name
, suffix
, mode
);
320 if (INTEGRAL_MODE_P (mode
))
321 gen_int_libfunc (optable
, name
, suffix
, mode
);
322 if (SIGNED_FIXED_POINT_MODE_P (mode
))
323 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
326 /* Like gen_libfunc, but verify that INT or FIXED operation is
330 gen_int_fixed_libfunc (optab optable
, const char *name
, char suffix
,
333 if (INTEGRAL_MODE_P (mode
))
334 gen_int_libfunc (optable
, name
, suffix
, mode
);
335 if (ALL_FIXED_POINT_MODE_P (mode
))
336 gen_fixed_libfunc (optable
, name
, suffix
, mode
);
339 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
343 gen_int_signed_fixed_libfunc (optab optable
, const char *name
, char suffix
,
346 if (INTEGRAL_MODE_P (mode
))
347 gen_int_libfunc (optable
, name
, suffix
, mode
);
348 if (SIGNED_FIXED_POINT_MODE_P (mode
))
349 gen_signed_fixed_libfunc (optable
, name
, suffix
, mode
);
352 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
356 gen_int_unsigned_fixed_libfunc (optab optable
, const char *name
, char suffix
,
359 if (INTEGRAL_MODE_P (mode
))
360 gen_int_libfunc (optable
, name
, suffix
, mode
);
361 if (UNSIGNED_FIXED_POINT_MODE_P (mode
))
362 gen_unsigned_fixed_libfunc (optable
, name
, suffix
, mode
);
365 /* Initialize the libfunc fields of an entire group of entries of an
366 inter-mode-class conversion optab. The string formation rules are
367 similar to the ones for init_libfuncs, above, but instead of having
368 a mode name and an operand count these functions have two mode names
369 and no operand count. */
372 gen_interclass_conv_libfunc (convert_optab tab
,
377 size_t opname_len
= strlen (opname
);
378 size_t mname_len
= 0;
380 const char *fname
, *tname
;
382 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
383 char *libfunc_name
, *suffix
;
384 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
387 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
388 depends on which underlying decimal floating point format is used. */
389 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
391 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
393 nondec_name
= XALLOCAVEC (char, prefix_len
+ opname_len
+ mname_len
+ 1 + 1);
394 nondec_name
[0] = '_';
395 nondec_name
[1] = '_';
396 if (targetm
.libfunc_gnu_prefix
)
398 nondec_name
[2] = 'g';
399 nondec_name
[3] = 'n';
400 nondec_name
[4] = 'u';
401 nondec_name
[5] = '_';
404 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
405 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
407 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
410 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
411 memcpy (&dec_name
[2+dec_len
], opname
, opname_len
);
412 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
414 fname
= GET_MODE_NAME (fmode
);
415 tname
= GET_MODE_NAME (tmode
);
417 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
419 libfunc_name
= dec_name
;
424 libfunc_name
= nondec_name
;
425 suffix
= nondec_suffix
;
429 for (q
= fname
; *q
; p
++, q
++)
431 for (q
= tname
; *q
; p
++, q
++)
436 set_conv_libfunc (tab
, tmode
, fmode
,
437 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
440 /* Same as gen_interclass_conv_libfunc but verify that we are producing
441 int->fp conversion. */
444 gen_int_to_fp_conv_libfunc (convert_optab tab
,
449 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
451 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (tmode
))
453 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
456 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
460 gen_ufloat_conv_libfunc (convert_optab tab
,
461 const char *opname ATTRIBUTE_UNUSED
,
465 if (DECIMAL_FLOAT_MODE_P (tmode
))
466 gen_int_to_fp_conv_libfunc (tab
, "floatuns", tmode
, fmode
);
468 gen_int_to_fp_conv_libfunc (tab
, "floatun", tmode
, fmode
);
471 /* Same as gen_interclass_conv_libfunc but verify that we are producing
472 fp->int conversion. */
475 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab
,
480 if (GET_MODE_CLASS (fmode
) != MODE_INT
)
482 if (GET_MODE_CLASS (tmode
) != MODE_FLOAT
)
484 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
487 /* Same as gen_interclass_conv_libfunc but verify that we are producing
488 fp->int conversion with no decimal floating point involved. */
491 gen_fp_to_int_conv_libfunc (convert_optab tab
,
496 if (GET_MODE_CLASS (fmode
) != MODE_FLOAT
&& !DECIMAL_FLOAT_MODE_P (fmode
))
498 if (GET_MODE_CLASS (tmode
) != MODE_INT
)
500 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
503 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
504 The string formation rules are
505 similar to the ones for init_libfunc, above. */
508 gen_intraclass_conv_libfunc (convert_optab tab
, const char *opname
,
509 machine_mode tmode
, machine_mode fmode
)
511 size_t opname_len
= strlen (opname
);
512 size_t mname_len
= 0;
514 const char *fname
, *tname
;
516 int prefix_len
= targetm
.libfunc_gnu_prefix
? 6 : 2;
517 char *nondec_name
, *dec_name
, *nondec_suffix
, *dec_suffix
;
518 char *libfunc_name
, *suffix
;
521 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
522 depends on which underlying decimal floating point format is used. */
523 const size_t dec_len
= sizeof (DECIMAL_PREFIX
) - 1;
525 mname_len
= strlen (GET_MODE_NAME (tmode
)) + strlen (GET_MODE_NAME (fmode
));
527 nondec_name
= XALLOCAVEC (char, 2 + opname_len
+ mname_len
+ 1 + 1);
528 nondec_name
[0] = '_';
529 nondec_name
[1] = '_';
530 if (targetm
.libfunc_gnu_prefix
)
532 nondec_name
[2] = 'g';
533 nondec_name
[3] = 'n';
534 nondec_name
[4] = 'u';
535 nondec_name
[5] = '_';
537 memcpy (&nondec_name
[prefix_len
], opname
, opname_len
);
538 nondec_suffix
= nondec_name
+ opname_len
+ prefix_len
;
540 dec_name
= XALLOCAVEC (char, 2 + dec_len
+ opname_len
+ mname_len
+ 1 + 1);
543 memcpy (&dec_name
[2], DECIMAL_PREFIX
, dec_len
);
544 memcpy (&dec_name
[2 + dec_len
], opname
, opname_len
);
545 dec_suffix
= dec_name
+ dec_len
+ opname_len
+ 2;
547 fname
= GET_MODE_NAME (fmode
);
548 tname
= GET_MODE_NAME (tmode
);
550 if (DECIMAL_FLOAT_MODE_P (fmode
) || DECIMAL_FLOAT_MODE_P (tmode
))
552 libfunc_name
= dec_name
;
557 libfunc_name
= nondec_name
;
558 suffix
= nondec_suffix
;
562 for (q
= fname
; *q
; p
++, q
++)
564 for (q
= tname
; *q
; p
++, q
++)
570 set_conv_libfunc (tab
, tmode
, fmode
,
571 ggc_alloc_string (libfunc_name
, p
- libfunc_name
));
574 /* Pick proper libcall for trunc_optab. We need to chose if we do
575 truncation or extension and interclass or intraclass. */
578 gen_trunc_conv_libfunc (convert_optab tab
,
583 scalar_float_mode float_tmode
, float_fmode
;
584 if (!is_a
<scalar_float_mode
> (fmode
, &float_fmode
)
585 || !is_a
<scalar_float_mode
> (tmode
, &float_tmode
)
586 || float_tmode
== float_fmode
)
589 if (GET_MODE_CLASS (float_tmode
) != GET_MODE_CLASS (float_fmode
))
590 gen_interclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
592 if (GET_MODE_PRECISION (float_fmode
) <= GET_MODE_PRECISION (float_tmode
))
595 if (GET_MODE_CLASS (float_tmode
) == GET_MODE_CLASS (float_fmode
))
596 gen_intraclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
599 /* Pick proper libcall for extend_optab. We need to chose if we do
600 truncation or extension and interclass or intraclass. */
603 gen_extend_conv_libfunc (convert_optab tab
,
604 const char *opname ATTRIBUTE_UNUSED
,
608 scalar_float_mode float_tmode
, float_fmode
;
609 if (!is_a
<scalar_float_mode
> (fmode
, &float_fmode
)
610 || !is_a
<scalar_float_mode
> (tmode
, &float_tmode
)
611 || float_tmode
== float_fmode
)
614 if (GET_MODE_CLASS (float_tmode
) != GET_MODE_CLASS (float_fmode
))
615 gen_interclass_conv_libfunc (tab
, opname
, float_tmode
, float_fmode
);
617 if (GET_MODE_PRECISION (float_fmode
) > GET_MODE_PRECISION (float_tmode
))
620 if (GET_MODE_CLASS (float_tmode
) == GET_MODE_CLASS (float_fmode
))
621 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
624 /* Pick proper libcall for fract_optab. We need to chose if we do
625 interclass or intraclass. */
628 gen_fract_conv_libfunc (convert_optab tab
,
635 if (!(ALL_FIXED_POINT_MODE_P (tmode
) || ALL_FIXED_POINT_MODE_P (fmode
)))
638 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
639 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
641 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
644 /* Pick proper libcall for fractuns_optab. */
647 gen_fractuns_conv_libfunc (convert_optab tab
,
654 /* One mode must be a fixed-point mode, and the other must be an integer
656 if (!((ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
)
657 || (ALL_FIXED_POINT_MODE_P (fmode
)
658 && GET_MODE_CLASS (tmode
) == MODE_INT
)))
661 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
664 /* Pick proper libcall for satfract_optab. We need to chose if we do
665 interclass or intraclass. */
668 gen_satfract_conv_libfunc (convert_optab tab
,
675 /* TMODE must be a fixed-point mode. */
676 if (!ALL_FIXED_POINT_MODE_P (tmode
))
679 if (GET_MODE_CLASS (tmode
) == GET_MODE_CLASS (fmode
))
680 gen_intraclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
682 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
685 /* Pick proper libcall for satfractuns_optab. */
688 gen_satfractuns_conv_libfunc (convert_optab tab
,
695 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
696 if (!(ALL_FIXED_POINT_MODE_P (tmode
) && GET_MODE_CLASS (fmode
) == MODE_INT
))
699 gen_interclass_conv_libfunc (tab
, opname
, tmode
, fmode
);
702 /* Hashtable callbacks for libfunc_decls. */
704 struct libfunc_decl_hasher
: ggc_ptr_hash
<tree_node
>
709 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry
));
713 equal (tree decl
, tree name
)
715 return DECL_NAME (decl
) == name
;
719 /* A table of previously-created libfuncs, hashed by name. */
720 static GTY (()) hash_table
<libfunc_decl_hasher
> *libfunc_decls
;
722 /* Build a decl for a libfunc named NAME with visibility VIS. */
725 build_libfunc_function_visibility (const char *name
, symbol_visibility vis
)
727 /* ??? We don't have any type information; pretend this is "int foo ()". */
728 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
729 get_identifier (name
),
730 build_function_type (integer_type_node
, NULL_TREE
));
731 DECL_EXTERNAL (decl
) = 1;
732 TREE_PUBLIC (decl
) = 1;
733 DECL_ARTIFICIAL (decl
) = 1;
734 DECL_VISIBILITY (decl
) = vis
;
735 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
736 gcc_assert (DECL_ASSEMBLER_NAME (decl
));
741 /* Build a decl for a libfunc named NAME. */
744 build_libfunc_function (const char *name
)
746 return build_libfunc_function_visibility (name
, VISIBILITY_DEFAULT
);
749 /* Return a libfunc for NAME, creating one if we don't already have one.
750 The decl is given visibility VIS. The returned rtx is a SYMBOL_REF. */
753 init_one_libfunc_visibility (const char *name
, symbol_visibility vis
)
758 if (libfunc_decls
== NULL
)
759 libfunc_decls
= hash_table
<libfunc_decl_hasher
>::create_ggc (37);
761 /* See if we have already created a libfunc decl for this function. */
762 id
= get_identifier (name
);
763 hash
= IDENTIFIER_HASH_VALUE (id
);
764 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, INSERT
);
768 /* Create a new decl, so that it can be passed to
769 targetm.encode_section_info. */
770 decl
= build_libfunc_function_visibility (name
, vis
);
773 return XEXP (DECL_RTL (decl
), 0);
777 init_one_libfunc (const char *name
)
779 return init_one_libfunc_visibility (name
, VISIBILITY_DEFAULT
);
782 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */
785 set_user_assembler_libfunc (const char *name
, const char *asmspec
)
790 id
= get_identifier (name
);
791 hash
= IDENTIFIER_HASH_VALUE (id
);
792 tree
*slot
= libfunc_decls
->find_slot_with_hash (id
, hash
, NO_INSERT
);
795 set_user_assembler_name (decl
, asmspec
);
796 return XEXP (DECL_RTL (decl
), 0);
799 /* Call this to reset the function entry for one optab (OPTABLE) in mode
800 MODE to NAME, which should be either 0 or a string constant. */
803 set_optab_libfunc (optab op
, machine_mode mode
, const char *name
)
806 struct libfunc_entry e
;
807 struct libfunc_entry
**slot
;
814 val
= init_one_libfunc (name
);
817 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
819 *slot
= ggc_alloc
<libfunc_entry
> ();
821 (*slot
)->mode1
= mode
;
822 (*slot
)->mode2
= VOIDmode
;
823 (*slot
)->libfunc
= val
;
826 /* Call this to reset the function entry for one conversion optab
827 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
828 either 0 or a string constant. */
831 set_conv_libfunc (convert_optab optab
, machine_mode tmode
,
832 machine_mode fmode
, const char *name
)
835 struct libfunc_entry e
;
836 struct libfunc_entry
**slot
;
843 val
= init_one_libfunc (name
);
846 slot
= libfunc_hash
->find_slot (&e
, INSERT
);
848 *slot
= ggc_alloc
<libfunc_entry
> ();
850 (*slot
)->mode1
= tmode
;
851 (*slot
)->mode2
= fmode
;
852 (*slot
)->libfunc
= val
;
855 /* Call this to initialize the contents of the optabs
856 appropriately for the current target machine. */
862 libfunc_hash
->empty ();
864 libfunc_hash
= hash_table
<libfunc_hasher
>::create_ggc (10);
866 /* Fill in the optabs with the insns we support. */
867 init_all_optabs (this_fn_optabs
);
869 /* The ffs function operates on `int'. Fall back on it if we do not
870 have a libgcc2 function for that width. */
871 if (INT_TYPE_SIZE
< BITS_PER_WORD
)
873 scalar_int_mode mode
= int_mode_for_size (INT_TYPE_SIZE
, 0).require ();
874 set_optab_libfunc (ffs_optab
, mode
, "ffs");
877 /* Explicitly initialize the bswap libfuncs since we need them to be
878 valid for things other than word_mode. */
879 if (targetm
.libfunc_gnu_prefix
)
881 set_optab_libfunc (bswap_optab
, SImode
, "__gnu_bswapsi2");
882 set_optab_libfunc (bswap_optab
, DImode
, "__gnu_bswapdi2");
886 set_optab_libfunc (bswap_optab
, SImode
, "__bswapsi2");
887 set_optab_libfunc (bswap_optab
, DImode
, "__bswapdi2");
890 /* Use cabs for double complex abs, since systems generally have cabs.
891 Don't define any libcall for float complex, so that cabs will be used. */
892 if (complex_double_type_node
)
893 set_optab_libfunc (abs_optab
, TYPE_MODE (complex_double_type_node
),
896 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
897 unwind_sjlj_unregister_libfunc
898 = init_one_libfunc ("_Unwind_SjLj_Unregister");
900 /* Allow the target to add more libcalls or rename some, etc. */
901 targetm
.init_libfuncs ();
904 /* A helper function for init_sync_libfuncs. Using the basename BASE,
905 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
908 init_sync_libfuncs_1 (optab tab
, const char *base
, int max
)
912 size_t len
= strlen (base
);
915 gcc_assert (max
<= 8);
916 gcc_assert (len
+ 3 < sizeof (buf
));
918 memcpy (buf
, base
, len
);
924 for (i
= 1; i
<= max
; i
*= 2)
927 mode
= GET_MODE_2XWIDER_MODE (mode
).require ();
928 buf
[len
+ 1] = '0' + i
;
929 set_optab_libfunc (tab
, mode
, buf
);
934 init_sync_libfuncs (int max
)
936 if (!flag_sync_libcalls
)
939 init_sync_libfuncs_1 (sync_compare_and_swap_optab
,
940 "__sync_val_compare_and_swap", max
);
941 init_sync_libfuncs_1 (sync_lock_test_and_set_optab
,
942 "__sync_lock_test_and_set", max
);
944 init_sync_libfuncs_1 (sync_old_add_optab
, "__sync_fetch_and_add", max
);
945 init_sync_libfuncs_1 (sync_old_sub_optab
, "__sync_fetch_and_sub", max
);
946 init_sync_libfuncs_1 (sync_old_ior_optab
, "__sync_fetch_and_or", max
);
947 init_sync_libfuncs_1 (sync_old_and_optab
, "__sync_fetch_and_and", max
);
948 init_sync_libfuncs_1 (sync_old_xor_optab
, "__sync_fetch_and_xor", max
);
949 init_sync_libfuncs_1 (sync_old_nand_optab
, "__sync_fetch_and_nand", max
);
951 init_sync_libfuncs_1 (sync_new_add_optab
, "__sync_add_and_fetch", max
);
952 init_sync_libfuncs_1 (sync_new_sub_optab
, "__sync_sub_and_fetch", max
);
953 init_sync_libfuncs_1 (sync_new_ior_optab
, "__sync_or_and_fetch", max
);
954 init_sync_libfuncs_1 (sync_new_and_optab
, "__sync_and_and_fetch", max
);
955 init_sync_libfuncs_1 (sync_new_xor_optab
, "__sync_xor_and_fetch", max
);
956 init_sync_libfuncs_1 (sync_new_nand_optab
, "__sync_nand_and_fetch", max
);
959 #include "gt-optabs-libfuncs.h"