1 /* Mapping from optabs to underlying library functions 2 Copyright (C) 1987-2017 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 193 if (GET_MODE_CLASS (mode) != MODE_INT) 194 return; 195 if (maxsize < LONG_LONG_TYPE_SIZE) 196 maxsize = LONG_LONG_TYPE_SIZE; 197 if (minsize > INT_TYPE_SIZE 198 && (trapv_binoptab_p (optable) 199 || trapv_unoptab_p (optable))) 200 minsize = INT_TYPE_SIZE; 201 if (GET_MODE_BITSIZE (mode) < minsize 202 || GET_MODE_BITSIZE (mode) > maxsize) 203 return; 204 gen_libfunc (optable, opname, suffix, mode); 205 } 206 207 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */ 208 209 void 210 gen_fp_libfunc (optab optable, const char *opname, char suffix, 211 machine_mode mode) 212 { 213 char *dec_opname; 214 215 if (GET_MODE_CLASS (mode) == MODE_FLOAT) 216 gen_libfunc (optable, opname, suffix, mode); 217 if (DECIMAL_FLOAT_MODE_P (mode)) 218 { 219 dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname)); 220 /* For BID support, change the name to have either a bid_ or dpd_ prefix 221 depending on the low level floating format used. */ 222 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1); 223 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname); 224 gen_libfunc (optable, dec_opname, suffix, mode); 225 } 226 } 227 228 /* Like gen_libfunc, but verify that fixed-point operation is involved. */ 229 230 void 231 gen_fixed_libfunc (optab optable, const char *opname, char suffix, 232 machine_mode mode) 233 { 234 if (!ALL_FIXED_POINT_MODE_P (mode)) 235 return; 236 gen_libfunc (optable, opname, suffix, mode); 237 } 238 239 /* Like gen_libfunc, but verify that signed fixed-point operation is 240 involved. */ 241 242 void 243 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix, 244 machine_mode mode) 245 { 246 if (!SIGNED_FIXED_POINT_MODE_P (mode)) 247 return; 248 gen_libfunc (optable, opname, suffix, mode); 249 } 250 251 /* Like gen_libfunc, but verify that unsigned fixed-point operation is 252 involved. */ 253 254 void 255 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix, 256 machine_mode mode) 257 { 258 if (!UNSIGNED_FIXED_POINT_MODE_P (mode)) 259 return; 260 gen_libfunc (optable, opname, suffix, mode); 261 } 262 263 /* Like gen_libfunc, but verify that FP or INT operation is involved. */ 264 265 void 266 gen_int_fp_libfunc (optab optable, const char *name, char suffix, 267 machine_mode mode) 268 { 269 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT) 270 gen_fp_libfunc (optable, name, suffix, mode); 271 if (INTEGRAL_MODE_P (mode)) 272 gen_int_libfunc (optable, name, suffix, mode); 273 } 274 275 /* Like gen_libfunc, but verify that FP or INT operation is involved 276 and add 'v' suffix for integer operation. */ 277 278 void 279 gen_intv_fp_libfunc (optab optable, const char *name, char suffix, 280 machine_mode mode) 281 { 282 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT) 283 gen_fp_libfunc (optable, name, suffix, mode); 284 if (GET_MODE_CLASS (mode) == MODE_INT) 285 { 286 int len = strlen (name); 287 char *v_name = XALLOCAVEC (char, len + 2); 288 strcpy (v_name, name); 289 v_name[len] = 'v'; 290 v_name[len + 1] = 0; 291 gen_int_libfunc (optable, v_name, suffix, mode); 292 } 293 } 294 295 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is 296 involved. */ 297 298 void 299 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix, 300 machine_mode mode) 301 { 302 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT) 303 gen_fp_libfunc (optable, name, suffix, mode); 304 if (INTEGRAL_MODE_P (mode)) 305 gen_int_libfunc (optable, name, suffix, mode); 306 if (ALL_FIXED_POINT_MODE_P (mode)) 307 gen_fixed_libfunc (optable, name, suffix, mode); 308 } 309 310 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is 311 involved. */ 312 313 void 314 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix, 315 machine_mode mode) 316 { 317 if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT) 318 gen_fp_libfunc (optable, name, suffix, mode); 319 if (INTEGRAL_MODE_P (mode)) 320 gen_int_libfunc (optable, name, suffix, mode); 321 if (SIGNED_FIXED_POINT_MODE_P (mode)) 322 gen_signed_fixed_libfunc (optable, name, suffix, mode); 323 } 324 325 /* Like gen_libfunc, but verify that INT or FIXED operation is 326 involved. */ 327 328 void 329 gen_int_fixed_libfunc (optab optable, const char *name, char suffix, 330 machine_mode mode) 331 { 332 if (INTEGRAL_MODE_P (mode)) 333 gen_int_libfunc (optable, name, suffix, mode); 334 if (ALL_FIXED_POINT_MODE_P (mode)) 335 gen_fixed_libfunc (optable, name, suffix, mode); 336 } 337 338 /* Like gen_libfunc, but verify that INT or signed FIXED operation is 339 involved. */ 340 341 void 342 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix, 343 machine_mode mode) 344 { 345 if (INTEGRAL_MODE_P (mode)) 346 gen_int_libfunc (optable, name, suffix, mode); 347 if (SIGNED_FIXED_POINT_MODE_P (mode)) 348 gen_signed_fixed_libfunc (optable, name, suffix, mode); 349 } 350 351 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is 352 involved. */ 353 354 void 355 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix, 356 machine_mode mode) 357 { 358 if (INTEGRAL_MODE_P (mode)) 359 gen_int_libfunc (optable, name, suffix, mode); 360 if (UNSIGNED_FIXED_POINT_MODE_P (mode)) 361 gen_unsigned_fixed_libfunc (optable, name, suffix, mode); 362 } 363 364 /* Initialize the libfunc fields of an entire group of entries of an 365 inter-mode-class conversion optab. The string formation rules are 366 similar to the ones for init_libfuncs, above, but instead of having 367 a mode name and an operand count these functions have two mode names 368 and no operand count. */ 369 370 void 371 gen_interclass_conv_libfunc (convert_optab tab, 372 const char *opname, 373 machine_mode tmode, 374 machine_mode fmode) 375 { 376 size_t opname_len = strlen (opname); 377 size_t mname_len = 0; 378 379 const char *fname, *tname; 380 const char *q; 381 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2; 382 char *libfunc_name, *suffix; 383 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix; 384 char *p; 385 386 /* If this is a decimal conversion, add the current BID vs. DPD prefix that 387 depends on which underlying decimal floating point format is used. */ 388 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1; 389 390 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode)); 391 392 nondec_name = XALLOCAVEC (char, prefix_len + opname_len + mname_len + 1 + 1); 393 nondec_name[0] = '_'; 394 nondec_name[1] = '_'; 395 if (targetm.libfunc_gnu_prefix) 396 { 397 nondec_name[2] = 'g'; 398 nondec_name[3] = 'n'; 399 nondec_name[4] = 'u'; 400 nondec_name[5] = '_'; 401 } 402 403 memcpy (&nondec_name[prefix_len], opname, opname_len); 404 nondec_suffix = nondec_name + opname_len + prefix_len; 405 406 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1); 407 dec_name[0] = '_'; 408 dec_name[1] = '_'; 409 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len); 410 memcpy (&dec_name[2+dec_len], opname, opname_len); 411 dec_suffix = dec_name + dec_len + opname_len + 2; 412 413 fname = GET_MODE_NAME (fmode); 414 tname = GET_MODE_NAME (tmode); 415 416 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode)) 417 { 418 libfunc_name = dec_name; 419 suffix = dec_suffix; 420 } 421 else 422 { 423 libfunc_name = nondec_name; 424 suffix = nondec_suffix; 425 } 426 427 p = suffix; 428 for (q = fname; *q; p++, q++) 429 *p = TOLOWER (*q); 430 for (q = tname; *q; p++, q++) 431 *p = TOLOWER (*q); 432 433 *p = '\0'; 434 435 set_conv_libfunc (tab, tmode, fmode, 436 ggc_alloc_string (libfunc_name, p - libfunc_name)); 437 } 438 439 /* Same as gen_interclass_conv_libfunc but verify that we are producing 440 int->fp conversion. */ 441 442 void 443 gen_int_to_fp_conv_libfunc (convert_optab tab, 444 const char *opname, 445 machine_mode tmode, 446 machine_mode fmode) 447 { 448 if (GET_MODE_CLASS (fmode) != MODE_INT) 449 return; 450 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode)) 451 return; 452 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 453 } 454 455 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp 456 naming scheme. */ 457 458 void 459 gen_ufloat_conv_libfunc (convert_optab tab, 460 const char *opname ATTRIBUTE_UNUSED, 461 machine_mode tmode, 462 machine_mode fmode) 463 { 464 if (DECIMAL_FLOAT_MODE_P (tmode)) 465 gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode); 466 else 467 gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode); 468 } 469 470 /* Same as gen_interclass_conv_libfunc but verify that we are producing 471 fp->int conversion. */ 472 473 void 474 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab, 475 const char *opname, 476 machine_mode tmode, 477 machine_mode fmode) 478 { 479 if (GET_MODE_CLASS (fmode) != MODE_INT) 480 return; 481 if (GET_MODE_CLASS (tmode) != MODE_FLOAT) 482 return; 483 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 484 } 485 486 /* Same as gen_interclass_conv_libfunc but verify that we are producing 487 fp->int conversion with no decimal floating point involved. */ 488 489 void 490 gen_fp_to_int_conv_libfunc (convert_optab tab, 491 const char *opname, 492 machine_mode tmode, 493 machine_mode fmode) 494 { 495 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode)) 496 return; 497 if (GET_MODE_CLASS (tmode) != MODE_INT) 498 return; 499 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 500 } 501 502 /* Initialize the libfunc fields of an of an intra-mode-class conversion optab. 503 The string formation rules are 504 similar to the ones for init_libfunc, above. */ 505 506 void 507 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname, 508 machine_mode tmode, machine_mode fmode) 509 { 510 size_t opname_len = strlen (opname); 511 size_t mname_len = 0; 512 513 const char *fname, *tname; 514 const char *q; 515 int prefix_len = targetm.libfunc_gnu_prefix ? 6 : 2; 516 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix; 517 char *libfunc_name, *suffix; 518 char *p; 519 520 /* If this is a decimal conversion, add the current BID vs. DPD prefix that 521 depends on which underlying decimal floating point format is used. */ 522 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1; 523 524 mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode)); 525 526 nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1); 527 nondec_name[0] = '_'; 528 nondec_name[1] = '_'; 529 if (targetm.libfunc_gnu_prefix) 530 { 531 nondec_name[2] = 'g'; 532 nondec_name[3] = 'n'; 533 nondec_name[4] = 'u'; 534 nondec_name[5] = '_'; 535 } 536 memcpy (&nondec_name[prefix_len], opname, opname_len); 537 nondec_suffix = nondec_name + opname_len + prefix_len; 538 539 dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1); 540 dec_name[0] = '_'; 541 dec_name[1] = '_'; 542 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len); 543 memcpy (&dec_name[2 + dec_len], opname, opname_len); 544 dec_suffix = dec_name + dec_len + opname_len + 2; 545 546 fname = GET_MODE_NAME (fmode); 547 tname = GET_MODE_NAME (tmode); 548 549 if (DECIMAL_FLOAT_MODE_P (fmode) || DECIMAL_FLOAT_MODE_P (tmode)) 550 { 551 libfunc_name = dec_name; 552 suffix = dec_suffix; 553 } 554 else 555 { 556 libfunc_name = nondec_name; 557 suffix = nondec_suffix; 558 } 559 560 p = suffix; 561 for (q = fname; *q; p++, q++) 562 *p = TOLOWER (*q); 563 for (q = tname; *q; p++, q++) 564 *p = TOLOWER (*q); 565 566 *p++ = '2'; 567 *p = '\0'; 568 569 set_conv_libfunc (tab, tmode, fmode, 570 ggc_alloc_string (libfunc_name, p - libfunc_name)); 571 } 572 573 /* Pick proper libcall for trunc_optab. We need to chose if we do 574 truncation or extension and interclass or intraclass. */ 575 576 void 577 gen_trunc_conv_libfunc (convert_optab tab, 578 const char *opname, 579 machine_mode tmode, 580 machine_mode fmode) 581 { 582 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode)) 583 return; 584 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode)) 585 return; 586 if (tmode == fmode) 587 return; 588 589 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode)) 590 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode))) 591 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 592 593 if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode)) 594 return; 595 596 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT 597 && GET_MODE_CLASS (fmode) == MODE_FLOAT) 598 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode))) 599 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 600 } 601 602 /* Pick proper libcall for extend_optab. We need to chose if we do 603 truncation or extension and interclass or intraclass. */ 604 605 void 606 gen_extend_conv_libfunc (convert_optab tab, 607 const char *opname ATTRIBUTE_UNUSED, 608 machine_mode tmode, 609 machine_mode fmode) 610 { 611 if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode)) 612 return; 613 if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode)) 614 return; 615 if (tmode == fmode) 616 return; 617 618 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode)) 619 || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode))) 620 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 621 622 if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode)) 623 return; 624 625 if ((GET_MODE_CLASS (tmode) == MODE_FLOAT 626 && GET_MODE_CLASS (fmode) == MODE_FLOAT) 627 || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode))) 628 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 629 } 630 631 /* Pick proper libcall for fract_optab. We need to chose if we do 632 interclass or intraclass. */ 633 634 void 635 gen_fract_conv_libfunc (convert_optab tab, 636 const char *opname, 637 machine_mode tmode, 638 machine_mode fmode) 639 { 640 if (tmode == fmode) 641 return; 642 if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode))) 643 return; 644 645 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode)) 646 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 647 else 648 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 649 } 650 651 /* Pick proper libcall for fractuns_optab. */ 652 653 void 654 gen_fractuns_conv_libfunc (convert_optab tab, 655 const char *opname, 656 machine_mode tmode, 657 machine_mode fmode) 658 { 659 if (tmode == fmode) 660 return; 661 /* One mode must be a fixed-point mode, and the other must be an integer 662 mode. */ 663 if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT) 664 || (ALL_FIXED_POINT_MODE_P (fmode) 665 && GET_MODE_CLASS (tmode) == MODE_INT))) 666 return; 667 668 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 669 } 670 671 /* Pick proper libcall for satfract_optab. We need to chose if we do 672 interclass or intraclass. */ 673 674 void 675 gen_satfract_conv_libfunc (convert_optab tab, 676 const char *opname, 677 machine_mode tmode, 678 machine_mode fmode) 679 { 680 if (tmode == fmode) 681 return; 682 /* TMODE must be a fixed-point mode. */ 683 if (!ALL_FIXED_POINT_MODE_P (tmode)) 684 return; 685 686 if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode)) 687 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode); 688 else 689 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 690 } 691 692 /* Pick proper libcall for satfractuns_optab. */ 693 694 void 695 gen_satfractuns_conv_libfunc (convert_optab tab, 696 const char *opname, 697 machine_mode tmode, 698 machine_mode fmode) 699 { 700 if (tmode == fmode) 701 return; 702 /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */ 703 if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)) 704 return; 705 706 gen_interclass_conv_libfunc (tab, opname, tmode, fmode); 707 } 708 709 /* Hashtable callbacks for libfunc_decls. */ 710 711 struct libfunc_decl_hasher : ggc_ptr_hash<tree_node> 712 { 713 static hashval_t 714 hash (tree entry) 715 { 716 return IDENTIFIER_HASH_VALUE (DECL_NAME (entry)); 717 } 718 719 static bool 720 equal (tree decl, tree name) 721 { 722 return DECL_NAME (decl) == name; 723 } 724 }; 725 726 /* A table of previously-created libfuncs, hashed by name. */ 727 static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls; 728 729 /* Build a decl for a libfunc named NAME. */ 730 731 tree 732 build_libfunc_function (const char *name) 733 { 734 /* ??? We don't have any type information; pretend this is "int foo ()". */ 735 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, 736 get_identifier (name), 737 build_function_type (integer_type_node, NULL_TREE)); 738 DECL_EXTERNAL (decl) = 1; 739 TREE_PUBLIC (decl) = 1; 740 DECL_ARTIFICIAL (decl) = 1; 741 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; 742 DECL_VISIBILITY_SPECIFIED (decl) = 1; 743 gcc_assert (DECL_ASSEMBLER_NAME (decl)); 744 745 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with 746 are the flags assigned by targetm.encode_section_info. */ 747 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL); 748 749 return decl; 750 } 751 752 /* Return a libfunc for NAME, creating one if we don't already have one. 753 The returned rtx is a SYMBOL_REF. */ 754 755 rtx 756 init_one_libfunc (const char *name) 757 { 758 tree id, decl; 759 hashval_t hash; 760 761 if (libfunc_decls == NULL) 762 libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37); 763 764 /* See if we have already created a libfunc decl for this function. */ 765 id = get_identifier (name); 766 hash = IDENTIFIER_HASH_VALUE (id); 767 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT); 768 decl = *slot; 769 if (decl == NULL) 770 { 771 /* Create a new decl, so that it can be passed to 772 targetm.encode_section_info. */ 773 decl = build_libfunc_function (name); 774 *slot = decl; 775 } 776 return XEXP (DECL_RTL (decl), 0); 777 } 778 779 /* Adjust the assembler name of libfunc NAME to ASMSPEC. */ 780 781 rtx 782 set_user_assembler_libfunc (const char *name, const char *asmspec) 783 { 784 tree id, decl; 785 hashval_t hash; 786 787 id = get_identifier (name); 788 hash = IDENTIFIER_HASH_VALUE (id); 789 tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT); 790 gcc_assert (slot); 791 decl = (tree) *slot; 792 set_user_assembler_name (decl, asmspec); 793 return XEXP (DECL_RTL (decl), 0); 794 } 795 796 /* Call this to reset the function entry for one optab (OPTABLE) in mode 797 MODE to NAME, which should be either 0 or a string constant. */ 798 799 void 800 set_optab_libfunc (optab op, machine_mode mode, const char *name) 801 { 802 rtx val; 803 struct libfunc_entry e; 804 struct libfunc_entry **slot; 805 806 e.op = op; 807 e.mode1 = mode; 808 e.mode2 = VOIDmode; 809 810 if (name) 811 val = init_one_libfunc (name); 812 else 813 val = 0; 814 slot = libfunc_hash->find_slot (&e, INSERT); 815 if (*slot == NULL) 816 *slot = ggc_alloc<libfunc_entry> (); 817 (*slot)->op = op; 818 (*slot)->mode1 = mode; 819 (*slot)->mode2 = VOIDmode; 820 (*slot)->libfunc = val; 821 } 822 823 /* Call this to reset the function entry for one conversion optab 824 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be 825 either 0 or a string constant. */ 826 827 void 828 set_conv_libfunc (convert_optab optab, machine_mode tmode, 829 machine_mode fmode, const char *name) 830 { 831 rtx val; 832 struct libfunc_entry e; 833 struct libfunc_entry **slot; 834 835 e.op = optab; 836 e.mode1 = tmode; 837 e.mode2 = fmode; 838 839 if (name) 840 val = init_one_libfunc (name); 841 else 842 val = 0; 843 slot = libfunc_hash->find_slot (&e, INSERT); 844 if (*slot == NULL) 845 *slot = ggc_alloc<libfunc_entry> (); 846 (*slot)->op = optab; 847 (*slot)->mode1 = tmode; 848 (*slot)->mode2 = fmode; 849 (*slot)->libfunc = val; 850 } 851 852 /* Call this to initialize the contents of the optabs 853 appropriately for the current target machine. */ 854 855 void 856 init_optabs (void) 857 { 858 if (libfunc_hash) 859 libfunc_hash->empty (); 860 else 861 libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10); 862 863 /* Fill in the optabs with the insns we support. */ 864 init_all_optabs (this_fn_optabs); 865 866 /* The ffs function operates on `int'. Fall back on it if we do not 867 have a libgcc2 function for that width. */ 868 if (INT_TYPE_SIZE < BITS_PER_WORD) 869 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0), 870 "ffs"); 871 872 /* Explicitly initialize the bswap libfuncs since we need them to be 873 valid for things other than word_mode. */ 874 if (targetm.libfunc_gnu_prefix) 875 { 876 set_optab_libfunc (bswap_optab, SImode, "__gnu_bswapsi2"); 877 set_optab_libfunc (bswap_optab, DImode, "__gnu_bswapdi2"); 878 } 879 else 880 { 881 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2"); 882 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2"); 883 } 884 885 /* Use cabs for double complex abs, since systems generally have cabs. 886 Don't define any libcall for float complex, so that cabs will be used. */ 887 if (complex_double_type_node) 888 set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), 889 "cabs"); 890 891 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register"); 892 unwind_sjlj_unregister_libfunc 893 = init_one_libfunc ("_Unwind_SjLj_Unregister"); 894 895 /* Allow the target to add more libcalls or rename some, etc. */ 896 targetm.init_libfuncs (); 897 } 898 899 /* A helper function for init_sync_libfuncs. Using the basename BASE, 900 install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */ 901 902 static void 903 init_sync_libfuncs_1 (optab tab, const char *base, int max) 904 { 905 machine_mode mode; 906 char buf[64]; 907 size_t len = strlen (base); 908 int i; 909 910 gcc_assert (max <= 8); 911 gcc_assert (len + 3 < sizeof (buf)); 912 913 memcpy (buf, base, len); 914 buf[len] = '_'; 915 buf[len + 1] = '0'; 916 buf[len + 2] = '\0'; 917 918 mode = QImode; 919 for (i = 1; i <= max; i *= 2) 920 { 921 buf[len + 1] = '0' + i; 922 set_optab_libfunc (tab, mode, buf); 923 mode = GET_MODE_2XWIDER_MODE (mode); 924 } 925 } 926 927 void 928 init_sync_libfuncs (int max) 929 { 930 if (!flag_sync_libcalls) 931 return; 932 933 init_sync_libfuncs_1 (sync_compare_and_swap_optab, 934 "__sync_val_compare_and_swap", max); 935 init_sync_libfuncs_1 (sync_lock_test_and_set_optab, 936 "__sync_lock_test_and_set", max); 937 938 init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max); 939 init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max); 940 init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max); 941 init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max); 942 init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max); 943 init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max); 944 945 init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max); 946 init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max); 947 init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max); 948 init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max); 949 init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max); 950 init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max); 951 } 952 953 #include "gt-optabs-libfuncs.h" 954