Machine description file gives out the way to construct instructions of RTL form for certain operation. For instruction emition, compiler tries to open coded RTL code (if something is open-coded, there is no actual function call made, just equivilent code dropped into place; close-coded results in a call to -some- function. In compiler circles, the phrase "open coded" is even more general than that. For instance, some machines have a fancy instruction to do several steps of some computation, such as a POLY instruction to calculate polynomials, or an INDEX instruction to use array subscripts (sometimes with build-in builds-checking). As it turns out, on some particular of the given architecture, it is faster to execute a series of multiple simpler instructions than to use the fancy instruction. This used to occur more often with microcoded systems with optional acceleration hardware – for instance, INDEX might micro-code a multiply, taking dozens of clock cycles, while a simpler MUL and then ADD uses the hardware multiplier and hence finishes in only a few clock cycles. These days it tends to happen instead with parallel-issue microprocessors: for instance, the x86 ENTER instruction is slower, on some x86 CPUs, than the equivalent sequence of instructions. (This is especially true if the compiler can omit several steps due to some specific knowledge, e.g., "we know there is no need for separate stack and frame pointers, nor for any stack adjustment, in this leaf function".) Compiler folks will say things like "we open coded the function entry and exit" when they avoid using the slow ENTER and EXIT instructions). If not possible, the compiler will have to invoke library routines to handle the operation.
lang_dependent_init (continue)
4540 init_optabs ();
5177 void
5178 init_optabs (void) in optabs.c
5179 {
5180 unsigned int i;
5181
5182 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5183
5184 for (i = 0; i < NUM_RTX_CODE; i++)
5185 setcc_gen_code[i] = CODE_FOR_nothing;
5186
5187 #ifdef HAVE_conditional_move
5188 for (i = 0; i < NUM_MACHINE_MODES; i++)
5189 movcc_gen_code[i] = CODE_FOR_nothing;
5190 #endif
setcc_gen_code indexed by the rtx-code for a conditional (eg. EQ, LT,...) gives the insn code to make a store-condition insn to test that condition. While movcc_gen_code indexed by the machine mode, gives the insn code to make a conditional move insn. This is not indexed by the rtx-code like bcc_gen_fctn and setcc_gen_code to cut down on the number of named patterns.
init_optabs (continue)
5192 add_optab = init_optab (PLUS);
5193 addv_optab = init_optabv (PLUS);
5194 sub_optab = init_optab (MINUS);
5195 subv_optab = init_optabv (MINUS);
5196 smul_optab = init_optab (MULT);
5197 smulv_optab = init_optabv (MULT);
5198 smul_highpart_optab = init_optab (UNKNOWN);
5199 umul_highpart_optab = init_optab (UNKNOWN);
5200 smul_widen_optab = init_optab (UNKNOWN);
5201 umul_widen_optab = init_optab (UNKNOWN);
5202 sdiv_optab = init_optab (DIV);
5203 sdivv_optab = init_optabv (DIV);
5204 sdivmod_optab = init_optab (UNKNOWN);
5205 udiv_optab = init_optab (UDIV);
5206 udivmod_optab = init_optab (UNKNOWN);
5207 smod_optab = init_optab (MOD);
5208 umod_optab = init_optab (UMOD);
5209 ftrunc_optab = init_optab (UNKNOWN);
5210 and_optab = init_optab (AND);
5211 ior_optab = init_optab (IOR);
5212 xor_optab = init_optab (XOR);
5213 ashl_optab = init_optab (ASHIFT);
5214 ashr_optab = init_optab (ASHIFTRT);
5215 lshr_optab = init_optab (LSHIFTRT);
5216 rotl_optab = init_optab (ROTATE);
5217 rotr_optab = init_optab (ROTATERT);
5218 smin_optab = init_optab (SMIN);
5219 smax_optab = init_optab (SMAX);
5220 umin_optab = init_optab (UMIN);
5221 umax_optab = init_optab (UMAX);
5222 pow_optab = init_optab (UNKNOWN);
5223 atan2_optab = init_optab (UNKNOWN);
5224
5225 /* These three have codes assigned exclusively for the sake of
5226 have_insn_for. */
5227 mov_optab = init_optab (SET);
5228 movstrict_optab = init_optab (STRICT_LOW_PART);
5229 cmp_optab = init_optab (COMPARE);
5230
5231 ucmp_optab = init_optab (UNKNOWN);
5232 tst_optab = init_optab (UNKNOWN);
5233
5234 eq_optab = init_optab (EQ);
5235 ne_optab = init_optab (NE);
5236 gt_optab = init_optab (GT);
5237 ge_optab = init_optab (GE);
5238 lt_optab = init_optab (LT);
5239 le_optab = init_optab (LE);
5240 unord_optab = init_optab (UNORDERED);
5241
5242 neg_optab = init_optab (NEG);
5243 negv_optab = init_optabv (NEG);
5244 abs_optab = init_optab (ABS);
5245 absv_optab = init_optabv (ABS);
5246 addcc_optab = init_optab (UNKNOWN);
5247 one_cmpl_optab = init_optab (NOT);
5248 ffs_optab = init_optab (FFS);
5249 clz_optab = init_optab (CLZ);
5250 ctz_optab = init_optab (CTZ);
5251 popcount_optab = init_optab (POPCOUNT);
5252 parity_optab = init_optab (PARITY);
5253 sqrt_optab = init_optab (SQRT);
5254 floor_optab = init_optab (UNKNOWN);
5255 ceil_optab = init_optab (UNKNOWN);
5256 round_optab = init_optab (UNKNOWN);
5257 btrunc_optab = init_optab (UNKNOWN);
5258 nearbyint_optab = init_optab (UNKNOWN);
5259 sin_optab = init_optab (UNKNOWN);
5260 cos_optab = init_optab (UNKNOWN);
5261 exp_optab = init_optab (UNKNOWN);
5262 log_optab = init_optab (UNKNOWN);
5263 tan_optab = init_optab (UNKNOWN);
5264 atan_optab = init_optab (UNKNOWN);
5265 strlen_optab = init_optab (UNKNOWN);
5266 cbranch_optab = init_optab (UNKNOWN);
5267 cmov_optab = init_optab (UNKNOWN);
5268 cstore_optab = init_optab (UNKNOWN);
5269 push_optab = init_optab (UNKNOWN);
5270
5271 vec_extract_optab = init_optab (UNKNOWN);
5272 vec_set_optab = init_optab (UNKNOWN);
5273 vec_init_optab = init_optab (UNKNOWN);
Above, at the left hand side of init_optab, init_optabv, are XXX_optab marco which just selects corresponding element of optab_table, which is a global array of struct optab.
41 struct optab_handlers GTY(()) in optabs.h
42 {
43 enum insn_code insn_code;
44 rtx libfunc;
45 };
In the definition, insn_code slot says how to generate an instruction for this operation on a particular machine mode. It is CODE_FOR_nothing if there is no such instruction on the target machine, libfunc slot is the name of the library function that can be used to perform the operation.
47 struct optab GTY(()) in optabs.h
48 {
49 enum rtx_code code;
50 struct optab_handlers handlers[NUM_MACHINE_MODES];
51 };
52 typedef struct optab * optab;
In sections of back-end, we know that insn_code describes the instructions the target can support (as result, insn_code must be generated by tool from target machine description file); while rtx_code describes target independent instructions in form of RTL generated by the front-end. Struct optab maps rtx_code to insn_code. Notice that handlers is an array, as on target, operations with different mode may need different instructions.
4910 static inline optab
4911 init_optab (enum rtx_code code) in optabs.c
4912 {
4913 optab op = new_optab ();
4914 op->code = code;
4915 code_to_optab[(int) code] = op;
4916 return op;
4917 }
4921 static inline optab
4922 init_optabv (enum rtx_code code)
4923 {
4924 optab op = new_optab ();
4925 op->code = code;
4926 return op;
4927 }
Here operation of name followed by ”v” shares the same rtx-code with the operation without “v” in name. The difference is, for “v” versoin, if the result is overflowed, it will trap. They are selected by the value of flag_trapv.
init_optabs (continue)
5274 /* Conversions. */
5275 sext_optab = init_convert_optab (SIGN_EXTEND);
5276 zext_optab = init_convert_optab (ZERO_EXTEND);
5277 trunc_optab = init_convert_optab (TRUNCATE);
5278 sfix_optab = init_convert_optab (FIX);
5279 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5280 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5281 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5282 sfloat_optab = init_convert_optab (FLOAT);
5283 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
In C++, we can use for example (int) f to do the type conversion. It’s clean and convenient, no need consider any detail about the data presentation. However, it’s not for granted and free. Methods must be defined for every permitted type conversion. It’s why comes convert_optab.
Above, at the left hand side of init_convert_optab, XXX_optab macro selects corresponding items in convert_optab_table, which is a global array of convert_optab.
57 struct convert_optab GTY(()) in optabs.h
58 {
59 enum rtx_code code;
60 struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
61 };
62 typedef struct convert_optab *convert_optab;
In the definition, handlers is two dimensions array, records conversion operation between modes
4930 static inline convert_optab
4931 init_convert_optab (enum rtx_code code) in optabs.c
4932 {
4933 convert_optab op = new_convert_optab ();
4934 op->code = code;
4935 return op;
4936 }
Here, movstr_optab records the insn_code of instructions to perform block moves. clrstr_optab records the insn_code of instructions to perform block clears. cmpstr_optab, and cmpmem_optab record the insn_code of two different kinds of instructions to perform block compares. While reload_in_optab and reload_out_optab record the insn_code of insns that may be needed to perform input and output reloads of special objects. They provide a place to pass a scratch register.
init_optabs (continue)
5285 for (i = 0; i < NUM_MACHINE_MODES; i++)
5286 {
5287 movstr_optab[i] = CODE_FOR_nothing;
5288 clrstr_optab[i] = CODE_FOR_nothing;
5289 cmpstr_optab[i] = CODE_FOR_nothing;
5290 cmpmem_optab[i] = CODE_FOR_nothing;
5291
5292 #ifdef HAVE_SECONDARY_RELOADS
5293 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5294 #endif
5295 }
5296
5297 /* Fill in the optabs with the insns we support. */
5298 init_all_optabs ();
Now from front-end’s view, all optabs have been filled with related rtx_code, but front-end hasn’t idea about insn_code, it is the business of back-end. To finish optabs, back-end specially generates init_all_optabs with genopinit from target machine description file. It helps fill in insn_code, below is code snippet of the function.
sext_optab->handlers[SImode][HImode].insn_code = CODE_FOR_extendhisi2;
sext_optab->handlers[HImode][QImode].insn_code = CODE_FOR_extendqihi2;
sext_optab->handlers[SImode][QImode].insn_code = CODE_FOR_extendqisi2;
…
setcc_gen_code[EQ] = CODE_FOR_seq;
setcc_gen_code[NE] = CODE_FOR_sne;
setcc_gen_code[GT] = CODE_FOR_sgt;
setcc_gen_code[GTU] = CODE_FOR_sgtu;
…
bcc_gen_fctn[EQ] = gen_beq;
bcc_gen_fctn[NE] = gen_bne;
bcc_gen_fctn[GT] = gen_bgt;
bcc_gen_fctn[GTU] = gen_bgtu;
Above, sext_optab selects convert_optab for signed extension in convert_optab_table. The first index for handlers is the target mode, the second is the source mode. At right hand side of the assignment is the insn_code.
Following, now setcc_gen_code is initialized with the correct insn_code if the target machine offers such instructions. Notice that not all machine mode of setcc_gen_code will get meaningful insn_code (not CODE_FOR_nothing), which can be not open coded, and library routine will be invoked at place.
Then global array bcc_gen_fctn of type rtx_fun gives the way to test the condition such as EQ (equal), LT (less than). Of course, gen_XXX are also generated following target machine description, and you will find the definition in insn_emit.c.
init_optabs (continue)
5300 /* Initialize the optabs with the names of the library functions. */
5301 init_integral_libfuncs (add_optab, "add", '3');
5302 init_floating_libfuncs (add_optab, "add", '3');
5303 init_integral_libfuncs (addv_optab, "addv", '3');
5304 init_floating_libfuncs (addv_optab, "add", '3');
5305 init_integral_libfuncs (sub_optab, "sub", '3');
5306 init_floating_libfuncs (sub_optab, "sub", '3');
5307 init_integral_libfuncs (subv_optab, "subv", '3');
5308 init_floating_libfuncs (subv_optab, "sub", '3');
5309 init_integral_libfuncs (smul_optab, "mul", '3');
5310 init_floating_libfuncs (smul_optab, "mul", '3');
5311 init_integral_libfuncs (smulv_optab, "mulv", '3');
5312 init_floating_libfuncs (smulv_optab, "mul", '3');
5313 init_integral_libfuncs (sdiv_optab, "div", '3');
5314 init_floating_libfuncs (sdiv_optab, "div", '3');
5315 init_integral_libfuncs (sdivv_optab, "divv", '3');
5316 init_integral_libfuncs (udiv_optab, "udiv", '3');
5317 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5318 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5319 init_integral_libfuncs (smod_optab, "mod", '3');
5320 init_integral_libfuncs (umod_optab, "umod", '3');
5321 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5322 init_integral_libfuncs (and_optab, "and", '3');
5323 init_integral_libfuncs (ior_optab, "ior", '3');
5324 init_integral_libfuncs (xor_optab, "xor", '3');
5325 init_integral_libfuncs (ashl_optab, "ashl", '3');
5326 init_integral_libfuncs (ashr_optab, "ashr", '3');
5327 init_integral_libfuncs (lshr_optab, "lshr", '3');
5328 init_integral_libfuncs (smin_optab, "min", '3');
5329 init_floating_libfuncs (smin_optab, "min", '3');
5330 init_integral_libfuncs (smax_optab, "max", '3');
5331 init_floating_libfuncs (smax_optab, "max", '3');
5332 init_integral_libfuncs (umin_optab, "umin", '3');
5333 init_integral_libfuncs (umax_optab, "umax", '3');
5334 init_integral_libfuncs (neg_optab, "neg", '2');
5335 init_floating_libfuncs (neg_optab, "neg", '2');
5336 init_integral_libfuncs (negv_optab, "negv", '2');
5337 init_floating_libfuncs (negv_optab, "neg", '2');
5338 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5339 init_integral_libfuncs (ffs_optab, "ffs", '2');
5340 init_integral_libfuncs (clz_optab, "clz", '2');
5341 init_integral_libfuncs (ctz_optab, "ctz", '2');
5342 init_integral_libfuncs (popcount_optab, "popcount", '2');
5343 init_integral_libfuncs (parity_optab, "parity", '2');
5344
5345 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
5346 init_integral_libfuncs (cmp_optab, "cmp", '2');
5347 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5348 init_floating_libfuncs (cmp_optab, "cmp", '2');
5349
5350 /* EQ etc are floating point only. */
5351 init_floating_libfuncs (eq_optab, "eq", '2');
5352 init_floating_libfuncs (ne_optab, "ne", '2');
5353 init_floating_libfuncs (gt_optab, "gt", '2');
5354 init_floating_libfuncs (ge_optab, "ge", '2');
5355 init_floating_libfuncs (lt_optab, "lt", '2');
5356 init_floating_libfuncs (le_optab, "le", '2');
5357 init_floating_libfuncs (unord_optab, "unord", '2');
Now times for initializing libfunc in handler of optab, this field records the library function that can perform the operation identified by insn_code (however, the library function may not exist).
4991 static void
4992 init_integral_libfuncs (optab optable, const char *opname, int suffix) in optabs.c
4993 {
4994 int maxsize = 2*BITS_PER_WORD;
4995 if (maxsize < LONG_LONG_TYPE_SIZE)
4996 maxsize = LONG_LONG_TYPE_SIZE;
4997 init_libfuncs (optable, word_mode,
4998 mode_for_size (maxsize, MODE_INT, 0),
4999 opname, suffix);
5000 }
At line 4998, mode_for_size finds out the machine mode of specified precision (here indicated by maxsize) in specified class (Here MODE_INT).
4955 static void
4956 init_libfuncs (optab optable, int first_mode, int last_mode, in optabs.c
4957 const char *opname, int suffix)
4958 {
4959 int mode;
4960 unsigned opname_len = strlen (opname);
4961
4962 for (mode = first_mode; (int) mode <= (int) last_mode;
4963 mode = (enum machine_mode) ((int) mode + 1))
4964 {
4965 const char *mname = GET_MODE_NAME (mode);
4966 unsigned mname_len = strlen (mname);
4967 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4968 char *p;
4969 const char *q;
4970
4971 p = libfunc_name;
4972 *p++ = '_';
4973 *p++ = '_';
4974 for (q = opname; *q; )
4975 *p++ = *q++;
4976 for (q = mname; *q; q++)
4977 *p++ = TOLOWER (*q);
4978 *p++ = suffix;
4979 *p = '/0';
4980
4981 optable->handlers [(int) mode].libfunc
4982 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
4983 }
4984 }
Before line 4981, it just constructs the library function name. At line 4982 allocates the string on ggc (gcc garbage collection) managing stack. Using code at line 5301 as example, library functions declared are: __addqi3, __addhi3, __addsi3, __adddi3. But these functions aren’t implemented in compiler, as the target machine description file has told the compiler about the detail of the instruction to do the operation.
init_optabs (continue)
5359 /* Conversions. */
5360 init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT);
5361 init_interclass_conv_libfuncs (sfix_optab, "fix", MODE_FLOAT, MODE_INT);
5362 init_interclass_conv_libfuncs (ufix_optab, "fixuns", MODE_FLOAT, MODE_INT);
For inter-class conversion, like int to float, it involves the change of data representation. It needs below init_interclass_conv_libfuncs to fill the handlers.
5018 static void
5019 init_interclass_conv_libfuncs (convert_optab tab, const char *opname, in optabs.c
5020 enum mode_class from_class,
5021 enum mode_class to_class)
5022 {
5023 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5024 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5025 size_t opname_len = strlen (opname);
5026 size_t max_mname_len = 0;
5027
5028 enum machine_mode fmode, tmode;
5029 const char *fname, *tname;
5030 const char *q;
5031 char *libfunc_name, *suffix;
5032 char *p;
5033
5034 for (fmode = first_from_mode;
5035 fmode != VOIDmode;
5036 fmode = GET_MODE_WIDER_MODE (fmode))
5037 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5038
5039 for (tmode = first_to_mode;
5040 tmode != VOIDmode;
5041 tmode = GET_MODE_WIDER_MODE (tmode))
5042 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5043
5044 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5045 libfunc_name[0] = '_';
5046 libfunc_name[1] = '_';
5047 memcpy (&libfunc_name[2], opname, opname_len);
5048 suffix = libfunc_name + opname_len + 2;
5049
5050 for (fmode = first_from_mode; fmode != VOIDmode;
5051 fmode = GET_MODE_WIDER_MODE (fmode))
5052 for (tmode = first_to_mode; tmode != VOIDmode;
5053 tmode = GET_MODE_WIDER_MODE (tmode))
5054 {
5055 fname = GET_MODE_NAME (fmode);
5056 tname = GET_MODE_NAME (tmode);
5057
5058 p = suffix;
5059 for (q = fname; *q; p++, q++)
5060 *p = TOLOWER (*q);
5061 for (q = tname; *q; p++, q++)
5062 *p = TOLOWER (*q);
5063
5064 *p = '/0';
5065
5066 tab->handlers[tmode][fmode].libfunc
5067 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5068 p - libfunc_name));
5069 }
5070 }
Similarly, most functions declared here aren’t implemented (refer to libgcc2.c). There are alternative instructions.
init_optabs (continue)
5364 /* sext_optab is also used for FLOAT_EXTEND. */
5365 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5366 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
Before, we have seen that single float and double float have different data representations, so either extending from single to double, or truncating from double to single, both are conversions in essense. Must prepare the conversion functions.
5077 static void
5078 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname, in optabs.c
5079 enum mode_class class, bool widening)
5080 {
5081 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5082 size_t opname_len = strlen (opname);
5083 size_t max_mname_len = 0;
5084
5085 enum machine_mode nmode, wmode;
5086 const char *nname, *wname;
5087 const char *q;
5088 char *libfunc_name, *suffix;
5089 char *p;
5090
5091 for (nmode = first_mode; nmode != VOIDmode;
5092 nmode = GET_MODE_WIDER_MODE (nmode))
5093 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5094
5095 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5096 libfunc_name[0] = '_';
5097 libfunc_name[1] = '_';
5098 memcpy (&libfunc_name[2], opname, opname_len);
5099 suffix = libfunc_name + opname_len + 2;
5100
5101 for (nmode = first_mode; nmode != VOIDmode;
5102 nmode = GET_MODE_WIDER_MODE (nmode))
5103 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5104 wmode = GET_MODE_WIDER_MODE (wmode))
5105 {
5106 nname = GET_MODE_NAME (nmode);
5107 wname = GET_MODE_NAME (wmode);
5108
5109 p = suffix;
5110 for (q = widening ? nname : wname; *q; p++, q++)
5111 *p = TOLOWER (*q);
5112 for (q = widening ? wname : nname; *q; p++, q++)
5113 *p = TOLOWER (*q);
5114
5115 *p++ = '2';
5116 *p = '/0';
5117
5118 tab->handlers[widening ? wmode : nmode]
5119 [widening ? nmode : wmode].libfunc
5120 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5121 p - libfunc_name));
5122 }
5123 }
All these library functions aren’t implemented also, these operations rely on the instructions given by machine description file.
init_optabs (continue)
5368 /* Use cabs for double complex abs, since systems generally have cabs.
5369 Don't define any libcall for float complex, so that cabs will be used. */
5370 if (complex_double_type_node)
5371 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5372 = init_one_libfunc ("cabs");
5373
5374 /* The ffs function operates on `int'. */
5375 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5376 = init_one_libfunc ("ffs");
5377
5378 abort_libfunc = init_one_libfunc ("abort");
5379 memcpy_libfunc = init_one_libfunc ("memcpy");
5380 memmove_libfunc = init_one_libfunc ("memmove");
5381 bcopy_libfunc = init_one_libfunc ("bcopy");
5382 memcmp_libfunc = init_one_libfunc ("memcmp");
5383 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5384 memset_libfunc = init_one_libfunc ("memset");
5385 bzero_libfunc = init_one_libfunc ("bzero");
5386 setbits_libfunc = init_one_libfunc ("__setbits");
5387
5388 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5389 ? "_Unwind_SjLj_Resume"
5390 : "_Unwind_Resume");
5391 #ifndef DONT_USE_BUILTIN_SETJMP
5392 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5393 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5394 #else
5395 setjmp_libfunc = init_one_libfunc ("setjmp");
5396 longjmp_libfunc = init_one_libfunc ("longjmp");
5397 #endif
5398 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5399 unwind_sjlj_unregister_libfunc
5400 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5401
5402 /* For function entry/exit instrumentation. */
5403 profile_function_entry_libfunc
5404 = init_one_libfunc ("__cyg_profile_func_enter");
5405 profile_function_exit_libfunc
5406 = init_one_libfunc ("__cyg_profile_func_exit");
5407
5408 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5409 gcov_init_libfunc = init_one_libfunc ("__gcov_init");
5410
5411 if (HAVE_conditional_trap)
5412 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5413
5414 /* Allow the target to add more libcalls or rename some, etc. */
5415 targetm.init_libfuncs ();
5416 }
In the install directory, there is sub-diretory “lib”. Within it are libraries compiler would use (of course, they are compiled at installing from the gcc source code). With tool nm, you can find out most functions above. At line 5415, hook init_libfuncs gives the target a chance to add in its library calls or rename some, but for x86, it needesn’t.