1 /* Mapping from optabs to underlying library functions 2 Copyright (C) 1987-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "target.h" 25 #include "insn-codes.h" 26 #include "optabs-libfuncs.h" 27 #include "libfuncs.h" 28 #include "optabs-query.h" 29 #include "tree.h" 30 #include "stringpool.h" 31 #include "varasm.h" 32 #include "stor-layout.h" 33 #include "rtl.h" 34 35 struct target_libfuncs default_target_libfuncs; 36 #if SWITCHABLE_TARGET 37 struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs; 38 #endif 39 40 #define libfunc_hash \ 41 (this_target_libfuncs->x_libfunc_hash) 42 43 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */ 44 #if ENABLE_DECIMAL_BID_FORMAT 45 #define DECIMAL_PREFIX "bid_" 46 #else 47 #define DECIMAL_PREFIX "dpd_" 48 #endif 49 50 /* Used for libfunc_hash. */ 51 52 hashval_t 53 libfunc_hasher::hash (libfunc_entry *e) 54 { 55 return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op); 56 } 57 58 /* Used for libfunc_hash. */ 59 60 bool 61 libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2) 62 { 63 return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2; 64 } 65 66 /* Return libfunc corresponding operation defined by OPTAB converting 67 from MODE2 to MODE1. Trigger lazy initialization if needed, return NULL 68 if no libfunc is available. */ 69 rtx 70 convert_optab_libfunc (convert_optab optab, machine_mode mode1, 71 machine_mode mode2) 72 { 73 struct libfunc_entry e; 74 struct libfunc_entry **slot; 75 76 /* ??? This ought to be an assert, but not all of the places 77 that we expand optabs know about the optabs that got moved 78 to being direct. */ 79 if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB)) 80 return NULL_RTX; 81 82 e.op = optab; 83 e.mode1 = mode1; 84 e.mode2 = mode2; 85 slot = libfunc_hash->find_slot (&e, NO_INSERT); 86 if (!slot) 87 { 88 const struct convert_optab_libcall_d *d 89 = &convlib_def[optab - FIRST_CONV_OPTAB]; 90 91 if (d->libcall_gen == NULL) 92 return NULL; 93 94 d->libcall_gen (optab, d->libcall_basename, mode1, mode2); 95 slot = libfunc_hash->find_slot (&e, NO_INSERT); 96 if (!slot) 97 return NULL; 98 } 99 return (*slot)->libfunc; 100 } 101 102 /* Return libfunc corresponding operation defined by OPTAB in MODE. 103 Trigger lazy initialization if needed, return NULL if no libfunc is 104 available. */ 105 rtx 106 optab_libfunc (optab optab, machine_mode mode) 107 { 108 struct libfunc_entry e; 109 struct libfunc_entry **slot; 110 111 /* ??? This ought to be an assert, but not all of the places 112 that we expand optabs know about the optabs that got moved 113 to being direct. */ 114 if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB)) 115 return NULL_RTX; 116 117 e.op = optab; 118 e.mode1 = mode; 119 e.mode2 = VOIDmode; 120 slot = libfunc_hash->find_slot (&e, NO_INSERT); 121 if (!slot) 122 { 123 const struct optab_libcall_d *d 124 = &normlib_def[optab - FIRST_NORM_OPTAB]; 125 126 if (d->libcall_gen == NULL) 127 return NULL; 128 129 d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode); 130 slot = libfunc_hash->find_slot (&e, NO_INSERT); 131 if (!slot) 132 return NULL; 133 } 134 return (*slot)->libfunc; 135 } 136 137 /* Initialize the libfunc fields of an entire group of entries in some 138 optab. Each entry is set equal to a string consisting of a leading 139 pair of underscores followed by a generic operation name followed by 140 a mode name (downshifted to lowercase) followed by a single character 141 representing the number of operands for the given operation (which is 142 usually one of the characters '2', '3', or '4'). 143 144 OPTABLE is the table in which libfunc fields are to be initialized. 145 OPNAME is the generic (string) name of the operation. 146 SUFFIX is the character which specifies the number of operands for 147 the given generic operation. 148 MODE is the mode to generate for. */ 149 150 static void 151 gen_libfunc (optab optable, const char *opname, int suffix, 152 machine_mode mode) 153 { 154 unsigned opname_len = strlen (opname); 155 const char *mname = GET_MODE_NAME (mode); 156 unsigned mname_len = strlen (mname); 157 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2; 158 int len = prefix_len + opname_len + mname_len + 1 + 1; 159 char *libfunc_name = XALLOCAVEC (char, len); 160 char *p; 161 const char *q; 162 163 p = libfunc_name; 164 *p++ = '_'; 165 *p++ = '_'; 166 if (targetm.libfunc_gnu_prefix) 167 { 168 *p++ = 'g'; 169 *p++ = 'n'; 170 *p++ = 'u'; 171 *p++ = '_'; 172 } 173 for (q = opname; *q;) 174 *p++ = *q++; 175 for (q = mname; *q; q++) 176 *p++ = TOLOWER (*q); 177 *p++ = suffix; 178 *p = '\0'; 179 180 set_optab_libfunc (optable, mode, 181 ggc_alloc_string (libfunc_name, p - libfunc_name)); 182 } 183 184 /* Like gen_libfunc, but verify that integer operation is involved. */ 185 186 void 187 gen_int_libfunc (optab optable, const char *opname, char suffix, 188 machine_mode mode) 189 { 190 int maxsize = 2 * BITS_PER_WORD; 191 int minsize = BITS_PER_WORD; 192 scalar_int_mode int_mode; 193 194 if (!is_int_mode (mode, &int_mode)) 195 return; 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) 204 return; 205 gen_libfunc (optable, opname, suffix, int_mode); 206 } 207 208 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */ 209 210 void 211 gen_fp_libfunc (optab optable, const char *opname, char suffix, 212 machine_mode mode) 213 { 214 char *dec_opname; 215 216 if (GET_MODE_CLASS (mode) == MODE_FLOAT) 217 gen_libfunc (optable, opname, suffix, mode); 218 if (DECIMAL_FLOAT_MODE_P (mode)) 219 { 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); 226 } 227 } 228 229 /* Like gen_libfunc, but verify that fixed-point operation is involved. */ 230 231 void 232 gen_fixed_libfunc (optab optable, const char *opname, char suffix, 233 machine_mode mode) 234 { 235 if (!ALL_FIXED_POINT_MODE_P (mode)) 236 return; 237 gen_libfunc (optable, opname, suffix, mode); 238 } 239 240 /* Like gen_libfunc, but verify that signed fixed-point operation is 241 involved. */ 242 243 void 244 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix, 245 machine_mode mode) 246 { 247 if (!SIGNED_FIXED_POINT_MODE_P (mode)) 248 return; 249 gen_libfunc (optable, opname, suffix, mode); 250 } 251 252 /* Like gen_libfunc, but verify that unsigned fixed-point operation is 253 involved. */ 254 255 void 256 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix, 257 machine_mode mode) 258 { 259 if (!UNSIGNED_FIXED_POINT_MODE_P (mode)) 260 return; 261 gen_libfunc (optable, opname, suffix, mode); 262 } 263 264 /* Like gen_libfunc, but verify that FP or INT operation is involved. */ 265 266 void 267 gen_int_fp_libfunc (optab optable, const char *name, char suffix, 268 machine_mode mode) 269 { 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); 274 } 275 276 /* Like gen_libfunc, but verify that FP or INT operation is involved 277 and add 'v' suffix for integer operation. */ 278 279 void 280 gen_intv_fp_libfunc (optab optable, const char *name, char suffix, 281 machine_mode mode) 282 { 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) 286 { 287 int len = strlen (name); 288 char *v_name = XALLOCAVEC (char, len + 2); 289 strcpy (v_name, name); 290 v_name[len] = 'v'; 291 v_name[len + 1] = 0; 292 gen_int_libfunc (optable, v_name, suffix, mode); 293 } 294 } 295 296 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is 297 involved. */ 298 299 void 300 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix, 301 machine_mode mode) 302 { 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); 309 } 310 311 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is 312 involved. */ 313 314 void 315 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix, 316 machine_mode mode) 317 { 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); 324 } 325 326 /* Like gen_libfunc, but verify that INT or FIXED operation is 327 involved. */ 328 329 void 330 gen_int_fixed_libfunc (optab optable, const char *name, char suffix, 331 machine_mode mode) 332 { 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); 337 } 338 339 /* Like gen_libfunc, but verify that INT or signed FIXED operation is 340 involved. */ 341 342 void 343 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix, 344 machine_mode mode) 345 { 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); 350 } 351 352 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is 353 involved. */ 354 355 void 356 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix, 357 machine_mode mode) 358 { 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); 363 } 364 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. */ 370 371 void 372 gen_interclass_conv_libfunc (convert_optab tab, 373 const char *opname, 374 machine_mode tmode, 375 machine_mode fmode) 376 { 377 size_t opname_len = strlen (opname); 378 size_t mname_len = 0; 379 380 const char *fname, *tname; 381 const char *q; 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; 385 char *p; 386 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; 390 391 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode)); 392 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) 397 { 398 nondec_name[2] = 'g'; 399 nondec_name[3] = 'n'; 400 nondec_name[4] = 'u'; 401 nondec_name[5] = '_'; 402 } 403 404 memcpy (&nondec_name[prefix_len], opname, opname_len); 405 nondec_suffix = nondec_name + opname_len + prefix_len; 406 407 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1); 408 dec_name[0] = '_'; 409 dec_name[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; 413 414 fname = GET_MODE_NAME (fmode); 415 tname = GET_MODE_NAME (tmode); 416 417 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode)) 418 { 419 libfunc_name = dec_name; 420 suffix = dec_suffix; 421 } 422 else 423 { 424 libfunc_name = nondec_name; 425 suffix = nondec_suffix; 426 } 427 428 p = suffix; 429 for (q = fname; *q; p++, q++) 430 *p = TOLOWER (*q); 431 for (q = tname; *q; p++, q++) 432 *p = TOLOWER (*q); 433 434 *p = '\0'; 435 436 set_conv_libfunc (tab, tmode, fmode, 437 ggc_alloc_string (libfunc_name, p - libfunc_name)); 438 } 439 440 /* Same as gen_interclass_conv_libfunc but verify that we are producing 441 int->fp conversion. */ 442 443 void 444 gen_int_to_fp_conv_libfunc (convert_optab tab, 445 const char *opname, 446 machine_mode tmode, 447 machine_mode fmode) 448 { 449 if (GET_MODE_CLASS (fmode) != MODE_INT) 450 return; 451 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode)) 452 return; 453 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 454 } 455 456 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp 457 naming scheme. */ 458 459 void 460 gen_ufloat_conv_libfunc (convert_optab tab, 461 const char *opname ATTRIBUTE_UNUSED, 462 machine_mode tmode, 463 machine_mode fmode) 464 { 465 if (DECIMAL_FLOAT_MODE_P (tmode)) 466 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode); 467 else 468 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode); 469 } 470 471 /* Same as gen_interclass_conv_libfunc but verify that we are producing 472 fp->int conversion. */ 473 474 void 475 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab, 476 const char *opname, 477 machine_mode tmode, 478 machine_mode fmode) 479 { 480 if (GET_MODE_CLASS (fmode) != MODE_INT) 481 return; 482 if (GET_MODE_CLASS (tmode) != MODE_FLOAT) 483 return; 484 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 485 } 486 487 /* Same as gen_interclass_conv_libfunc but verify that we are producing 488 fp->int conversion with no decimal floating point involved. */ 489 490 void 491 gen_fp_to_int_conv_libfunc (convert_optab tab, 492 const char *opname, 493 machine_mode tmode, 494 machine_mode fmode) 495 { 496 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode)) 497 return; 498 if (GET_MODE_CLASS (tmode) != MODE_INT) 499 return; 500 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 501 } 502 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. */ 506 507 void 508 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname, 509 machine_mode tmode, machine_mode fmode) 510 { 511 size_t opname_len = strlen (opname); 512 size_t mname_len = 0; 513 514 const char *fname, *tname; 515 const char *q; 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; 519 char *p; 520 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; 524 525 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode)); 526 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) 531 { 532 nondec_name[2] = 'g'; 533 nondec_name[3] = 'n'; 534 nondec_name[4] = 'u'; 535 nondec_name[5] = '_'; 536 } 537 memcpy (&nondec_name[prefix_len], opname, opname_len); 538 nondec_suffix = nondec_name + opname_len + prefix_len; 539 540 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1); 541 dec_name[0] = '_'; 542 dec_name[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; 546 547 fname = GET_MODE_NAME (fmode); 548 tname = GET_MODE_NAME (tmode); 549 550 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode)) 551 { 552 libfunc_name = dec_name; 553 suffix = dec_suffix; 554 } 555 else 556 { 557 libfunc_name = nondec_name; 558 suffix = nondec_suffix; 559 } 560 561 p = suffix; 562 for (q = fname; *q; p++, q++) 563 *p = TOLOWER (*q); 564 for (q = tname; *q; p++, q++) 565 *p = TOLOWER (*q); 566 567 *p++ = '2'; 568 *p = '\0'; 569 570 set_conv_libfunc (tab, tmode, fmode, 571 ggc_alloc_string (libfunc_name, p - libfunc_name)); 572 } 573 574 /* Pick proper libcall for trunc_optab. We need to chose if we do 575 truncation or extension and interclass or intraclass. */ 576 577 void 578 gen_trunc_conv_libfunc (convert_optab tab, 579 const char *opname, 580 machine_mode tmode, 581 machine_mode fmode) 582 { 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) 587 return; 588 589 if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode)) 590 gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode); 591 592 if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)) 593 return; 594 595 if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode)) 596 gen_intraclass_conv_libfunc (tab, opname, float_tmode, float_fmode); 597 } 598 599 /* Pick proper libcall for extend_optab. We need to chose if we do 600 truncation or extension and interclass or intraclass. */ 601 602 void 603 gen_extend_conv_libfunc (convert_optab tab, 604 const char *opname ATTRIBUTE_UNUSED, 605 machine_mode tmode, 606 machine_mode fmode) 607 { 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) 612 return; 613 614 if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode)) 615 gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode); 616 617 if (GET_MODE_PRECISION (float_fmode) > GET_MODE_PRECISION (float_tmode)) 618 return; 619 620 if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode)) 621 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 622 } 623 624 /* Pick proper libcall for fract_optab. We need to chose if we do 625 interclass or intraclass. */ 626 627 void 628 gen_fract_conv_libfunc (convert_optab tab, 629 const char *opname, 630 machine_mode tmode, 631 machine_mode fmode) 632 { 633 if (tmode == fmode) 634 return; 635 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode))) 636 return; 637 638 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode)) 639 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 640 else 641 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 642 } 643 644 /* Pick proper libcall for fractuns_optab. */ 645 646 void 647 gen_fractuns_conv_libfunc (convert_optab tab, 648 const char *opname, 649 machine_mode tmode, 650 machine_mode fmode) 651 { 652 if (tmode == fmode) 653 return; 654 /* One mode must be a fixed-point mode, and the other must be an integer 655 mode. */ 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))) 659 return; 660 661 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 662 } 663 664 /* Pick proper libcall for satfract_optab. We need to chose if we do 665 interclass or intraclass. */ 666 667 void 668 gen_satfract_conv_libfunc (convert_optab tab, 669 const char *opname, 670 machine_mode tmode, 671 machine_mode fmode) 672 { 673 if (tmode == fmode) 674 return; 675 /* TMODE must be a fixed-point mode. */ 676 if (!ALL_FIXED_POINT_MODE_P (tmode)) 677 return; 678 679 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode)) 680 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 681 else 682 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 683 } 684 685 /* Pick proper libcall for satfractuns_optab. */ 686 687 void 688 gen_satfractuns_conv_libfunc (convert_optab tab, 689 const char *opname, 690 machine_mode tmode, 691 machine_mode fmode) 692 { 693 if (tmode == fmode) 694 return; 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)) 697 return; 698 699 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 700 } 701 702 /* Hashtable callbacks for libfunc_decls. */ 703 704 struct libfunc_decl_hasher : ggc_ptr_hash<tree_node> 705 { 706 static hashval_t 707 hash (tree entry) 708 { 709 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry)); 710 } 711 712 static bool 713 equal (tree decl, tree name) 714 { 715 return DECL_NAME (decl) == name; 716 } 717 }; 718 719 /* A table of previously-created libfuncs, hashed by name. */ 720 static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls; 721 722 /* Build a decl for a libfunc named NAME. */ 723 724 tree 725 build_libfunc_function (const char *name) 726 { 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) = VISIBILITY_DEFAULT; 735 DECL_VISIBILITY_SPECIFIED (decl) = 1; 736 gcc_assert (DECL_ASSEMBLER_NAME (decl)); 737 738 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with 739 are the flags assigned by targetm.encode_section_info. */ 740 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL); 741 742 return decl; 743 } 744 745 /* Return a libfunc for NAME, creating one if we don't already have one. 746 The returned rtx is a SYMBOL_REF. */ 747 748 rtx 749 init_one_libfunc (const char *name) 750 { 751 tree id, decl; 752 hashval_t hash; 753 754 if (libfunc_decls == NULL) 755 libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37); 756 757 /* See if we have already created a libfunc decl for this function. */ 758 id = get_identifier (name); 759 hash = IDENTIFIER_HASH_VALUE (id); 760 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT); 761 decl = *slot; 762 if (decl == NULL) 763 { 764 /* Create a new decl, so that it can be passed to 765 targetm.encode_section_info. */ 766 decl = build_libfunc_function (name); 767 *slot = decl; 768 } 769 return XEXP (DECL_RTL (decl), 0); 770 } 771 772 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */ 773 774 rtx 775 set_user_assembler_libfunc (const char *name, const char *asmspec) 776 { 777 tree id, decl; 778 hashval_t hash; 779 780 id = get_identifier (name); 781 hash = IDENTIFIER_HASH_VALUE (id); 782 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT); 783 gcc_assert (slot); 784 decl = (tree) *slot; 785 set_user_assembler_name (decl, asmspec); 786 return XEXP (DECL_RTL (decl), 0); 787 } 788 789 /* Call this to reset the function entry for one optab (OPTABLE) in mode 790 MODE to NAME, which should be either 0 or a string constant. */ 791 792 void 793 set_optab_libfunc (optab op, machine_mode mode, const char *name) 794 { 795 rtx val; 796 struct libfunc_entry e; 797 struct libfunc_entry **slot; 798 799 e.op = op; 800 e.mode1 = mode; 801 e.mode2 = VOIDmode; 802 803 if (name) 804 val = init_one_libfunc (name); 805 else 806 val = 0; 807 slot = libfunc_hash->find_slot (&e, INSERT); 808 if (*slot == NULL) 809 *slot = ggc_alloc<libfunc_entry> (); 810 (*slot)->op = op; 811 (*slot)->mode1 = mode; 812 (*slot)->mode2 = VOIDmode; 813 (*slot)->libfunc = val; 814 } 815 816 /* Call this to reset the function entry for one conversion optab 817 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be 818 either 0 or a string constant. */ 819 820 void 821 set_conv_libfunc (convert_optab optab, machine_mode tmode, 822 machine_mode fmode, const char *name) 823 { 824 rtx val; 825 struct libfunc_entry e; 826 struct libfunc_entry **slot; 827 828 e.op = optab; 829 e.mode1 = tmode; 830 e.mode2 = fmode; 831 832 if (name) 833 val = init_one_libfunc (name); 834 else 835 val = 0; 836 slot = libfunc_hash->find_slot (&e, INSERT); 837 if (*slot == NULL) 838 *slot = ggc_alloc<libfunc_entry> (); 839 (*slot)->op = optab; 840 (*slot)->mode1 = tmode; 841 (*slot)->mode2 = fmode; 842 (*slot)->libfunc = val; 843 } 844 845 /* Call this to initialize the contents of the optabs 846 appropriately for the current target machine. */ 847 848 void 849 init_optabs (void) 850 { 851 if (libfunc_hash) 852 libfunc_hash->empty (); 853 else 854 libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10); 855 856 /* Fill in the optabs with the insns we support. */ 857 init_all_optabs (this_fn_optabs); 858 859 /* The ffs function operates on `int'. Fall back on it if we do not 860 have a libgcc2 function for that width. */ 861 if (INT_TYPE_SIZE < BITS_PER_WORD) 862 { 863 scalar_int_mode mode = int_mode_for_size (INT_TYPE_SIZE, 0).require (); 864 set_optab_libfunc (ffs_optab, mode, "ffs"); 865 } 866 867 /* Explicitly initialize the bswap libfuncs since we need them to be 868 valid for things other than word_mode. */ 869 if (targetm.libfunc_gnu_prefix) 870 { 871 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2"); 872 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2"); 873 } 874 else 875 { 876 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2"); 877 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2"); 878 } 879 880 /* Use cabs for double complex abs, since systems generally have cabs. 881 Don't define any libcall for float complex, so that cabs will be used. */ 882 if (complex_double_type_node) 883 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), 884 "cabs"); 885 886 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register"); 887 unwind_sjlj_unregister_libfunc 888 = init_one_libfunc ("_Unwind_SjLj_Unregister"); 889 890 /* Allow the target to add more libcalls or rename some, etc. */ 891 targetm.init_libfuncs (); 892 } 893 894 /* A helper function for init_sync_libfuncs. Using the basename BASE, 895 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */ 896 897 static void 898 init_sync_libfuncs_1 (optab tab, const char *base, int max) 899 { 900 machine_mode mode; 901 char buf[64]; 902 size_t len = strlen (base); 903 int i; 904 905 gcc_assert (max <= 8); 906 gcc_assert (len + 3 < sizeof (buf)); 907 908 memcpy (buf, base, len); 909 buf[len] = '_'; 910 buf[len + 1] = '0'; 911 buf[len + 2] = '\0'; 912 913 mode = QImode; 914 for (i = 1; i <= max; i *= 2) 915 { 916 if (i > 1) 917 mode = GET_MODE_2XWIDER_MODE (mode).require (); 918 buf[len + 1] = '0' + i; 919 set_optab_libfunc (tab, mode, buf); 920 } 921 } 922 923 void 924 init_sync_libfuncs (int max) 925 { 926 if (!flag_sync_libcalls) 927 return; 928 929 init_sync_libfuncs_1 (sync_compare_and_swap_optab, 930 "__sync_val_compare_and_swap", max); 931 init_sync_libfuncs_1 (sync_lock_test_and_set_optab, 932 "__sync_lock_test_and_set", max); 933 934 init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max); 935 init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max); 936 init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max); 937 init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max); 938 init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max); 939 init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max); 940 941 init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max); 942 init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max); 943 init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max); 944 init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max); 945 init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max); 946 init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max); 947 } 948 949 #include "gt-optabs-libfuncs.h" 950