optabs.c revision 119256
1/* Expand the basic unary and binary arithmetic operations, for GNU compiler. 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 2, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to the Free 19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2002111-1307, USA. */ 21 22 23#include "config.h" 24#include "system.h" 25#include "toplev.h" 26 27/* Include insn-config.h before expr.h so that HAVE_conditional_move 28 is properly defined. */ 29#include "insn-config.h" 30#include "rtl.h" 31#include "tree.h" 32#include "tm_p.h" 33#include "flags.h" 34#include "function.h" 35#include "except.h" 36#include "expr.h" 37#include "optabs.h" 38#include "libfuncs.h" 39#include "recog.h" 40#include "reload.h" 41#include "ggc.h" 42#include "real.h" 43#include "basic-block.h" 44 45/* Each optab contains info on how this target machine 46 can perform a particular operation 47 for all sizes and kinds of operands. 48 49 The operation to be performed is often specified 50 by passing one of these optabs as an argument. 51 52 See expr.h for documentation of these optabs. */ 53 54optab optab_table[OTI_MAX]; 55 56rtx libfunc_table[LTI_MAX]; 57 58/* Tables of patterns for extending one integer mode to another. */ 59enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2]; 60 61/* Tables of patterns for converting between fixed and floating point. */ 62enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 63enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 64enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 65 66/* Contains the optab used for each rtx code. */ 67optab code_to_optab[NUM_RTX_CODE + 1]; 68 69/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 70 gives the gen_function to make a branch to test that condition. */ 71 72rtxfun bcc_gen_fctn[NUM_RTX_CODE]; 73 74/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 75 gives the insn code to make a store-condition insn 76 to test that condition. */ 77 78enum insn_code setcc_gen_code[NUM_RTX_CODE]; 79 80#ifdef HAVE_conditional_move 81/* Indexed by the machine mode, gives the insn code to make a conditional 82 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and 83 setcc_gen_code to cut down on the number of named patterns. Consider a day 84 when a lot more rtx codes are conditional (eg: for the ARM). */ 85 86enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; 87#endif 88 89/* The insn generating function can not take an rtx_code argument. 90 TRAP_RTX is used as an rtx argument. Its code is replaced with 91 the code to be used in the trap insn and all other fields are ignored. */ 92static GTY(()) rtx trap_rtx; 93 94static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx)); 95static rtx widen_operand PARAMS ((rtx, enum machine_mode, 96 enum machine_mode, int, int)); 97static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx, 98 rtx, rtx, enum machine_mode, 99 int, enum optab_methods, 100 enum mode_class, optab)); 101static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx, 102 rtx, rtx, enum machine_mode, 103 int, enum optab_methods, 104 enum mode_class, optab)); 105static void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx, 106 enum machine_mode *, int *, 107 enum can_compare_purpose)); 108static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode, 109 int, int *)); 110static enum insn_code can_float_p PARAMS ((enum machine_mode, 111 enum machine_mode, 112 int)); 113static rtx ftruncify PARAMS ((rtx)); 114static optab new_optab PARAMS ((void)); 115static inline optab init_optab PARAMS ((enum rtx_code)); 116static inline optab init_optabv PARAMS ((enum rtx_code)); 117static void init_libfuncs PARAMS ((optab, int, int, const char *, int)); 118static void init_integral_libfuncs PARAMS ((optab, const char *, int)); 119static void init_floating_libfuncs PARAMS ((optab, const char *, int)); 120static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode, 121 enum rtx_code, int, rtx)); 122static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *, 123 enum machine_mode *, int *)); 124static rtx expand_vector_binop PARAMS ((enum machine_mode, optab, 125 rtx, rtx, rtx, int, 126 enum optab_methods)); 127static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx, 128 int)); 129 130#ifndef HAVE_conditional_trap 131#define HAVE_conditional_trap 0 132#define gen_conditional_trap(a,b) (abort (), NULL_RTX) 133#endif 134 135/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to 136 the result of operation CODE applied to OP0 (and OP1 if it is a binary 137 operation). 138 139 If the last insn does not set TARGET, don't do anything, but return 1. 140 141 If a previous insn sets TARGET and TARGET is one of OP0 or OP1, 142 don't add the REG_EQUAL note but return 0. Our caller can then try 143 again, ensuring that TARGET is not one of the operands. */ 144 145static int 146add_equal_note (insns, target, code, op0, op1) 147 rtx insns; 148 rtx target; 149 enum rtx_code code; 150 rtx op0, op1; 151{ 152 rtx last_insn, insn, set; 153 rtx note; 154 155 if (! insns 156 || ! INSN_P (insns) 157 || NEXT_INSN (insns) == NULL_RTX) 158 abort (); 159 160 if (GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2' 161 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<') 162 return 1; 163 164 if (GET_CODE (target) == ZERO_EXTRACT) 165 return 1; 166 167 for (last_insn = insns; 168 NEXT_INSN (last_insn) != NULL_RTX; 169 last_insn = NEXT_INSN (last_insn)) 170 ; 171 172 set = single_set (last_insn); 173 if (set == NULL_RTX) 174 return 1; 175 176 if (! rtx_equal_p (SET_DEST (set), target) 177 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the 178 SUBREG. */ 179 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART 180 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)), 181 target))) 182 return 1; 183 184 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET 185 besides the last insn. */ 186 if (reg_overlap_mentioned_p (target, op0) 187 || (op1 && reg_overlap_mentioned_p (target, op1))) 188 { 189 insn = PREV_INSN (last_insn); 190 while (insn != NULL_RTX) 191 { 192 if (reg_set_p (target, insn)) 193 return 0; 194 195 insn = PREV_INSN (insn); 196 } 197 } 198 199 if (GET_RTX_CLASS (code) == '1') 200 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0)); 201 else 202 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1)); 203 204 set_unique_reg_note (last_insn, REG_EQUAL, note); 205 206 return 1; 207} 208 209/* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP 210 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need 211 not actually do a sign-extend or zero-extend, but can leave the 212 higher-order bits of the result rtx undefined, for example, in the case 213 of logical operations, but not right shifts. */ 214 215static rtx 216widen_operand (op, mode, oldmode, unsignedp, no_extend) 217 rtx op; 218 enum machine_mode mode, oldmode; 219 int unsignedp; 220 int no_extend; 221{ 222 rtx result; 223 224 /* If we don't have to extend and this is a constant, return it. */ 225 if (no_extend && GET_MODE (op) == VOIDmode) 226 return op; 227 228 /* If we must extend do so. If OP is a SUBREG for a promoted object, also 229 extend since it will be more efficient to do so unless the signedness of 230 a promoted object differs from our extension. */ 231 if (! no_extend 232 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op) 233 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp)) 234 return convert_modes (mode, oldmode, op, unsignedp); 235 236 /* If MODE is no wider than a single word, we return a paradoxical 237 SUBREG. */ 238 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) 239 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); 240 241 /* Otherwise, get an object of MODE, clobber it, and set the low-order 242 part to OP. */ 243 244 result = gen_reg_rtx (mode); 245 emit_insn (gen_rtx_CLOBBER (VOIDmode, result)); 246 emit_move_insn (gen_lowpart (GET_MODE (op), result), op); 247 return result; 248} 249 250/* Generate code to perform a straightforward complex divide. */ 251 252static int 253expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode, 254 unsignedp, methods, class, binoptab) 255 rtx real0, real1, imag0, imag1, realr, imagr; 256 enum machine_mode submode; 257 int unsignedp; 258 enum optab_methods methods; 259 enum mode_class class; 260 optab binoptab; 261{ 262 rtx divisor; 263 rtx real_t, imag_t; 264 rtx temp1, temp2; 265 rtx res; 266 optab this_add_optab = add_optab; 267 optab this_sub_optab = sub_optab; 268 optab this_neg_optab = neg_optab; 269 optab this_mul_optab = smul_optab; 270 271 if (binoptab == sdivv_optab) 272 { 273 this_add_optab = addv_optab; 274 this_sub_optab = subv_optab; 275 this_neg_optab = negv_optab; 276 this_mul_optab = smulv_optab; 277 } 278 279 /* Don't fetch these from memory more than once. */ 280 real0 = force_reg (submode, real0); 281 real1 = force_reg (submode, real1); 282 283 if (imag0 != 0) 284 imag0 = force_reg (submode, imag0); 285 286 imag1 = force_reg (submode, imag1); 287 288 /* Divisor: c*c + d*d. */ 289 temp1 = expand_binop (submode, this_mul_optab, real1, real1, 290 NULL_RTX, unsignedp, methods); 291 292 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1, 293 NULL_RTX, unsignedp, methods); 294 295 if (temp1 == 0 || temp2 == 0) 296 return 0; 297 298 divisor = expand_binop (submode, this_add_optab, temp1, temp2, 299 NULL_RTX, unsignedp, methods); 300 if (divisor == 0) 301 return 0; 302 303 if (imag0 == 0) 304 { 305 /* Mathematically, ((a)(c-id))/divisor. */ 306 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */ 307 308 /* Calculate the dividend. */ 309 real_t = expand_binop (submode, this_mul_optab, real0, real1, 310 NULL_RTX, unsignedp, methods); 311 312 imag_t = expand_binop (submode, this_mul_optab, real0, imag1, 313 NULL_RTX, unsignedp, methods); 314 315 if (real_t == 0 || imag_t == 0) 316 return 0; 317 318 imag_t = expand_unop (submode, this_neg_optab, imag_t, 319 NULL_RTX, unsignedp); 320 } 321 else 322 { 323 /* Mathematically, ((a+ib)(c-id))/divider. */ 324 /* Calculate the dividend. */ 325 temp1 = expand_binop (submode, this_mul_optab, real0, real1, 326 NULL_RTX, unsignedp, methods); 327 328 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1, 329 NULL_RTX, unsignedp, methods); 330 331 if (temp1 == 0 || temp2 == 0) 332 return 0; 333 334 real_t = expand_binop (submode, this_add_optab, temp1, temp2, 335 NULL_RTX, unsignedp, methods); 336 337 temp1 = expand_binop (submode, this_mul_optab, imag0, real1, 338 NULL_RTX, unsignedp, methods); 339 340 temp2 = expand_binop (submode, this_mul_optab, real0, imag1, 341 NULL_RTX, unsignedp, methods); 342 343 if (temp1 == 0 || temp2 == 0) 344 return 0; 345 346 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2, 347 NULL_RTX, unsignedp, methods); 348 349 if (real_t == 0 || imag_t == 0) 350 return 0; 351 } 352 353 if (class == MODE_COMPLEX_FLOAT) 354 res = expand_binop (submode, binoptab, real_t, divisor, 355 realr, unsignedp, methods); 356 else 357 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 358 real_t, divisor, realr, unsignedp); 359 360 if (res == 0) 361 return 0; 362 363 if (res != realr) 364 emit_move_insn (realr, res); 365 366 if (class == MODE_COMPLEX_FLOAT) 367 res = expand_binop (submode, binoptab, imag_t, divisor, 368 imagr, unsignedp, methods); 369 else 370 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 371 imag_t, divisor, imagr, unsignedp); 372 373 if (res == 0) 374 return 0; 375 376 if (res != imagr) 377 emit_move_insn (imagr, res); 378 379 return 1; 380} 381 382/* Generate code to perform a wide-input-range-acceptable complex divide. */ 383 384static int 385expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode, 386 unsignedp, methods, class, binoptab) 387 rtx real0, real1, imag0, imag1, realr, imagr; 388 enum machine_mode submode; 389 int unsignedp; 390 enum optab_methods methods; 391 enum mode_class class; 392 optab binoptab; 393{ 394 rtx ratio, divisor; 395 rtx real_t, imag_t; 396 rtx temp1, temp2, lab1, lab2; 397 enum machine_mode mode; 398 rtx res; 399 optab this_add_optab = add_optab; 400 optab this_sub_optab = sub_optab; 401 optab this_neg_optab = neg_optab; 402 optab this_mul_optab = smul_optab; 403 404 if (binoptab == sdivv_optab) 405 { 406 this_add_optab = addv_optab; 407 this_sub_optab = subv_optab; 408 this_neg_optab = negv_optab; 409 this_mul_optab = smulv_optab; 410 } 411 412 /* Don't fetch these from memory more than once. */ 413 real0 = force_reg (submode, real0); 414 real1 = force_reg (submode, real1); 415 416 if (imag0 != 0) 417 imag0 = force_reg (submode, imag0); 418 419 imag1 = force_reg (submode, imag1); 420 421 /* XXX What's an "unsigned" complex number? */ 422 if (unsignedp) 423 { 424 temp1 = real1; 425 temp2 = imag1; 426 } 427 else 428 { 429 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1); 430 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1); 431 } 432 433 if (temp1 == 0 || temp2 == 0) 434 return 0; 435 436 mode = GET_MODE (temp1); 437 lab1 = gen_label_rtx (); 438 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX, 439 mode, unsignedp, lab1); 440 441 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */ 442 443 if (class == MODE_COMPLEX_FLOAT) 444 ratio = expand_binop (submode, binoptab, imag1, real1, 445 NULL_RTX, unsignedp, methods); 446 else 447 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode, 448 imag1, real1, NULL_RTX, unsignedp); 449 450 if (ratio == 0) 451 return 0; 452 453 /* Calculate divisor. */ 454 455 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio, 456 NULL_RTX, unsignedp, methods); 457 458 if (temp1 == 0) 459 return 0; 460 461 divisor = expand_binop (submode, this_add_optab, temp1, real1, 462 NULL_RTX, unsignedp, methods); 463 464 if (divisor == 0) 465 return 0; 466 467 /* Calculate dividend. */ 468 469 if (imag0 == 0) 470 { 471 real_t = real0; 472 473 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */ 474 475 imag_t = expand_binop (submode, this_mul_optab, real0, ratio, 476 NULL_RTX, unsignedp, methods); 477 478 if (imag_t == 0) 479 return 0; 480 481 imag_t = expand_unop (submode, this_neg_optab, imag_t, 482 NULL_RTX, unsignedp); 483 484 if (real_t == 0 || imag_t == 0) 485 return 0; 486 } 487 else 488 { 489 /* Compute (a+ib)/(c+id) as 490 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */ 491 492 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio, 493 NULL_RTX, unsignedp, methods); 494 495 if (temp1 == 0) 496 return 0; 497 498 real_t = expand_binop (submode, this_add_optab, temp1, real0, 499 NULL_RTX, unsignedp, methods); 500 501 temp1 = expand_binop (submode, this_mul_optab, real0, ratio, 502 NULL_RTX, unsignedp, methods); 503 504 if (temp1 == 0) 505 return 0; 506 507 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1, 508 NULL_RTX, unsignedp, methods); 509 510 if (real_t == 0 || imag_t == 0) 511 return 0; 512 } 513 514 if (class == MODE_COMPLEX_FLOAT) 515 res = expand_binop (submode, binoptab, real_t, divisor, 516 realr, unsignedp, methods); 517 else 518 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 519 real_t, divisor, realr, unsignedp); 520 521 if (res == 0) 522 return 0; 523 524 if (res != realr) 525 emit_move_insn (realr, res); 526 527 if (class == MODE_COMPLEX_FLOAT) 528 res = expand_binop (submode, binoptab, imag_t, divisor, 529 imagr, unsignedp, methods); 530 else 531 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 532 imag_t, divisor, imagr, unsignedp); 533 534 if (res == 0) 535 return 0; 536 537 if (res != imagr) 538 emit_move_insn (imagr, res); 539 540 lab2 = gen_label_rtx (); 541 emit_jump_insn (gen_jump (lab2)); 542 emit_barrier (); 543 544 emit_label (lab1); 545 546 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */ 547 548 if (class == MODE_COMPLEX_FLOAT) 549 ratio = expand_binop (submode, binoptab, real1, imag1, 550 NULL_RTX, unsignedp, methods); 551 else 552 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode, 553 real1, imag1, NULL_RTX, unsignedp); 554 555 if (ratio == 0) 556 return 0; 557 558 /* Calculate divisor. */ 559 560 temp1 = expand_binop (submode, this_mul_optab, real1, ratio, 561 NULL_RTX, unsignedp, methods); 562 563 if (temp1 == 0) 564 return 0; 565 566 divisor = expand_binop (submode, this_add_optab, temp1, imag1, 567 NULL_RTX, unsignedp, methods); 568 569 if (divisor == 0) 570 return 0; 571 572 /* Calculate dividend. */ 573 574 if (imag0 == 0) 575 { 576 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */ 577 578 real_t = expand_binop (submode, this_mul_optab, real0, ratio, 579 NULL_RTX, unsignedp, methods); 580 581 imag_t = expand_unop (submode, this_neg_optab, real0, 582 NULL_RTX, unsignedp); 583 584 if (real_t == 0 || imag_t == 0) 585 return 0; 586 } 587 else 588 { 589 /* Compute (a+ib)/(c+id) as 590 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */ 591 592 temp1 = expand_binop (submode, this_mul_optab, real0, ratio, 593 NULL_RTX, unsignedp, methods); 594 595 if (temp1 == 0) 596 return 0; 597 598 real_t = expand_binop (submode, this_add_optab, temp1, imag0, 599 NULL_RTX, unsignedp, methods); 600 601 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio, 602 NULL_RTX, unsignedp, methods); 603 604 if (temp1 == 0) 605 return 0; 606 607 imag_t = expand_binop (submode, this_sub_optab, temp1, real0, 608 NULL_RTX, unsignedp, methods); 609 610 if (real_t == 0 || imag_t == 0) 611 return 0; 612 } 613 614 if (class == MODE_COMPLEX_FLOAT) 615 res = expand_binop (submode, binoptab, real_t, divisor, 616 realr, unsignedp, methods); 617 else 618 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 619 real_t, divisor, realr, unsignedp); 620 621 if (res == 0) 622 return 0; 623 624 if (res != realr) 625 emit_move_insn (realr, res); 626 627 if (class == MODE_COMPLEX_FLOAT) 628 res = expand_binop (submode, binoptab, imag_t, divisor, 629 imagr, unsignedp, methods); 630 else 631 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 632 imag_t, divisor, imagr, unsignedp); 633 634 if (res == 0) 635 return 0; 636 637 if (res != imagr) 638 emit_move_insn (imagr, res); 639 640 emit_label (lab2); 641 642 return 1; 643} 644 645/* Wrapper around expand_binop which takes an rtx code to specify 646 the operation to perform, not an optab pointer. All other 647 arguments are the same. */ 648rtx 649expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods) 650 enum machine_mode mode; 651 enum rtx_code code; 652 rtx op0, op1; 653 rtx target; 654 int unsignedp; 655 enum optab_methods methods; 656{ 657 optab binop = code_to_optab[(int) code]; 658 if (binop == 0) 659 abort (); 660 661 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods); 662} 663 664/* Generate code to perform an operation specified by BINOPTAB 665 on operands OP0 and OP1, with result having machine-mode MODE. 666 667 UNSIGNEDP is for the case where we have to widen the operands 668 to perform the operation. It says to use zero-extension. 669 670 If TARGET is nonzero, the value 671 is generated there, if it is convenient to do so. 672 In all cases an rtx is returned for the locus of the value; 673 this may or may not be TARGET. */ 674 675rtx 676expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) 677 enum machine_mode mode; 678 optab binoptab; 679 rtx op0, op1; 680 rtx target; 681 int unsignedp; 682 enum optab_methods methods; 683{ 684 enum optab_methods next_methods 685 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN 686 ? OPTAB_WIDEN : methods); 687 enum mode_class class; 688 enum machine_mode wider_mode; 689 rtx temp; 690 int commutative_op = 0; 691 int shift_op = (binoptab->code == ASHIFT 692 || binoptab->code == ASHIFTRT 693 || binoptab->code == LSHIFTRT 694 || binoptab->code == ROTATE 695 || binoptab->code == ROTATERT); 696 rtx entry_last = get_last_insn (); 697 rtx last; 698 699 class = GET_MODE_CLASS (mode); 700 701 op0 = protect_from_queue (op0, 0); 702 op1 = protect_from_queue (op1, 0); 703 if (target) 704 target = protect_from_queue (target, 1); 705 706 if (flag_force_mem) 707 { 708 op0 = force_not_mem (op0); 709 op1 = force_not_mem (op1); 710 } 711 712 /* If subtracting an integer constant, convert this into an addition of 713 the negated constant. */ 714 715 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT) 716 { 717 op1 = negate_rtx (mode, op1); 718 binoptab = add_optab; 719 } 720 721 /* If we are inside an appropriately-short loop and one operand is an 722 expensive constant, force it into a register. */ 723 if (CONSTANT_P (op0) && preserve_subexpressions_p () 724 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1)) 725 op0 = force_reg (mode, op0); 726 727 if (CONSTANT_P (op1) && preserve_subexpressions_p () 728 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1)) 729 op1 = force_reg (mode, op1); 730 731 /* Record where to delete back to if we backtrack. */ 732 last = get_last_insn (); 733 734 /* If operation is commutative, 735 try to make the first operand a register. 736 Even better, try to make it the same as the target. 737 Also try to make the last operand a constant. */ 738 if (GET_RTX_CLASS (binoptab->code) == 'c' 739 || binoptab == smul_widen_optab 740 || binoptab == umul_widen_optab 741 || binoptab == smul_highpart_optab 742 || binoptab == umul_highpart_optab) 743 { 744 commutative_op = 1; 745 746 if (((target == 0 || GET_CODE (target) == REG) 747 ? ((GET_CODE (op1) == REG 748 && GET_CODE (op0) != REG) 749 || target == op1) 750 : rtx_equal_p (op1, target)) 751 || GET_CODE (op0) == CONST_INT) 752 { 753 temp = op1; 754 op1 = op0; 755 op0 = temp; 756 } 757 } 758 759 /* If we can do it with a three-operand insn, do so. */ 760 761 if (methods != OPTAB_MUST_WIDEN 762 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 763 { 764 int icode = (int) binoptab->handlers[(int) mode].insn_code; 765 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 766 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 767 rtx pat; 768 rtx xop0 = op0, xop1 = op1; 769 770 if (target) 771 temp = target; 772 else 773 temp = gen_reg_rtx (mode); 774 775 /* If it is a commutative operator and the modes would match 776 if we would swap the operands, we can save the conversions. */ 777 if (commutative_op) 778 { 779 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1 780 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0) 781 { 782 rtx tmp; 783 784 tmp = op0; op0 = op1; op1 = tmp; 785 tmp = xop0; xop0 = xop1; xop1 = tmp; 786 } 787 } 788 789 /* In case the insn wants input operands in modes different from 790 those of the actual operands, convert the operands. It would 791 seem that we don't need to convert CONST_INTs, but we do, so 792 that they're properly zero-extended, sign-extended or truncated 793 for their mode. */ 794 795 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode) 796 xop0 = convert_modes (mode0, 797 GET_MODE (op0) != VOIDmode 798 ? GET_MODE (op0) 799 : mode, 800 xop0, unsignedp); 801 802 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode) 803 xop1 = convert_modes (mode1, 804 GET_MODE (op1) != VOIDmode 805 ? GET_MODE (op1) 806 : mode, 807 xop1, unsignedp); 808 809 /* Now, if insn's predicates don't allow our operands, put them into 810 pseudo regs. */ 811 812 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0) 813 && mode0 != VOIDmode) 814 xop0 = copy_to_mode_reg (mode0, xop0); 815 816 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1) 817 && mode1 != VOIDmode) 818 xop1 = copy_to_mode_reg (mode1, xop1); 819 820 if (! (*insn_data[icode].operand[0].predicate) (temp, mode)) 821 temp = gen_reg_rtx (mode); 822 823 pat = GEN_FCN (icode) (temp, xop0, xop1); 824 if (pat) 825 { 826 /* If PAT is composed of more than one insn, try to add an appropriate 827 REG_EQUAL note to it. If we can't because TEMP conflicts with an 828 operand, call ourselves again, this time without a target. */ 829 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX 830 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1)) 831 { 832 delete_insns_since (last); 833 return expand_binop (mode, binoptab, op0, op1, NULL_RTX, 834 unsignedp, methods); 835 } 836 837 emit_insn (pat); 838 return temp; 839 } 840 else 841 delete_insns_since (last); 842 } 843 844 /* If this is a multiply, see if we can do a widening operation that 845 takes operands of this mode and makes a wider mode. */ 846 847 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode 848 && (((unsignedp ? umul_widen_optab : smul_widen_optab) 849 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code) 850 != CODE_FOR_nothing)) 851 { 852 temp = expand_binop (GET_MODE_WIDER_MODE (mode), 853 unsignedp ? umul_widen_optab : smul_widen_optab, 854 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT); 855 856 if (temp != 0) 857 { 858 if (GET_MODE_CLASS (mode) == MODE_INT) 859 return gen_lowpart (mode, temp); 860 else 861 return convert_to_mode (mode, temp, unsignedp); 862 } 863 } 864 865 /* Look for a wider mode of the same class for which we think we 866 can open-code the operation. Check for a widening multiply at the 867 wider mode as well. */ 868 869 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) 870 && methods != OPTAB_DIRECT && methods != OPTAB_LIB) 871 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 872 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 873 { 874 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing 875 || (binoptab == smul_optab 876 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode 877 && (((unsignedp ? umul_widen_optab : smul_widen_optab) 878 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code) 879 != CODE_FOR_nothing))) 880 { 881 rtx xop0 = op0, xop1 = op1; 882 int no_extend = 0; 883 884 /* For certain integer operations, we need not actually extend 885 the narrow operands, as long as we will truncate 886 the results to the same narrowness. */ 887 888 if ((binoptab == ior_optab || binoptab == and_optab 889 || binoptab == xor_optab 890 || binoptab == add_optab || binoptab == sub_optab 891 || binoptab == smul_optab || binoptab == ashl_optab) 892 && class == MODE_INT) 893 no_extend = 1; 894 895 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend); 896 897 /* The second operand of a shift must always be extended. */ 898 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp, 899 no_extend && binoptab != ashl_optab); 900 901 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX, 902 unsignedp, OPTAB_DIRECT); 903 if (temp) 904 { 905 if (class != MODE_INT) 906 { 907 if (target == 0) 908 target = gen_reg_rtx (mode); 909 convert_move (target, temp, 0); 910 return target; 911 } 912 else 913 return gen_lowpart (mode, temp); 914 } 915 else 916 delete_insns_since (last); 917 } 918 } 919 920 /* These can be done a word at a time. */ 921 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab) 922 && class == MODE_INT 923 && GET_MODE_SIZE (mode) > UNITS_PER_WORD 924 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing) 925 { 926 int i; 927 rtx insns; 928 rtx equiv_value; 929 930 /* If TARGET is the same as one of the operands, the REG_EQUAL note 931 won't be accurate, so use a new target. */ 932 if (target == 0 || target == op0 || target == op1) 933 target = gen_reg_rtx (mode); 934 935 start_sequence (); 936 937 /* Do the actual arithmetic. */ 938 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++) 939 { 940 rtx target_piece = operand_subword (target, i, 1, mode); 941 rtx x = expand_binop (word_mode, binoptab, 942 operand_subword_force (op0, i, mode), 943 operand_subword_force (op1, i, mode), 944 target_piece, unsignedp, next_methods); 945 946 if (x == 0) 947 break; 948 949 if (target_piece != x) 950 emit_move_insn (target_piece, x); 951 } 952 953 insns = get_insns (); 954 end_sequence (); 955 956 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD) 957 { 958 if (binoptab->code != UNKNOWN) 959 equiv_value 960 = gen_rtx_fmt_ee (binoptab->code, mode, 961 copy_rtx (op0), copy_rtx (op1)); 962 else 963 equiv_value = 0; 964 965 emit_no_conflict_block (insns, target, op0, op1, equiv_value); 966 return target; 967 } 968 } 969 970 /* Synthesize double word shifts from single word shifts. */ 971 if ((binoptab == lshr_optab || binoptab == ashl_optab 972 || binoptab == ashr_optab) 973 && class == MODE_INT 974 && GET_CODE (op1) == CONST_INT 975 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD 976 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing 977 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing 978 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing) 979 { 980 rtx insns, inter, equiv_value; 981 rtx into_target, outof_target; 982 rtx into_input, outof_input; 983 int shift_count, left_shift, outof_word; 984 985 /* If TARGET is the same as one of the operands, the REG_EQUAL note 986 won't be accurate, so use a new target. */ 987 if (target == 0 || target == op0 || target == op1) 988 target = gen_reg_rtx (mode); 989 990 start_sequence (); 991 992 shift_count = INTVAL (op1); 993 994 /* OUTOF_* is the word we are shifting bits away from, and 995 INTO_* is the word that we are shifting bits towards, thus 996 they differ depending on the direction of the shift and 997 WORDS_BIG_ENDIAN. */ 998 999 left_shift = binoptab == ashl_optab; 1000 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN; 1001 1002 outof_target = operand_subword (target, outof_word, 1, mode); 1003 into_target = operand_subword (target, 1 - outof_word, 1, mode); 1004 1005 outof_input = operand_subword_force (op0, outof_word, mode); 1006 into_input = operand_subword_force (op0, 1 - outof_word, mode); 1007 1008 if (shift_count >= BITS_PER_WORD) 1009 { 1010 inter = expand_binop (word_mode, binoptab, 1011 outof_input, 1012 GEN_INT (shift_count - BITS_PER_WORD), 1013 into_target, unsignedp, next_methods); 1014 1015 if (inter != 0 && inter != into_target) 1016 emit_move_insn (into_target, inter); 1017 1018 /* For a signed right shift, we must fill the word we are shifting 1019 out of with copies of the sign bit. Otherwise it is zeroed. */ 1020 if (inter != 0 && binoptab != ashr_optab) 1021 inter = CONST0_RTX (word_mode); 1022 else if (inter != 0) 1023 inter = expand_binop (word_mode, binoptab, 1024 outof_input, 1025 GEN_INT (BITS_PER_WORD - 1), 1026 outof_target, unsignedp, next_methods); 1027 1028 if (inter != 0 && inter != outof_target) 1029 emit_move_insn (outof_target, inter); 1030 } 1031 else 1032 { 1033 rtx carries; 1034 optab reverse_unsigned_shift, unsigned_shift; 1035 1036 /* For a shift of less then BITS_PER_WORD, to compute the carry, 1037 we must do a logical shift in the opposite direction of the 1038 desired shift. */ 1039 1040 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab); 1041 1042 /* For a shift of less than BITS_PER_WORD, to compute the word 1043 shifted towards, we need to unsigned shift the orig value of 1044 that word. */ 1045 1046 unsigned_shift = (left_shift ? ashl_optab : lshr_optab); 1047 1048 carries = expand_binop (word_mode, reverse_unsigned_shift, 1049 outof_input, 1050 GEN_INT (BITS_PER_WORD - shift_count), 1051 0, unsignedp, next_methods); 1052 1053 if (carries == 0) 1054 inter = 0; 1055 else 1056 inter = expand_binop (word_mode, unsigned_shift, into_input, 1057 op1, 0, unsignedp, next_methods); 1058 1059 if (inter != 0) 1060 inter = expand_binop (word_mode, ior_optab, carries, inter, 1061 into_target, unsignedp, next_methods); 1062 1063 if (inter != 0 && inter != into_target) 1064 emit_move_insn (into_target, inter); 1065 1066 if (inter != 0) 1067 inter = expand_binop (word_mode, binoptab, outof_input, 1068 op1, outof_target, unsignedp, next_methods); 1069 1070 if (inter != 0 && inter != outof_target) 1071 emit_move_insn (outof_target, inter); 1072 } 1073 1074 insns = get_insns (); 1075 end_sequence (); 1076 1077 if (inter != 0) 1078 { 1079 if (binoptab->code != UNKNOWN) 1080 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1); 1081 else 1082 equiv_value = 0; 1083 1084 emit_no_conflict_block (insns, target, op0, op1, equiv_value); 1085 return target; 1086 } 1087 } 1088 1089 /* Synthesize double word rotates from single word shifts. */ 1090 if ((binoptab == rotl_optab || binoptab == rotr_optab) 1091 && class == MODE_INT 1092 && GET_CODE (op1) == CONST_INT 1093 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD 1094 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing 1095 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing) 1096 { 1097 rtx insns, equiv_value; 1098 rtx into_target, outof_target; 1099 rtx into_input, outof_input; 1100 rtx inter; 1101 int shift_count, left_shift, outof_word; 1102 1103 /* If TARGET is the same as one of the operands, the REG_EQUAL note 1104 won't be accurate, so use a new target. */ 1105 if (target == 0 || target == op0 || target == op1) 1106 target = gen_reg_rtx (mode); 1107 1108 start_sequence (); 1109 1110 shift_count = INTVAL (op1); 1111 1112 /* OUTOF_* is the word we are shifting bits away from, and 1113 INTO_* is the word that we are shifting bits towards, thus 1114 they differ depending on the direction of the shift and 1115 WORDS_BIG_ENDIAN. */ 1116 1117 left_shift = (binoptab == rotl_optab); 1118 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN; 1119 1120 outof_target = operand_subword (target, outof_word, 1, mode); 1121 into_target = operand_subword (target, 1 - outof_word, 1, mode); 1122 1123 outof_input = operand_subword_force (op0, outof_word, mode); 1124 into_input = operand_subword_force (op0, 1 - outof_word, mode); 1125 1126 if (shift_count == BITS_PER_WORD) 1127 { 1128 /* This is just a word swap. */ 1129 emit_move_insn (outof_target, into_input); 1130 emit_move_insn (into_target, outof_input); 1131 inter = const0_rtx; 1132 } 1133 else 1134 { 1135 rtx into_temp1, into_temp2, outof_temp1, outof_temp2; 1136 rtx first_shift_count, second_shift_count; 1137 optab reverse_unsigned_shift, unsigned_shift; 1138 1139 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD) 1140 ? lshr_optab : ashl_optab); 1141 1142 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD) 1143 ? ashl_optab : lshr_optab); 1144 1145 if (shift_count > BITS_PER_WORD) 1146 { 1147 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD); 1148 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count); 1149 } 1150 else 1151 { 1152 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count); 1153 second_shift_count = GEN_INT (shift_count); 1154 } 1155 1156 into_temp1 = expand_binop (word_mode, unsigned_shift, 1157 outof_input, first_shift_count, 1158 NULL_RTX, unsignedp, next_methods); 1159 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift, 1160 into_input, second_shift_count, 1161 NULL_RTX, unsignedp, next_methods); 1162 1163 if (into_temp1 != 0 && into_temp2 != 0) 1164 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2, 1165 into_target, unsignedp, next_methods); 1166 else 1167 inter = 0; 1168 1169 if (inter != 0 && inter != into_target) 1170 emit_move_insn (into_target, inter); 1171 1172 outof_temp1 = expand_binop (word_mode, unsigned_shift, 1173 into_input, first_shift_count, 1174 NULL_RTX, unsignedp, next_methods); 1175 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift, 1176 outof_input, second_shift_count, 1177 NULL_RTX, unsignedp, next_methods); 1178 1179 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0) 1180 inter = expand_binop (word_mode, ior_optab, 1181 outof_temp1, outof_temp2, 1182 outof_target, unsignedp, next_methods); 1183 1184 if (inter != 0 && inter != outof_target) 1185 emit_move_insn (outof_target, inter); 1186 } 1187 1188 insns = get_insns (); 1189 end_sequence (); 1190 1191 if (inter != 0) 1192 { 1193 if (binoptab->code != UNKNOWN) 1194 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1); 1195 else 1196 equiv_value = 0; 1197 1198 /* We can't make this a no conflict block if this is a word swap, 1199 because the word swap case fails if the input and output values 1200 are in the same register. */ 1201 if (shift_count != BITS_PER_WORD) 1202 emit_no_conflict_block (insns, target, op0, op1, equiv_value); 1203 else 1204 emit_insn (insns); 1205 1206 1207 return target; 1208 } 1209 } 1210 1211 /* These can be done a word at a time by propagating carries. */ 1212 if ((binoptab == add_optab || binoptab == sub_optab) 1213 && class == MODE_INT 1214 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD 1215 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing) 1216 { 1217 unsigned int i; 1218 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab; 1219 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD; 1220 rtx carry_in = NULL_RTX, carry_out = NULL_RTX; 1221 rtx xop0, xop1, xtarget; 1222 1223 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG 1224 value is one of those, use it. Otherwise, use 1 since it is the 1225 one easiest to get. */ 1226#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1 1227 int normalizep = STORE_FLAG_VALUE; 1228#else 1229 int normalizep = 1; 1230#endif 1231 1232 /* Prepare the operands. */ 1233 xop0 = force_reg (mode, op0); 1234 xop1 = force_reg (mode, op1); 1235 1236 xtarget = gen_reg_rtx (mode); 1237 1238 if (target == 0 || GET_CODE (target) != REG) 1239 target = xtarget; 1240 1241 /* Indicate for flow that the entire target reg is being set. */ 1242 if (GET_CODE (target) == REG) 1243 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget)); 1244 1245 /* Do the actual arithmetic. */ 1246 for (i = 0; i < nwords; i++) 1247 { 1248 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i); 1249 rtx target_piece = operand_subword (xtarget, index, 1, mode); 1250 rtx op0_piece = operand_subword_force (xop0, index, mode); 1251 rtx op1_piece = operand_subword_force (xop1, index, mode); 1252 rtx x; 1253 1254 /* Main add/subtract of the input operands. */ 1255 x = expand_binop (word_mode, binoptab, 1256 op0_piece, op1_piece, 1257 target_piece, unsignedp, next_methods); 1258 if (x == 0) 1259 break; 1260 1261 if (i + 1 < nwords) 1262 { 1263 /* Store carry from main add/subtract. */ 1264 carry_out = gen_reg_rtx (word_mode); 1265 carry_out = emit_store_flag_force (carry_out, 1266 (binoptab == add_optab 1267 ? LT : GT), 1268 x, op0_piece, 1269 word_mode, 1, normalizep); 1270 } 1271 1272 if (i > 0) 1273 { 1274 rtx newx; 1275 1276 /* Add/subtract previous carry to main result. */ 1277 newx = expand_binop (word_mode, 1278 normalizep == 1 ? binoptab : otheroptab, 1279 x, carry_in, 1280 NULL_RTX, 1, next_methods); 1281 1282 if (i + 1 < nwords) 1283 { 1284 /* Get out carry from adding/subtracting carry in. */ 1285 rtx carry_tmp = gen_reg_rtx (word_mode); 1286 carry_tmp = emit_store_flag_force (carry_tmp, 1287 (binoptab == add_optab 1288 ? LT : GT), 1289 newx, x, 1290 word_mode, 1, normalizep); 1291 1292 /* Logical-ior the two poss. carry together. */ 1293 carry_out = expand_binop (word_mode, ior_optab, 1294 carry_out, carry_tmp, 1295 carry_out, 0, next_methods); 1296 if (carry_out == 0) 1297 break; 1298 } 1299 emit_move_insn (target_piece, newx); 1300 } 1301 1302 carry_in = carry_out; 1303 } 1304 1305 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD) 1306 { 1307 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 1308 { 1309 rtx temp = emit_move_insn (target, xtarget); 1310 1311 set_unique_reg_note (temp, 1312 REG_EQUAL, 1313 gen_rtx_fmt_ee (binoptab->code, mode, 1314 copy_rtx (xop0), 1315 copy_rtx (xop1))); 1316 } 1317 else 1318 target = xtarget; 1319 1320 return target; 1321 } 1322 1323 else 1324 delete_insns_since (last); 1325 } 1326 1327 /* If we want to multiply two two-word values and have normal and widening 1328 multiplies of single-word values, we can do this with three smaller 1329 multiplications. Note that we do not make a REG_NO_CONFLICT block here 1330 because we are not operating on one word at a time. 1331 1332 The multiplication proceeds as follows: 1333 _______________________ 1334 [__op0_high_|__op0_low__] 1335 _______________________ 1336 * [__op1_high_|__op1_low__] 1337 _______________________________________________ 1338 _______________________ 1339 (1) [__op0_low__*__op1_low__] 1340 _______________________ 1341 (2a) [__op0_low__*__op1_high_] 1342 _______________________ 1343 (2b) [__op0_high_*__op1_low__] 1344 _______________________ 1345 (3) [__op0_high_*__op1_high_] 1346 1347 1348 This gives a 4-word result. Since we are only interested in the 1349 lower 2 words, partial result (3) and the upper words of (2a) and 1350 (2b) don't need to be calculated. Hence (2a) and (2b) can be 1351 calculated using non-widening multiplication. 1352 1353 (1), however, needs to be calculated with an unsigned widening 1354 multiplication. If this operation is not directly supported we 1355 try using a signed widening multiplication and adjust the result. 1356 This adjustment works as follows: 1357 1358 If both operands are positive then no adjustment is needed. 1359 1360 If the operands have different signs, for example op0_low < 0 and 1361 op1_low >= 0, the instruction treats the most significant bit of 1362 op0_low as a sign bit instead of a bit with significance 1363 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low 1364 with 2**BITS_PER_WORD - op0_low, and two's complements the 1365 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to 1366 the result. 1367 1368 Similarly, if both operands are negative, we need to add 1369 (op0_low + op1_low) * 2**BITS_PER_WORD. 1370 1371 We use a trick to adjust quickly. We logically shift op0_low right 1372 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to 1373 op0_high (op1_high) before it is used to calculate 2b (2a). If no 1374 logical shift exists, we do an arithmetic right shift and subtract 1375 the 0 or -1. */ 1376 1377 if (binoptab == smul_optab 1378 && class == MODE_INT 1379 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD 1380 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing 1381 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing 1382 && ((umul_widen_optab->handlers[(int) mode].insn_code 1383 != CODE_FOR_nothing) 1384 || (smul_widen_optab->handlers[(int) mode].insn_code 1385 != CODE_FOR_nothing))) 1386 { 1387 int low = (WORDS_BIG_ENDIAN ? 1 : 0); 1388 int high = (WORDS_BIG_ENDIAN ? 0 : 1); 1389 rtx op0_high = operand_subword_force (op0, high, mode); 1390 rtx op0_low = operand_subword_force (op0, low, mode); 1391 rtx op1_high = operand_subword_force (op1, high, mode); 1392 rtx op1_low = operand_subword_force (op1, low, mode); 1393 rtx product = 0; 1394 rtx op0_xhigh = NULL_RTX; 1395 rtx op1_xhigh = NULL_RTX; 1396 1397 /* If the target is the same as one of the inputs, don't use it. This 1398 prevents problems with the REG_EQUAL note. */ 1399 if (target == op0 || target == op1 1400 || (target != 0 && GET_CODE (target) != REG)) 1401 target = 0; 1402 1403 /* Multiply the two lower words to get a double-word product. 1404 If unsigned widening multiplication is available, use that; 1405 otherwise use the signed form and compensate. */ 1406 1407 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 1408 { 1409 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low, 1410 target, 1, OPTAB_DIRECT); 1411 1412 /* If we didn't succeed, delete everything we did so far. */ 1413 if (product == 0) 1414 delete_insns_since (last); 1415 else 1416 op0_xhigh = op0_high, op1_xhigh = op1_high; 1417 } 1418 1419 if (product == 0 1420 && smul_widen_optab->handlers[(int) mode].insn_code 1421 != CODE_FOR_nothing) 1422 { 1423 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1); 1424 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low, 1425 target, 1, OPTAB_DIRECT); 1426 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1, 1427 NULL_RTX, 1, next_methods); 1428 if (op0_xhigh) 1429 op0_xhigh = expand_binop (word_mode, add_optab, op0_high, 1430 op0_xhigh, op0_xhigh, 0, next_methods); 1431 else 1432 { 1433 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1, 1434 NULL_RTX, 0, next_methods); 1435 if (op0_xhigh) 1436 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high, 1437 op0_xhigh, op0_xhigh, 0, 1438 next_methods); 1439 } 1440 1441 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1, 1442 NULL_RTX, 1, next_methods); 1443 if (op1_xhigh) 1444 op1_xhigh = expand_binop (word_mode, add_optab, op1_high, 1445 op1_xhigh, op1_xhigh, 0, next_methods); 1446 else 1447 { 1448 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1, 1449 NULL_RTX, 0, next_methods); 1450 if (op1_xhigh) 1451 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high, 1452 op1_xhigh, op1_xhigh, 0, 1453 next_methods); 1454 } 1455 } 1456 1457 /* If we have been able to directly compute the product of the 1458 low-order words of the operands and perform any required adjustments 1459 of the operands, we proceed by trying two more multiplications 1460 and then computing the appropriate sum. 1461 1462 We have checked above that the required addition is provided. 1463 Full-word addition will normally always succeed, especially if 1464 it is provided at all, so we don't worry about its failure. The 1465 multiplication may well fail, however, so we do handle that. */ 1466 1467 if (product && op0_xhigh && op1_xhigh) 1468 { 1469 rtx product_high = operand_subword (product, high, 1, mode); 1470 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh, 1471 NULL_RTX, 0, OPTAB_DIRECT); 1472 1473 if (!REG_P (product_high)) 1474 product_high = force_reg (word_mode, product_high); 1475 1476 if (temp != 0) 1477 temp = expand_binop (word_mode, add_optab, temp, product_high, 1478 product_high, 0, next_methods); 1479 1480 if (temp != 0 && temp != product_high) 1481 emit_move_insn (product_high, temp); 1482 1483 if (temp != 0) 1484 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 1485 NULL_RTX, 0, OPTAB_DIRECT); 1486 1487 if (temp != 0) 1488 temp = expand_binop (word_mode, add_optab, temp, 1489 product_high, product_high, 1490 0, next_methods); 1491 1492 if (temp != 0 && temp != product_high) 1493 emit_move_insn (product_high, temp); 1494 1495 emit_move_insn (operand_subword (product, high, 1, mode), product_high); 1496 1497 if (temp != 0) 1498 { 1499 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 1500 { 1501 temp = emit_move_insn (product, product); 1502 set_unique_reg_note (temp, 1503 REG_EQUAL, 1504 gen_rtx_fmt_ee (MULT, mode, 1505 copy_rtx (op0), 1506 copy_rtx (op1))); 1507 } 1508 1509 return product; 1510 } 1511 } 1512 1513 /* If we get here, we couldn't do it for some reason even though we 1514 originally thought we could. Delete anything we've emitted in 1515 trying to do it. */ 1516 1517 delete_insns_since (last); 1518 } 1519 1520 /* Open-code the vector operations if we have no hardware support 1521 for them. */ 1522 if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT) 1523 return expand_vector_binop (mode, binoptab, op0, op1, target, 1524 unsignedp, methods); 1525 1526 /* We need to open-code the complex type operations: '+, -, * and /' */ 1527 1528 /* At this point we allow operations between two similar complex 1529 numbers, and also if one of the operands is not a complex number 1530 but rather of MODE_FLOAT or MODE_INT. However, the caller 1531 must make sure that the MODE of the non-complex operand matches 1532 the SUBMODE of the complex operand. */ 1533 1534 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT) 1535 { 1536 rtx real0 = 0, imag0 = 0; 1537 rtx real1 = 0, imag1 = 0; 1538 rtx realr, imagr, res; 1539 rtx seq; 1540 rtx equiv_value; 1541 int ok = 0; 1542 1543 /* Find the correct mode for the real and imaginary parts */ 1544 enum machine_mode submode = GET_MODE_INNER(mode); 1545 1546 if (submode == BLKmode) 1547 abort (); 1548 1549 if (! target) 1550 target = gen_reg_rtx (mode); 1551 1552 start_sequence (); 1553 1554 realr = gen_realpart (submode, target); 1555 imagr = gen_imagpart (submode, target); 1556 1557 if (GET_MODE (op0) == mode) 1558 { 1559 real0 = gen_realpart (submode, op0); 1560 imag0 = gen_imagpart (submode, op0); 1561 } 1562 else 1563 real0 = op0; 1564 1565 if (GET_MODE (op1) == mode) 1566 { 1567 real1 = gen_realpart (submode, op1); 1568 imag1 = gen_imagpart (submode, op1); 1569 } 1570 else 1571 real1 = op1; 1572 1573 if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0)) 1574 abort (); 1575 1576 switch (binoptab->code) 1577 { 1578 case PLUS: 1579 /* (a+ib) + (c+id) = (a+c) + i(b+d) */ 1580 case MINUS: 1581 /* (a+ib) - (c+id) = (a-c) + i(b-d) */ 1582 res = expand_binop (submode, binoptab, real0, real1, 1583 realr, unsignedp, methods); 1584 1585 if (res == 0) 1586 break; 1587 else if (res != realr) 1588 emit_move_insn (realr, res); 1589 1590 if (imag0 != 0 && imag1 != 0) 1591 res = expand_binop (submode, binoptab, imag0, imag1, 1592 imagr, unsignedp, methods); 1593 else if (imag0 != 0) 1594 res = imag0; 1595 else if (binoptab->code == MINUS) 1596 res = expand_unop (submode, 1597 binoptab == subv_optab ? negv_optab : neg_optab, 1598 imag1, imagr, unsignedp); 1599 else 1600 res = imag1; 1601 1602 if (res == 0) 1603 break; 1604 else if (res != imagr) 1605 emit_move_insn (imagr, res); 1606 1607 ok = 1; 1608 break; 1609 1610 case MULT: 1611 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */ 1612 1613 if (imag0 != 0 && imag1 != 0) 1614 { 1615 rtx temp1, temp2; 1616 1617 /* Don't fetch these from memory more than once. */ 1618 real0 = force_reg (submode, real0); 1619 real1 = force_reg (submode, real1); 1620 imag0 = force_reg (submode, imag0); 1621 imag1 = force_reg (submode, imag1); 1622 1623 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX, 1624 unsignedp, methods); 1625 1626 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX, 1627 unsignedp, methods); 1628 1629 if (temp1 == 0 || temp2 == 0) 1630 break; 1631 1632 res = (expand_binop 1633 (submode, 1634 binoptab == smulv_optab ? subv_optab : sub_optab, 1635 temp1, temp2, realr, unsignedp, methods)); 1636 1637 if (res == 0) 1638 break; 1639 else if (res != realr) 1640 emit_move_insn (realr, res); 1641 1642 temp1 = expand_binop (submode, binoptab, real0, imag1, 1643 NULL_RTX, unsignedp, methods); 1644 1645 temp2 = expand_binop (submode, binoptab, real1, imag0, 1646 NULL_RTX, unsignedp, methods); 1647 1648 if (temp1 == 0 || temp2 == 0) 1649 break; 1650 1651 res = (expand_binop 1652 (submode, 1653 binoptab == smulv_optab ? addv_optab : add_optab, 1654 temp1, temp2, imagr, unsignedp, methods)); 1655 1656 if (res == 0) 1657 break; 1658 else if (res != imagr) 1659 emit_move_insn (imagr, res); 1660 1661 ok = 1; 1662 } 1663 else 1664 { 1665 /* Don't fetch these from memory more than once. */ 1666 real0 = force_reg (submode, real0); 1667 real1 = force_reg (submode, real1); 1668 1669 res = expand_binop (submode, binoptab, real0, real1, 1670 realr, unsignedp, methods); 1671 if (res == 0) 1672 break; 1673 else if (res != realr) 1674 emit_move_insn (realr, res); 1675 1676 if (imag0 != 0) 1677 res = expand_binop (submode, binoptab, 1678 real1, imag0, imagr, unsignedp, methods); 1679 else 1680 res = expand_binop (submode, binoptab, 1681 real0, imag1, imagr, unsignedp, methods); 1682 1683 if (res == 0) 1684 break; 1685 else if (res != imagr) 1686 emit_move_insn (imagr, res); 1687 1688 ok = 1; 1689 } 1690 break; 1691 1692 case DIV: 1693 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */ 1694 1695 if (imag1 == 0) 1696 { 1697 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */ 1698 1699 /* Don't fetch these from memory more than once. */ 1700 real1 = force_reg (submode, real1); 1701 1702 /* Simply divide the real and imaginary parts by `c' */ 1703 if (class == MODE_COMPLEX_FLOAT) 1704 res = expand_binop (submode, binoptab, real0, real1, 1705 realr, unsignedp, methods); 1706 else 1707 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 1708 real0, real1, realr, unsignedp); 1709 1710 if (res == 0) 1711 break; 1712 else if (res != realr) 1713 emit_move_insn (realr, res); 1714 1715 if (class == MODE_COMPLEX_FLOAT) 1716 res = expand_binop (submode, binoptab, imag0, real1, 1717 imagr, unsignedp, methods); 1718 else 1719 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 1720 imag0, real1, imagr, unsignedp); 1721 1722 if (res == 0) 1723 break; 1724 else if (res != imagr) 1725 emit_move_insn (imagr, res); 1726 1727 ok = 1; 1728 } 1729 else 1730 { 1731 switch (flag_complex_divide_method) 1732 { 1733 case 0: 1734 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1, 1735 realr, imagr, submode, 1736 unsignedp, methods, 1737 class, binoptab); 1738 break; 1739 1740 case 1: 1741 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1, 1742 realr, imagr, submode, 1743 unsignedp, methods, 1744 class, binoptab); 1745 break; 1746 1747 default: 1748 abort (); 1749 } 1750 } 1751 break; 1752 1753 default: 1754 abort (); 1755 } 1756 1757 seq = get_insns (); 1758 end_sequence (); 1759 1760 if (ok) 1761 { 1762 if (binoptab->code != UNKNOWN) 1763 equiv_value 1764 = gen_rtx_fmt_ee (binoptab->code, mode, 1765 copy_rtx (op0), copy_rtx (op1)); 1766 else 1767 equiv_value = 0; 1768 1769 emit_no_conflict_block (seq, target, op0, op1, equiv_value); 1770 1771 return target; 1772 } 1773 } 1774 1775 /* It can't be open-coded in this mode. 1776 Use a library call if one is available and caller says that's ok. */ 1777 1778 if (binoptab->handlers[(int) mode].libfunc 1779 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN)) 1780 { 1781 rtx insns; 1782 rtx op1x = op1; 1783 enum machine_mode op1_mode = mode; 1784 rtx value; 1785 1786 start_sequence (); 1787 1788 if (shift_op) 1789 { 1790 op1_mode = word_mode; 1791 /* Specify unsigned here, 1792 since negative shift counts are meaningless. */ 1793 op1x = convert_to_mode (word_mode, op1, 1); 1794 } 1795 1796 if (GET_MODE (op0) != VOIDmode 1797 && GET_MODE (op0) != mode) 1798 op0 = convert_to_mode (mode, op0, unsignedp); 1799 1800 /* Pass 1 for NO_QUEUE so we don't lose any increments 1801 if the libcall is cse'd or moved. */ 1802 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc, 1803 NULL_RTX, LCT_CONST, mode, 2, 1804 op0, mode, op1x, op1_mode); 1805 1806 insns = get_insns (); 1807 end_sequence (); 1808 1809 target = gen_reg_rtx (mode); 1810 emit_libcall_block (insns, target, value, 1811 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1)); 1812 1813 return target; 1814 } 1815 1816 delete_insns_since (last); 1817 1818 /* It can't be done in this mode. Can we do it in a wider mode? */ 1819 1820 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN 1821 || methods == OPTAB_MUST_WIDEN)) 1822 { 1823 /* Caller says, don't even try. */ 1824 delete_insns_since (entry_last); 1825 return 0; 1826 } 1827 1828 /* Compute the value of METHODS to pass to recursive calls. 1829 Don't allow widening to be tried recursively. */ 1830 1831 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT); 1832 1833 /* Look for a wider mode of the same class for which it appears we can do 1834 the operation. */ 1835 1836 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) 1837 { 1838 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 1839 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 1840 { 1841 if ((binoptab->handlers[(int) wider_mode].insn_code 1842 != CODE_FOR_nothing) 1843 || (methods == OPTAB_LIB 1844 && binoptab->handlers[(int) wider_mode].libfunc)) 1845 { 1846 rtx xop0 = op0, xop1 = op1; 1847 int no_extend = 0; 1848 1849 /* For certain integer operations, we need not actually extend 1850 the narrow operands, as long as we will truncate 1851 the results to the same narrowness. */ 1852 1853 if ((binoptab == ior_optab || binoptab == and_optab 1854 || binoptab == xor_optab 1855 || binoptab == add_optab || binoptab == sub_optab 1856 || binoptab == smul_optab || binoptab == ashl_optab) 1857 && class == MODE_INT) 1858 no_extend = 1; 1859 1860 xop0 = widen_operand (xop0, wider_mode, mode, 1861 unsignedp, no_extend); 1862 1863 /* The second operand of a shift must always be extended. */ 1864 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp, 1865 no_extend && binoptab != ashl_optab); 1866 1867 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX, 1868 unsignedp, methods); 1869 if (temp) 1870 { 1871 if (class != MODE_INT) 1872 { 1873 if (target == 0) 1874 target = gen_reg_rtx (mode); 1875 convert_move (target, temp, 0); 1876 return target; 1877 } 1878 else 1879 return gen_lowpart (mode, temp); 1880 } 1881 else 1882 delete_insns_since (last); 1883 } 1884 } 1885 } 1886 1887 delete_insns_since (entry_last); 1888 return 0; 1889} 1890 1891/* Like expand_binop, but for open-coding vectors binops. */ 1892 1893static rtx 1894expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods) 1895 enum machine_mode mode; 1896 optab binoptab; 1897 rtx op0, op1; 1898 rtx target; 1899 int unsignedp; 1900 enum optab_methods methods; 1901{ 1902 enum machine_mode submode, tmode; 1903 int size, elts, subsize, subbitsize, i; 1904 rtx t, a, b, res, seq; 1905 enum mode_class class; 1906 1907 class = GET_MODE_CLASS (mode); 1908 1909 size = GET_MODE_SIZE (mode); 1910 submode = GET_MODE_INNER (mode); 1911 1912 /* Search for the widest vector mode with the same inner mode that is 1913 still narrower than MODE and that allows to open-code this operator. 1914 Note, if we find such a mode and the handler later decides it can't 1915 do the expansion, we'll be called recursively with the narrower mode. */ 1916 for (tmode = GET_CLASS_NARROWEST_MODE (class); 1917 GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode); 1918 tmode = GET_MODE_WIDER_MODE (tmode)) 1919 { 1920 if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode) 1921 && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) 1922 submode = tmode; 1923 } 1924 1925 switch (binoptab->code) 1926 { 1927 case AND: 1928 case IOR: 1929 case XOR: 1930 tmode = int_mode_for_mode (mode); 1931 if (tmode != BLKmode) 1932 submode = tmode; 1933 case PLUS: 1934 case MINUS: 1935 case MULT: 1936 case DIV: 1937 subsize = GET_MODE_SIZE (submode); 1938 subbitsize = GET_MODE_BITSIZE (submode); 1939 elts = size / subsize; 1940 1941 /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode, 1942 but that we operate on more than one element at a time. */ 1943 if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT) 1944 return 0; 1945 1946 start_sequence (); 1947 1948 /* Errors can leave us with a const0_rtx as operand. */ 1949 if (GET_MODE (op0) != mode) 1950 op0 = copy_to_mode_reg (mode, op0); 1951 if (GET_MODE (op1) != mode) 1952 op1 = copy_to_mode_reg (mode, op1); 1953 1954 if (!target) 1955 target = gen_reg_rtx (mode); 1956 1957 for (i = 0; i < elts; ++i) 1958 { 1959 /* If this is part of a register, and not the first item in the 1960 word, we can't store using a SUBREG - that would clobber 1961 previous results. 1962 And storing with a SUBREG is only possible for the least 1963 significant part, hence we can't do it for big endian 1964 (unless we want to permute the evaluation order. */ 1965 if (GET_CODE (target) == REG 1966 && (BYTES_BIG_ENDIAN 1967 ? subsize < UNITS_PER_WORD 1968 : ((i * subsize) % UNITS_PER_WORD) != 0)) 1969 t = NULL_RTX; 1970 else 1971 t = simplify_gen_subreg (submode, target, mode, i * subsize); 1972 if (CONSTANT_P (op0)) 1973 a = simplify_gen_subreg (submode, op0, mode, i * subsize); 1974 else 1975 a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp, 1976 NULL_RTX, submode, submode, size); 1977 if (CONSTANT_P (op1)) 1978 b = simplify_gen_subreg (submode, op1, mode, i * subsize); 1979 else 1980 b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp, 1981 NULL_RTX, submode, submode, size); 1982 1983 if (binoptab->code == DIV) 1984 { 1985 if (class == MODE_VECTOR_FLOAT) 1986 res = expand_binop (submode, binoptab, a, b, t, 1987 unsignedp, methods); 1988 else 1989 res = expand_divmod (0, TRUNC_DIV_EXPR, submode, 1990 a, b, t, unsignedp); 1991 } 1992 else 1993 res = expand_binop (submode, binoptab, a, b, t, 1994 unsignedp, methods); 1995 1996 if (res == 0) 1997 break; 1998 1999 if (t) 2000 emit_move_insn (t, res); 2001 else 2002 store_bit_field (target, subbitsize, i * subbitsize, submode, res, 2003 size); 2004 } 2005 break; 2006 2007 default: 2008 abort (); 2009 } 2010 2011 seq = get_insns (); 2012 end_sequence (); 2013 emit_insn (seq); 2014 2015 return target; 2016} 2017 2018/* Like expand_unop but for open-coding vector unops. */ 2019 2020static rtx 2021expand_vector_unop (mode, unoptab, op0, target, unsignedp) 2022 enum machine_mode mode; 2023 optab unoptab; 2024 rtx op0; 2025 rtx target; 2026 int unsignedp; 2027{ 2028 enum machine_mode submode, tmode; 2029 int size, elts, subsize, subbitsize, i; 2030 rtx t, a, res, seq; 2031 2032 size = GET_MODE_SIZE (mode); 2033 submode = GET_MODE_INNER (mode); 2034 2035 /* Search for the widest vector mode with the same inner mode that is 2036 still narrower than MODE and that allows to open-code this operator. 2037 Note, if we find such a mode and the handler later decides it can't 2038 do the expansion, we'll be called recursively with the narrower mode. */ 2039 for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode)); 2040 GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode); 2041 tmode = GET_MODE_WIDER_MODE (tmode)) 2042 { 2043 if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode) 2044 && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) 2045 submode = tmode; 2046 } 2047 /* If there is no negate operation, try doing a subtract from zero. */ 2048 if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT 2049 /* Avoid infinite recursion when an 2050 error has left us with the wrong mode. */ 2051 && GET_MODE (op0) == mode) 2052 { 2053 rtx temp; 2054 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0, 2055 target, unsignedp, OPTAB_DIRECT); 2056 if (temp) 2057 return temp; 2058 } 2059 2060 if (unoptab == one_cmpl_optab) 2061 { 2062 tmode = int_mode_for_mode (mode); 2063 if (tmode != BLKmode) 2064 submode = tmode; 2065 } 2066 2067 subsize = GET_MODE_SIZE (submode); 2068 subbitsize = GET_MODE_BITSIZE (submode); 2069 elts = size / subsize; 2070 2071 /* Errors can leave us with a const0_rtx as operand. */ 2072 if (GET_MODE (op0) != mode) 2073 op0 = copy_to_mode_reg (mode, op0); 2074 2075 if (!target) 2076 target = gen_reg_rtx (mode); 2077 2078 start_sequence (); 2079 2080 for (i = 0; i < elts; ++i) 2081 { 2082 /* If this is part of a register, and not the first item in the 2083 word, we can't store using a SUBREG - that would clobber 2084 previous results. 2085 And storing with a SUBREG is only possible for the least 2086 significant part, hence we can't do it for big endian 2087 (unless we want to permute the evaluation order. */ 2088 if (GET_CODE (target) == REG 2089 && (BYTES_BIG_ENDIAN 2090 ? subsize < UNITS_PER_WORD 2091 : ((i * subsize) % UNITS_PER_WORD) != 0)) 2092 t = NULL_RTX; 2093 else 2094 t = simplify_gen_subreg (submode, target, mode, i * subsize); 2095 if (CONSTANT_P (op0)) 2096 a = simplify_gen_subreg (submode, op0, mode, i * subsize); 2097 else 2098 a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp, 2099 t, submode, submode, size); 2100 2101 res = expand_unop (submode, unoptab, a, t, unsignedp); 2102 2103 if (t) 2104 emit_move_insn (t, res); 2105 else 2106 store_bit_field (target, subbitsize, i * subbitsize, submode, res, 2107 size); 2108 } 2109 2110 seq = get_insns (); 2111 end_sequence (); 2112 emit_insn (seq); 2113 2114 return target; 2115} 2116 2117/* Expand a binary operator which has both signed and unsigned forms. 2118 UOPTAB is the optab for unsigned operations, and SOPTAB is for 2119 signed operations. 2120 2121 If we widen unsigned operands, we may use a signed wider operation instead 2122 of an unsigned wider operation, since the result would be the same. */ 2123 2124rtx 2125sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods) 2126 enum machine_mode mode; 2127 optab uoptab, soptab; 2128 rtx op0, op1, target; 2129 int unsignedp; 2130 enum optab_methods methods; 2131{ 2132 rtx temp; 2133 optab direct_optab = unsignedp ? uoptab : soptab; 2134 struct optab wide_soptab; 2135 2136 /* Do it without widening, if possible. */ 2137 temp = expand_binop (mode, direct_optab, op0, op1, target, 2138 unsignedp, OPTAB_DIRECT); 2139 if (temp || methods == OPTAB_DIRECT) 2140 return temp; 2141 2142 /* Try widening to a signed int. Make a fake signed optab that 2143 hides any signed insn for direct use. */ 2144 wide_soptab = *soptab; 2145 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing; 2146 wide_soptab.handlers[(int) mode].libfunc = 0; 2147 2148 temp = expand_binop (mode, &wide_soptab, op0, op1, target, 2149 unsignedp, OPTAB_WIDEN); 2150 2151 /* For unsigned operands, try widening to an unsigned int. */ 2152 if (temp == 0 && unsignedp) 2153 temp = expand_binop (mode, uoptab, op0, op1, target, 2154 unsignedp, OPTAB_WIDEN); 2155 if (temp || methods == OPTAB_WIDEN) 2156 return temp; 2157 2158 /* Use the right width lib call if that exists. */ 2159 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB); 2160 if (temp || methods == OPTAB_LIB) 2161 return temp; 2162 2163 /* Must widen and use a lib call, use either signed or unsigned. */ 2164 temp = expand_binop (mode, &wide_soptab, op0, op1, target, 2165 unsignedp, methods); 2166 if (temp != 0) 2167 return temp; 2168 if (unsignedp) 2169 return expand_binop (mode, uoptab, op0, op1, target, 2170 unsignedp, methods); 2171 return 0; 2172} 2173 2174/* Generate code to perform an operation specified by BINOPTAB 2175 on operands OP0 and OP1, with two results to TARG1 and TARG2. 2176 We assume that the order of the operands for the instruction 2177 is TARG0, OP0, OP1, TARG1, which would fit a pattern like 2178 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))]. 2179 2180 Either TARG0 or TARG1 may be zero, but what that means is that 2181 the result is not actually wanted. We will generate it into 2182 a dummy pseudo-reg and discard it. They may not both be zero. 2183 2184 Returns 1 if this operation can be performed; 0 if not. */ 2185 2186int 2187expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp) 2188 optab binoptab; 2189 rtx op0, op1; 2190 rtx targ0, targ1; 2191 int unsignedp; 2192{ 2193 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1); 2194 enum mode_class class; 2195 enum machine_mode wider_mode; 2196 rtx entry_last = get_last_insn (); 2197 rtx last; 2198 2199 class = GET_MODE_CLASS (mode); 2200 2201 op0 = protect_from_queue (op0, 0); 2202 op1 = protect_from_queue (op1, 0); 2203 2204 if (flag_force_mem) 2205 { 2206 op0 = force_not_mem (op0); 2207 op1 = force_not_mem (op1); 2208 } 2209 2210 /* If we are inside an appropriately-short loop and one operand is an 2211 expensive constant, force it into a register. */ 2212 if (CONSTANT_P (op0) && preserve_subexpressions_p () 2213 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1)) 2214 op0 = force_reg (mode, op0); 2215 2216 if (CONSTANT_P (op1) && preserve_subexpressions_p () 2217 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1)) 2218 op1 = force_reg (mode, op1); 2219 2220 if (targ0) 2221 targ0 = protect_from_queue (targ0, 1); 2222 else 2223 targ0 = gen_reg_rtx (mode); 2224 if (targ1) 2225 targ1 = protect_from_queue (targ1, 1); 2226 else 2227 targ1 = gen_reg_rtx (mode); 2228 2229 /* Record where to go back to if we fail. */ 2230 last = get_last_insn (); 2231 2232 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2233 { 2234 int icode = (int) binoptab->handlers[(int) mode].insn_code; 2235 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 2236 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 2237 rtx pat; 2238 rtx xop0 = op0, xop1 = op1; 2239 2240 /* In case the insn wants input operands in modes different from 2241 those of the actual operands, convert the operands. It would 2242 seem that we don't need to convert CONST_INTs, but we do, so 2243 that they're properly zero-extended, sign-extended or truncated 2244 for their mode. */ 2245 2246 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode) 2247 xop0 = convert_modes (mode0, 2248 GET_MODE (op0) != VOIDmode 2249 ? GET_MODE (op0) 2250 : mode, 2251 xop0, unsignedp); 2252 2253 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode) 2254 xop1 = convert_modes (mode1, 2255 GET_MODE (op1) != VOIDmode 2256 ? GET_MODE (op1) 2257 : mode, 2258 xop1, unsignedp); 2259 2260 /* Now, if insn doesn't accept these operands, put them into pseudos. */ 2261 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)) 2262 xop0 = copy_to_mode_reg (mode0, xop0); 2263 2264 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)) 2265 xop1 = copy_to_mode_reg (mode1, xop1); 2266 2267 /* We could handle this, but we should always be called with a pseudo 2268 for our targets and all insns should take them as outputs. */ 2269 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode) 2270 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode)) 2271 abort (); 2272 2273 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1); 2274 if (pat) 2275 { 2276 emit_insn (pat); 2277 return 1; 2278 } 2279 else 2280 delete_insns_since (last); 2281 } 2282 2283 /* It can't be done in this mode. Can we do it in a wider mode? */ 2284 2285 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) 2286 { 2287 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 2288 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 2289 { 2290 if (binoptab->handlers[(int) wider_mode].insn_code 2291 != CODE_FOR_nothing) 2292 { 2293 rtx t0 = gen_reg_rtx (wider_mode); 2294 rtx t1 = gen_reg_rtx (wider_mode); 2295 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp); 2296 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp); 2297 2298 if (expand_twoval_binop (binoptab, cop0, cop1, 2299 t0, t1, unsignedp)) 2300 { 2301 convert_move (targ0, t0, unsignedp); 2302 convert_move (targ1, t1, unsignedp); 2303 return 1; 2304 } 2305 else 2306 delete_insns_since (last); 2307 } 2308 } 2309 } 2310 2311 delete_insns_since (entry_last); 2312 return 0; 2313} 2314 2315/* Wrapper around expand_unop which takes an rtx code to specify 2316 the operation to perform, not an optab pointer. All other 2317 arguments are the same. */ 2318rtx 2319expand_simple_unop (mode, code, op0, target, unsignedp) 2320 enum machine_mode mode; 2321 enum rtx_code code; 2322 rtx op0; 2323 rtx target; 2324 int unsignedp; 2325{ 2326 optab unop = code_to_optab[(int) code]; 2327 if (unop == 0) 2328 abort (); 2329 2330 return expand_unop (mode, unop, op0, target, unsignedp); 2331} 2332 2333/* Generate code to perform an operation specified by UNOPTAB 2334 on operand OP0, with result having machine-mode MODE. 2335 2336 UNSIGNEDP is for the case where we have to widen the operands 2337 to perform the operation. It says to use zero-extension. 2338 2339 If TARGET is nonzero, the value 2340 is generated there, if it is convenient to do so. 2341 In all cases an rtx is returned for the locus of the value; 2342 this may or may not be TARGET. */ 2343 2344rtx 2345expand_unop (mode, unoptab, op0, target, unsignedp) 2346 enum machine_mode mode; 2347 optab unoptab; 2348 rtx op0; 2349 rtx target; 2350 int unsignedp; 2351{ 2352 enum mode_class class; 2353 enum machine_mode wider_mode; 2354 rtx temp; 2355 rtx last = get_last_insn (); 2356 rtx pat; 2357 2358 class = GET_MODE_CLASS (mode); 2359 2360 op0 = protect_from_queue (op0, 0); 2361 2362 if (flag_force_mem) 2363 { 2364 op0 = force_not_mem (op0); 2365 } 2366 2367 if (target) 2368 target = protect_from_queue (target, 1); 2369 2370 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2371 { 2372 int icode = (int) unoptab->handlers[(int) mode].insn_code; 2373 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 2374 rtx xop0 = op0; 2375 2376 if (target) 2377 temp = target; 2378 else 2379 temp = gen_reg_rtx (mode); 2380 2381 if (GET_MODE (xop0) != VOIDmode 2382 && GET_MODE (xop0) != mode0) 2383 xop0 = convert_to_mode (mode0, xop0, unsignedp); 2384 2385 /* Now, if insn doesn't accept our operand, put it into a pseudo. */ 2386 2387 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)) 2388 xop0 = copy_to_mode_reg (mode0, xop0); 2389 2390 if (! (*insn_data[icode].operand[0].predicate) (temp, mode)) 2391 temp = gen_reg_rtx (mode); 2392 2393 pat = GEN_FCN (icode) (temp, xop0); 2394 if (pat) 2395 { 2396 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX 2397 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX)) 2398 { 2399 delete_insns_since (last); 2400 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp); 2401 } 2402 2403 emit_insn (pat); 2404 2405 return temp; 2406 } 2407 else 2408 delete_insns_since (last); 2409 } 2410 2411 /* It can't be done in this mode. Can we open-code it in a wider mode? */ 2412 2413 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) 2414 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 2415 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 2416 { 2417 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing) 2418 { 2419 rtx xop0 = op0; 2420 2421 /* For certain operations, we need not actually extend 2422 the narrow operand, as long as we will truncate the 2423 results to the same narrowness. */ 2424 2425 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, 2426 (unoptab == neg_optab 2427 || unoptab == one_cmpl_optab) 2428 && class == MODE_INT); 2429 2430 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX, 2431 unsignedp); 2432 2433 if (temp) 2434 { 2435 if (class != MODE_INT) 2436 { 2437 if (target == 0) 2438 target = gen_reg_rtx (mode); 2439 convert_move (target, temp, 0); 2440 return target; 2441 } 2442 else 2443 return gen_lowpart (mode, temp); 2444 } 2445 else 2446 delete_insns_since (last); 2447 } 2448 } 2449 2450 /* These can be done a word at a time. */ 2451 if (unoptab == one_cmpl_optab 2452 && class == MODE_INT 2453 && GET_MODE_SIZE (mode) > UNITS_PER_WORD 2454 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing) 2455 { 2456 int i; 2457 rtx insns; 2458 2459 if (target == 0 || target == op0) 2460 target = gen_reg_rtx (mode); 2461 2462 start_sequence (); 2463 2464 /* Do the actual arithmetic. */ 2465 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++) 2466 { 2467 rtx target_piece = operand_subword (target, i, 1, mode); 2468 rtx x = expand_unop (word_mode, unoptab, 2469 operand_subword_force (op0, i, mode), 2470 target_piece, unsignedp); 2471 2472 if (target_piece != x) 2473 emit_move_insn (target_piece, x); 2474 } 2475 2476 insns = get_insns (); 2477 end_sequence (); 2478 2479 emit_no_conflict_block (insns, target, op0, NULL_RTX, 2480 gen_rtx_fmt_e (unoptab->code, mode, 2481 copy_rtx (op0))); 2482 return target; 2483 } 2484 2485 /* Open-code the complex negation operation. */ 2486 else if (unoptab->code == NEG 2487 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)) 2488 { 2489 rtx target_piece; 2490 rtx x; 2491 rtx seq; 2492 2493 /* Find the correct mode for the real and imaginary parts */ 2494 enum machine_mode submode = GET_MODE_INNER (mode); 2495 2496 if (submode == BLKmode) 2497 abort (); 2498 2499 if (target == 0) 2500 target = gen_reg_rtx (mode); 2501 2502 start_sequence (); 2503 2504 target_piece = gen_imagpart (submode, target); 2505 x = expand_unop (submode, unoptab, 2506 gen_imagpart (submode, op0), 2507 target_piece, unsignedp); 2508 if (target_piece != x) 2509 emit_move_insn (target_piece, x); 2510 2511 target_piece = gen_realpart (submode, target); 2512 x = expand_unop (submode, unoptab, 2513 gen_realpart (submode, op0), 2514 target_piece, unsignedp); 2515 if (target_piece != x) 2516 emit_move_insn (target_piece, x); 2517 2518 seq = get_insns (); 2519 end_sequence (); 2520 2521 emit_no_conflict_block (seq, target, op0, 0, 2522 gen_rtx_fmt_e (unoptab->code, mode, 2523 copy_rtx (op0))); 2524 return target; 2525 } 2526 2527 /* Now try a library call in this mode. */ 2528 if (unoptab->handlers[(int) mode].libfunc) 2529 { 2530 rtx insns; 2531 rtx value; 2532 2533 start_sequence (); 2534 2535 /* Pass 1 for NO_QUEUE so we don't lose any increments 2536 if the libcall is cse'd or moved. */ 2537 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc, 2538 NULL_RTX, LCT_CONST, mode, 1, op0, mode); 2539 insns = get_insns (); 2540 end_sequence (); 2541 2542 target = gen_reg_rtx (mode); 2543 emit_libcall_block (insns, target, value, 2544 gen_rtx_fmt_e (unoptab->code, mode, op0)); 2545 2546 return target; 2547 } 2548 2549 if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT) 2550 return expand_vector_unop (mode, unoptab, op0, target, unsignedp); 2551 2552 /* It can't be done in this mode. Can we do it in a wider mode? */ 2553 2554 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) 2555 { 2556 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 2557 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 2558 { 2559 if ((unoptab->handlers[(int) wider_mode].insn_code 2560 != CODE_FOR_nothing) 2561 || unoptab->handlers[(int) wider_mode].libfunc) 2562 { 2563 rtx xop0 = op0; 2564 2565 /* For certain operations, we need not actually extend 2566 the narrow operand, as long as we will truncate the 2567 results to the same narrowness. */ 2568 2569 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, 2570 (unoptab == neg_optab 2571 || unoptab == one_cmpl_optab) 2572 && class == MODE_INT); 2573 2574 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX, 2575 unsignedp); 2576 2577 if (temp) 2578 { 2579 if (class != MODE_INT) 2580 { 2581 if (target == 0) 2582 target = gen_reg_rtx (mode); 2583 convert_move (target, temp, 0); 2584 return target; 2585 } 2586 else 2587 return gen_lowpart (mode, temp); 2588 } 2589 else 2590 delete_insns_since (last); 2591 } 2592 } 2593 } 2594 2595 /* If there is no negate operation, try doing a subtract from zero. 2596 The US Software GOFAST library needs this. */ 2597 if (unoptab->code == NEG) 2598 { 2599 rtx temp; 2600 temp = expand_binop (mode, 2601 unoptab == negv_optab ? subv_optab : sub_optab, 2602 CONST0_RTX (mode), op0, 2603 target, unsignedp, OPTAB_LIB_WIDEN); 2604 if (temp) 2605 return temp; 2606 } 2607 2608 return 0; 2609} 2610 2611/* Emit code to compute the absolute value of OP0, with result to 2612 TARGET if convenient. (TARGET may be 0.) The return value says 2613 where the result actually is to be found. 2614 2615 MODE is the mode of the operand; the mode of the result is 2616 different but can be deduced from MODE. 2617 2618 */ 2619 2620rtx 2621expand_abs (mode, op0, target, result_unsignedp, safe) 2622 enum machine_mode mode; 2623 rtx op0; 2624 rtx target; 2625 int result_unsignedp; 2626 int safe; 2627{ 2628 rtx temp, op1; 2629 2630 if (! flag_trapv) 2631 result_unsignedp = 1; 2632 2633 /* First try to do it with a special abs instruction. */ 2634 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab, 2635 op0, target, 0); 2636 if (temp != 0) 2637 return temp; 2638 2639 /* If we have a MAX insn, we can do this as MAX (x, -x). */ 2640 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2641 { 2642 rtx last = get_last_insn (); 2643 2644 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0); 2645 if (temp != 0) 2646 temp = expand_binop (mode, smax_optab, op0, temp, target, 0, 2647 OPTAB_WIDEN); 2648 2649 if (temp != 0) 2650 return temp; 2651 2652 delete_insns_since (last); 2653 } 2654 2655 /* If this machine has expensive jumps, we can do integer absolute 2656 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)), 2657 where W is the width of MODE. */ 2658 2659 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2) 2660 { 2661 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0, 2662 size_int (GET_MODE_BITSIZE (mode) - 1), 2663 NULL_RTX, 0); 2664 2665 temp = expand_binop (mode, xor_optab, extended, op0, target, 0, 2666 OPTAB_LIB_WIDEN); 2667 if (temp != 0) 2668 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab, 2669 temp, extended, target, 0, OPTAB_LIB_WIDEN); 2670 2671 if (temp != 0) 2672 return temp; 2673 } 2674 2675 /* If that does not win, use conditional jump and negate. */ 2676 2677 /* It is safe to use the target if it is the same 2678 as the source if this is also a pseudo register */ 2679 if (op0 == target && GET_CODE (op0) == REG 2680 && REGNO (op0) >= FIRST_PSEUDO_REGISTER) 2681 safe = 1; 2682 2683 op1 = gen_label_rtx (); 2684 if (target == 0 || ! safe 2685 || GET_MODE (target) != mode 2686 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)) 2687 || (GET_CODE (target) == REG 2688 && REGNO (target) < FIRST_PSEUDO_REGISTER)) 2689 target = gen_reg_rtx (mode); 2690 2691 emit_move_insn (target, op0); 2692 NO_DEFER_POP; 2693 2694 /* If this mode is an integer too wide to compare properly, 2695 compare word by word. Rely on CSE to optimize constant cases. */ 2696 if (GET_MODE_CLASS (mode) == MODE_INT 2697 && ! can_compare_p (GE, mode, ccp_jump)) 2698 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 2699 NULL_RTX, op1); 2700 else 2701 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode, 2702 NULL_RTX, NULL_RTX, op1); 2703 2704 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab, 2705 target, target, 0); 2706 if (op0 != target) 2707 emit_move_insn (target, op0); 2708 emit_label (op1); 2709 OK_DEFER_POP; 2710 return target; 2711} 2712 2713/* Emit code to compute the absolute value of OP0, with result to 2714 TARGET if convenient. (TARGET may be 0.) The return value says 2715 where the result actually is to be found. 2716 2717 MODE is the mode of the operand; the mode of the result is 2718 different but can be deduced from MODE. 2719 2720 UNSIGNEDP is relevant for complex integer modes. */ 2721 2722rtx 2723expand_complex_abs (mode, op0, target, unsignedp) 2724 enum machine_mode mode; 2725 rtx op0; 2726 rtx target; 2727 int unsignedp; 2728{ 2729 enum mode_class class = GET_MODE_CLASS (mode); 2730 enum machine_mode wider_mode; 2731 rtx temp; 2732 rtx entry_last = get_last_insn (); 2733 rtx last; 2734 rtx pat; 2735 optab this_abs_optab; 2736 2737 /* Find the correct mode for the real and imaginary parts. */ 2738 enum machine_mode submode = GET_MODE_INNER (mode); 2739 2740 if (submode == BLKmode) 2741 abort (); 2742 2743 op0 = protect_from_queue (op0, 0); 2744 2745 if (flag_force_mem) 2746 { 2747 op0 = force_not_mem (op0); 2748 } 2749 2750 last = get_last_insn (); 2751 2752 if (target) 2753 target = protect_from_queue (target, 1); 2754 2755 this_abs_optab = ! unsignedp && flag_trapv 2756 && (GET_MODE_CLASS(mode) == MODE_INT) 2757 ? absv_optab : abs_optab; 2758 2759 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2760 { 2761 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code; 2762 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 2763 rtx xop0 = op0; 2764 2765 if (target) 2766 temp = target; 2767 else 2768 temp = gen_reg_rtx (submode); 2769 2770 if (GET_MODE (xop0) != VOIDmode 2771 && GET_MODE (xop0) != mode0) 2772 xop0 = convert_to_mode (mode0, xop0, unsignedp); 2773 2774 /* Now, if insn doesn't accept our operand, put it into a pseudo. */ 2775 2776 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)) 2777 xop0 = copy_to_mode_reg (mode0, xop0); 2778 2779 if (! (*insn_data[icode].operand[0].predicate) (temp, submode)) 2780 temp = gen_reg_rtx (submode); 2781 2782 pat = GEN_FCN (icode) (temp, xop0); 2783 if (pat) 2784 { 2785 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX 2786 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 2787 NULL_RTX)) 2788 { 2789 delete_insns_since (last); 2790 return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 2791 unsignedp); 2792 } 2793 2794 emit_insn (pat); 2795 2796 return temp; 2797 } 2798 else 2799 delete_insns_since (last); 2800 } 2801 2802 /* It can't be done in this mode. Can we open-code it in a wider mode? */ 2803 2804 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 2805 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 2806 { 2807 if (this_abs_optab->handlers[(int) wider_mode].insn_code 2808 != CODE_FOR_nothing) 2809 { 2810 rtx xop0 = op0; 2811 2812 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp); 2813 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp); 2814 2815 if (temp) 2816 { 2817 if (class != MODE_COMPLEX_INT) 2818 { 2819 if (target == 0) 2820 target = gen_reg_rtx (submode); 2821 convert_move (target, temp, 0); 2822 return target; 2823 } 2824 else 2825 return gen_lowpart (submode, temp); 2826 } 2827 else 2828 delete_insns_since (last); 2829 } 2830 } 2831 2832 /* Open-code the complex absolute-value operation 2833 if we can open-code sqrt. Otherwise it's not worth while. */ 2834 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing 2835 && ! flag_trapv) 2836 { 2837 rtx real, imag, total; 2838 2839 real = gen_realpart (submode, op0); 2840 imag = gen_imagpart (submode, op0); 2841 2842 /* Square both parts. */ 2843 real = expand_mult (submode, real, real, NULL_RTX, 0); 2844 imag = expand_mult (submode, imag, imag, NULL_RTX, 0); 2845 2846 /* Sum the parts. */ 2847 total = expand_binop (submode, add_optab, real, imag, NULL_RTX, 2848 0, OPTAB_LIB_WIDEN); 2849 2850 /* Get sqrt in TARGET. Set TARGET to where the result is. */ 2851 target = expand_unop (submode, sqrt_optab, total, target, 0); 2852 if (target == 0) 2853 delete_insns_since (last); 2854 else 2855 return target; 2856 } 2857 2858 /* Now try a library call in this mode. */ 2859 if (this_abs_optab->handlers[(int) mode].libfunc) 2860 { 2861 rtx insns; 2862 rtx value; 2863 2864 start_sequence (); 2865 2866 /* Pass 1 for NO_QUEUE so we don't lose any increments 2867 if the libcall is cse'd or moved. */ 2868 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc, 2869 NULL_RTX, LCT_CONST, submode, 1, op0, mode); 2870 insns = get_insns (); 2871 end_sequence (); 2872 2873 target = gen_reg_rtx (submode); 2874 emit_libcall_block (insns, target, value, 2875 gen_rtx_fmt_e (this_abs_optab->code, mode, op0)); 2876 2877 return target; 2878 } 2879 2880 /* It can't be done in this mode. Can we do it in a wider mode? */ 2881 2882 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 2883 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 2884 { 2885 if ((this_abs_optab->handlers[(int) wider_mode].insn_code 2886 != CODE_FOR_nothing) 2887 || this_abs_optab->handlers[(int) wider_mode].libfunc) 2888 { 2889 rtx xop0 = op0; 2890 2891 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp); 2892 2893 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp); 2894 2895 if (temp) 2896 { 2897 if (class != MODE_COMPLEX_INT) 2898 { 2899 if (target == 0) 2900 target = gen_reg_rtx (submode); 2901 convert_move (target, temp, 0); 2902 return target; 2903 } 2904 else 2905 return gen_lowpart (submode, temp); 2906 } 2907 else 2908 delete_insns_since (last); 2909 } 2910 } 2911 2912 delete_insns_since (entry_last); 2913 return 0; 2914} 2915 2916/* Generate an instruction whose insn-code is INSN_CODE, 2917 with two operands: an output TARGET and an input OP0. 2918 TARGET *must* be nonzero, and the output is always stored there. 2919 CODE is an rtx code such that (CODE OP0) is an rtx that describes 2920 the value that is stored into TARGET. */ 2921 2922void 2923emit_unop_insn (icode, target, op0, code) 2924 int icode; 2925 rtx target; 2926 rtx op0; 2927 enum rtx_code code; 2928{ 2929 rtx temp; 2930 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 2931 rtx pat; 2932 2933 temp = target = protect_from_queue (target, 1); 2934 2935 op0 = protect_from_queue (op0, 0); 2936 2937 /* Sign and zero extension from memory is often done specially on 2938 RISC machines, so forcing into a register here can pessimize 2939 code. */ 2940 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND) 2941 op0 = force_not_mem (op0); 2942 2943 /* Now, if insn does not accept our operands, put them into pseudos. */ 2944 2945 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 2946 op0 = copy_to_mode_reg (mode0, op0); 2947 2948 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp)) 2949 || (flag_force_mem && GET_CODE (temp) == MEM)) 2950 temp = gen_reg_rtx (GET_MODE (temp)); 2951 2952 pat = GEN_FCN (icode) (temp, op0); 2953 2954 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN) 2955 add_equal_note (pat, temp, code, op0, NULL_RTX); 2956 2957 emit_insn (pat); 2958 2959 if (temp != target) 2960 emit_move_insn (target, temp); 2961} 2962 2963/* Emit code to perform a series of operations on a multi-word quantity, one 2964 word at a time. 2965 2966 Such a block is preceded by a CLOBBER of the output, consists of multiple 2967 insns, each setting one word of the output, and followed by a SET copying 2968 the output to itself. 2969 2970 Each of the insns setting words of the output receives a REG_NO_CONFLICT 2971 note indicating that it doesn't conflict with the (also multi-word) 2972 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL 2973 notes. 2974 2975 INSNS is a block of code generated to perform the operation, not including 2976 the CLOBBER and final copy. All insns that compute intermediate values 2977 are first emitted, followed by the block as described above. 2978 2979 TARGET, OP0, and OP1 are the output and inputs of the operations, 2980 respectively. OP1 may be zero for a unary operation. 2981 2982 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note 2983 on the last insn. 2984 2985 If TARGET is not a register, INSNS is simply emitted with no special 2986 processing. Likewise if anything in INSNS is not an INSN or if 2987 there is a libcall block inside INSNS. 2988 2989 The final insn emitted is returned. */ 2990 2991rtx 2992emit_no_conflict_block (insns, target, op0, op1, equiv) 2993 rtx insns; 2994 rtx target; 2995 rtx op0, op1; 2996 rtx equiv; 2997{ 2998 rtx prev, next, first, last, insn; 2999 3000 if (GET_CODE (target) != REG || reload_in_progress) 3001 return emit_insn (insns); 3002 else 3003 for (insn = insns; insn; insn = NEXT_INSN (insn)) 3004 if (GET_CODE (insn) != INSN 3005 || find_reg_note (insn, REG_LIBCALL, NULL_RTX)) 3006 return emit_insn (insns); 3007 3008 /* First emit all insns that do not store into words of the output and remove 3009 these from the list. */ 3010 for (insn = insns; insn; insn = next) 3011 { 3012 rtx set = 0, note; 3013 int i; 3014 3015 next = NEXT_INSN (insn); 3016 3017 /* Some ports (cris) create an libcall regions at their own. We must 3018 avoid any potential nesting of LIBCALLs. */ 3019 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL) 3020 remove_note (insn, note); 3021 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL) 3022 remove_note (insn, note); 3023 3024 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE 3025 || GET_CODE (PATTERN (insn)) == CLOBBER) 3026 set = PATTERN (insn); 3027 else if (GET_CODE (PATTERN (insn)) == PARALLEL) 3028 { 3029 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) 3030 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) 3031 { 3032 set = XVECEXP (PATTERN (insn), 0, i); 3033 break; 3034 } 3035 } 3036 3037 if (set == 0) 3038 abort (); 3039 3040 if (! reg_overlap_mentioned_p (target, SET_DEST (set))) 3041 { 3042 if (PREV_INSN (insn)) 3043 NEXT_INSN (PREV_INSN (insn)) = next; 3044 else 3045 insns = next; 3046 3047 if (next) 3048 PREV_INSN (next) = PREV_INSN (insn); 3049 3050 add_insn (insn); 3051 } 3052 } 3053 3054 prev = get_last_insn (); 3055 3056 /* Now write the CLOBBER of the output, followed by the setting of each 3057 of the words, followed by the final copy. */ 3058 if (target != op0 && target != op1) 3059 emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); 3060 3061 for (insn = insns; insn; insn = next) 3062 { 3063 next = NEXT_INSN (insn); 3064 add_insn (insn); 3065 3066 if (op1 && GET_CODE (op1) == REG) 3067 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1, 3068 REG_NOTES (insn)); 3069 3070 if (op0 && GET_CODE (op0) == REG) 3071 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0, 3072 REG_NOTES (insn)); 3073 } 3074 3075 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code 3076 != CODE_FOR_nothing) 3077 { 3078 last = emit_move_insn (target, target); 3079 if (equiv) 3080 set_unique_reg_note (last, REG_EQUAL, equiv); 3081 } 3082 else 3083 { 3084 last = get_last_insn (); 3085 3086 /* Remove any existing REG_EQUAL note from "last", or else it will 3087 be mistaken for a note referring to the full contents of the 3088 alleged libcall value when found together with the REG_RETVAL 3089 note added below. An existing note can come from an insn 3090 expansion at "last". */ 3091 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX)); 3092 } 3093 3094 if (prev == 0) 3095 first = get_insns (); 3096 else 3097 first = NEXT_INSN (prev); 3098 3099 /* Encapsulate the block so it gets manipulated as a unit. */ 3100 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, 3101 REG_NOTES (first)); 3102 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); 3103 3104 return last; 3105} 3106 3107/* Emit code to make a call to a constant function or a library call. 3108 3109 INSNS is a list containing all insns emitted in the call. 3110 These insns leave the result in RESULT. Our block is to copy RESULT 3111 to TARGET, which is logically equivalent to EQUIV. 3112 3113 We first emit any insns that set a pseudo on the assumption that these are 3114 loading constants into registers; doing so allows them to be safely cse'ed 3115 between blocks. Then we emit all the other insns in the block, followed by 3116 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL 3117 note with an operand of EQUIV. 3118 3119 Moving assignments to pseudos outside of the block is done to improve 3120 the generated code, but is not required to generate correct code, 3121 hence being unable to move an assignment is not grounds for not making 3122 a libcall block. There are two reasons why it is safe to leave these 3123 insns inside the block: First, we know that these pseudos cannot be 3124 used in generated RTL outside the block since they are created for 3125 temporary purposes within the block. Second, CSE will not record the 3126 values of anything set inside a libcall block, so we know they must 3127 be dead at the end of the block. 3128 3129 Except for the first group of insns (the ones setting pseudos), the 3130 block is delimited by REG_RETVAL and REG_LIBCALL notes. */ 3131 3132void 3133emit_libcall_block (insns, target, result, equiv) 3134 rtx insns; 3135 rtx target; 3136 rtx result; 3137 rtx equiv; 3138{ 3139 rtx final_dest = target; 3140 rtx prev, next, first, last, insn; 3141 3142 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn 3143 into a MEM later. Protect the libcall block from this change. */ 3144 if (! REG_P (target) || REG_USERVAR_P (target)) 3145 target = gen_reg_rtx (GET_MODE (target)); 3146 3147 /* If we're using non-call exceptions, a libcall corresponding to an 3148 operation that may trap may also trap. */ 3149 if (flag_non_call_exceptions && may_trap_p (equiv)) 3150 { 3151 for (insn = insns; insn; insn = NEXT_INSN (insn)) 3152 if (GET_CODE (insn) == CALL_INSN) 3153 { 3154 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 3155 3156 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0) 3157 remove_note (insn, note); 3158 } 3159 } 3160 else 3161 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION 3162 reg note to indicate that this call cannot throw or execute a nonlocal 3163 goto (unless there is already a REG_EH_REGION note, in which case 3164 we update it). */ 3165 for (insn = insns; insn; insn = NEXT_INSN (insn)) 3166 if (GET_CODE (insn) == CALL_INSN) 3167 { 3168 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 3169 3170 if (note != 0) 3171 XEXP (note, 0) = GEN_INT (-1); 3172 else 3173 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1), 3174 REG_NOTES (insn)); 3175 } 3176 3177 /* First emit all insns that set pseudos. Remove them from the list as 3178 we go. Avoid insns that set pseudos which were referenced in previous 3179 insns. These can be generated by move_by_pieces, for example, 3180 to update an address. Similarly, avoid insns that reference things 3181 set in previous insns. */ 3182 3183 for (insn = insns; insn; insn = next) 3184 { 3185 rtx set = single_set (insn); 3186 rtx note; 3187 3188 /* Some ports (cris) create an libcall regions at their own. We must 3189 avoid any potential nesting of LIBCALLs. */ 3190 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL) 3191 remove_note (insn, note); 3192 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL) 3193 remove_note (insn, note); 3194 3195 next = NEXT_INSN (insn); 3196 3197 if (set != 0 && GET_CODE (SET_DEST (set)) == REG 3198 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER 3199 && (insn == insns 3200 || ((! INSN_P(insns) 3201 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns))) 3202 && ! reg_used_between_p (SET_DEST (set), insns, insn) 3203 && ! modified_in_p (SET_SRC (set), insns) 3204 && ! modified_between_p (SET_SRC (set), insns, insn)))) 3205 { 3206 if (PREV_INSN (insn)) 3207 NEXT_INSN (PREV_INSN (insn)) = next; 3208 else 3209 insns = next; 3210 3211 if (next) 3212 PREV_INSN (next) = PREV_INSN (insn); 3213 3214 add_insn (insn); 3215 } 3216 } 3217 3218 prev = get_last_insn (); 3219 3220 /* Write the remaining insns followed by the final copy. */ 3221 3222 for (insn = insns; insn; insn = next) 3223 { 3224 next = NEXT_INSN (insn); 3225 3226 add_insn (insn); 3227 } 3228 3229 last = emit_move_insn (target, result); 3230 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code 3231 != CODE_FOR_nothing) 3232 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv)); 3233 else 3234 { 3235 /* Remove any existing REG_EQUAL note from "last", or else it will 3236 be mistaken for a note referring to the full contents of the 3237 libcall value when found together with the REG_RETVAL note added 3238 below. An existing note can come from an insn expansion at 3239 "last". */ 3240 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX)); 3241 } 3242 3243 if (final_dest != target) 3244 emit_move_insn (final_dest, target); 3245 3246 if (prev == 0) 3247 first = get_insns (); 3248 else 3249 first = NEXT_INSN (prev); 3250 3251 /* Encapsulate the block so it gets manipulated as a unit. */ 3252 if (!flag_non_call_exceptions || !may_trap_p (equiv)) 3253 { 3254 /* We can't attach the REG_LIBCALL and REG_RETVAL notes 3255 when the encapsulated region would not be in one basic block, 3256 i.e. when there is a control_flow_insn_p insn between FIRST and LAST. 3257 */ 3258 bool attach_libcall_retval_notes = true; 3259 next = NEXT_INSN (last); 3260 for (insn = first; insn != next; insn = NEXT_INSN (insn)) 3261 if (control_flow_insn_p (insn)) 3262 { 3263 attach_libcall_retval_notes = false; 3264 break; 3265 } 3266 3267 if (attach_libcall_retval_notes) 3268 { 3269 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, 3270 REG_NOTES (first)); 3271 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, 3272 REG_NOTES (last)); 3273 } 3274 } 3275} 3276 3277/* Generate code to store zero in X. */ 3278 3279void 3280emit_clr_insn (x) 3281 rtx x; 3282{ 3283 emit_move_insn (x, const0_rtx); 3284} 3285 3286/* Generate code to store 1 in X 3287 assuming it contains zero beforehand. */ 3288 3289void 3290emit_0_to_1_insn (x) 3291 rtx x; 3292{ 3293 emit_move_insn (x, const1_rtx); 3294} 3295 3296/* Nonzero if we can perform a comparison of mode MODE straightforwardly. 3297 PURPOSE describes how this comparison will be used. CODE is the rtx 3298 comparison code we will be using. 3299 3300 ??? Actually, CODE is slightly weaker than that. A target is still 3301 required to implement all of the normal bcc operations, but not 3302 required to implement all (or any) of the unordered bcc operations. */ 3303 3304int 3305can_compare_p (code, mode, purpose) 3306 enum rtx_code code; 3307 enum machine_mode mode; 3308 enum can_compare_purpose purpose; 3309{ 3310 do 3311 { 3312 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 3313 { 3314 if (purpose == ccp_jump) 3315 return bcc_gen_fctn[(int) code] != NULL; 3316 else if (purpose == ccp_store_flag) 3317 return setcc_gen_code[(int) code] != CODE_FOR_nothing; 3318 else 3319 /* There's only one cmov entry point, and it's allowed to fail. */ 3320 return 1; 3321 } 3322 if (purpose == ccp_jump 3323 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 3324 return 1; 3325 if (purpose == ccp_cmov 3326 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 3327 return 1; 3328 if (purpose == ccp_store_flag 3329 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 3330 return 1; 3331 3332 mode = GET_MODE_WIDER_MODE (mode); 3333 } 3334 while (mode != VOIDmode); 3335 3336 return 0; 3337} 3338 3339/* This function is called when we are going to emit a compare instruction that 3340 compares the values found in *PX and *PY, using the rtl operator COMPARISON. 3341 3342 *PMODE is the mode of the inputs (in case they are const_int). 3343 *PUNSIGNEDP nonzero says that the operands are unsigned; 3344 this matters if they need to be widened. 3345 3346 If they have mode BLKmode, then SIZE specifies the size of both operands. 3347 3348 This function performs all the setup necessary so that the caller only has 3349 to emit a single comparison insn. This setup can involve doing a BLKmode 3350 comparison or emitting a library call to perform the comparison if no insn 3351 is available to handle it. 3352 The values which are passed in through pointers can be modified; the caller 3353 should perform the comparison on the modified values. */ 3354 3355static void 3356prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose) 3357 rtx *px, *py; 3358 enum rtx_code *pcomparison; 3359 rtx size; 3360 enum machine_mode *pmode; 3361 int *punsignedp; 3362 enum can_compare_purpose purpose; 3363{ 3364 enum machine_mode mode = *pmode; 3365 rtx x = *px, y = *py; 3366 int unsignedp = *punsignedp; 3367 enum mode_class class; 3368 3369 class = GET_MODE_CLASS (mode); 3370 3371 /* They could both be VOIDmode if both args are immediate constants, 3372 but we should fold that at an earlier stage. 3373 With no special code here, this will call abort, 3374 reminding the programmer to implement such folding. */ 3375 3376 if (mode != BLKmode && flag_force_mem) 3377 { 3378 x = force_not_mem (x); 3379 y = force_not_mem (y); 3380 } 3381 3382 /* If we are inside an appropriately-short loop and one operand is an 3383 expensive constant, force it into a register. */ 3384 if (CONSTANT_P (x) && preserve_subexpressions_p () 3385 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1)) 3386 x = force_reg (mode, x); 3387 3388 if (CONSTANT_P (y) && preserve_subexpressions_p () 3389 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1)) 3390 y = force_reg (mode, y); 3391 3392#ifdef HAVE_cc0 3393 /* Abort if we have a non-canonical comparison. The RTL documentation 3394 states that canonical comparisons are required only for targets which 3395 have cc0. */ 3396 if (CONSTANT_P (x) && ! CONSTANT_P (y)) 3397 abort (); 3398#endif 3399 3400 /* Don't let both operands fail to indicate the mode. */ 3401 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode) 3402 x = force_reg (mode, x); 3403 3404 /* Handle all BLKmode compares. */ 3405 3406 if (mode == BLKmode) 3407 { 3408 rtx result; 3409 enum machine_mode result_mode; 3410 rtx opalign ATTRIBUTE_UNUSED 3411 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT); 3412 3413 emit_queue (); 3414 x = protect_from_queue (x, 0); 3415 y = protect_from_queue (y, 0); 3416 3417 if (size == 0) 3418 abort (); 3419#ifdef HAVE_cmpstrqi 3420 if (HAVE_cmpstrqi 3421 && GET_CODE (size) == CONST_INT 3422 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode))) 3423 { 3424 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode; 3425 result = gen_reg_rtx (result_mode); 3426 emit_insn (gen_cmpstrqi (result, x, y, size, opalign)); 3427 } 3428 else 3429#endif 3430#ifdef HAVE_cmpstrhi 3431 if (HAVE_cmpstrhi 3432 && GET_CODE (size) == CONST_INT 3433 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode))) 3434 { 3435 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode; 3436 result = gen_reg_rtx (result_mode); 3437 emit_insn (gen_cmpstrhi (result, x, y, size, opalign)); 3438 } 3439 else 3440#endif 3441#ifdef HAVE_cmpstrsi 3442 if (HAVE_cmpstrsi) 3443 { 3444 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 3445 result = gen_reg_rtx (result_mode); 3446 size = protect_from_queue (size, 0); 3447 emit_insn (gen_cmpstrsi (result, x, y, 3448 convert_to_mode (SImode, size, 1), 3449 opalign)); 3450 } 3451 else 3452#endif 3453 { 3454#ifdef TARGET_MEM_FUNCTIONS 3455 result = emit_library_call_value (memcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK, 3456 TYPE_MODE (integer_type_node), 3, 3457 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, 3458 convert_to_mode (TYPE_MODE (sizetype), size, 3459 TREE_UNSIGNED (sizetype)), 3460 TYPE_MODE (sizetype)); 3461#else 3462 result = emit_library_call_value (bcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK, 3463 TYPE_MODE (integer_type_node), 3, 3464 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, 3465 convert_to_mode (TYPE_MODE (integer_type_node), 3466 size, 3467 TREE_UNSIGNED (integer_type_node)), 3468 TYPE_MODE (integer_type_node)); 3469#endif 3470 3471 result_mode = TYPE_MODE (integer_type_node); 3472 } 3473 *px = result; 3474 *py = const0_rtx; 3475 *pmode = result_mode; 3476 return; 3477 } 3478 3479 *px = x; 3480 *py = y; 3481 if (can_compare_p (*pcomparison, mode, purpose)) 3482 return; 3483 3484 /* Handle a lib call just for the mode we are using. */ 3485 3486 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT) 3487 { 3488 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc; 3489 rtx result; 3490 3491 /* If we want unsigned, and this mode has a distinct unsigned 3492 comparison routine, use that. */ 3493 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc) 3494 libfunc = ucmp_optab->handlers[(int) mode].libfunc; 3495 3496 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK, 3497 word_mode, 2, x, mode, y, mode); 3498 3499 /* Integer comparison returns a result that must be compared against 1, 3500 so that even if we do an unsigned compare afterward, 3501 there is still a value that can represent the result "less than". */ 3502 *px = result; 3503 *py = const1_rtx; 3504 *pmode = word_mode; 3505 return; 3506 } 3507 3508 if (class == MODE_FLOAT) 3509 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp); 3510 3511 else 3512 abort (); 3513} 3514 3515/* Before emitting an insn with code ICODE, make sure that X, which is going 3516 to be used for operand OPNUM of the insn, is converted from mode MODE to 3517 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and 3518 that it is accepted by the operand predicate. Return the new value. */ 3519 3520rtx 3521prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp) 3522 int icode; 3523 rtx x; 3524 int opnum; 3525 enum machine_mode mode, wider_mode; 3526 int unsignedp; 3527{ 3528 x = protect_from_queue (x, 0); 3529 3530 if (mode != wider_mode) 3531 x = convert_modes (wider_mode, mode, x, unsignedp); 3532 3533 if (! (*insn_data[icode].operand[opnum].predicate) 3534 (x, insn_data[icode].operand[opnum].mode)) 3535 { 3536 if (no_new_pseudos) 3537 return NULL_RTX; 3538 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x); 3539 } 3540 3541 return x; 3542} 3543 3544/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know 3545 we can do the comparison. 3546 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may 3547 be NULL_RTX which indicates that only a comparison is to be generated. */ 3548 3549static void 3550emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label) 3551 rtx x, y; 3552 enum machine_mode mode; 3553 enum rtx_code comparison; 3554 int unsignedp; 3555 rtx label; 3556{ 3557 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y); 3558 enum mode_class class = GET_MODE_CLASS (mode); 3559 enum machine_mode wider_mode = mode; 3560 3561 /* Try combined insns first. */ 3562 do 3563 { 3564 enum insn_code icode; 3565 PUT_MODE (test, wider_mode); 3566 3567 if (label) 3568 { 3569 icode = cbranch_optab->handlers[(int) wider_mode].insn_code; 3570 3571 if (icode != CODE_FOR_nothing 3572 && (*insn_data[icode].operand[0].predicate) (test, wider_mode)) 3573 { 3574 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp); 3575 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp); 3576 emit_jump_insn (GEN_FCN (icode) (test, x, y, label)); 3577 return; 3578 } 3579 } 3580 3581 /* Handle some compares against zero. */ 3582 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code; 3583 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing) 3584 { 3585 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp); 3586 emit_insn (GEN_FCN (icode) (x)); 3587 if (label) 3588 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label)); 3589 return; 3590 } 3591 3592 /* Handle compares for which there is a directly suitable insn. */ 3593 3594 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code; 3595 if (icode != CODE_FOR_nothing) 3596 { 3597 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp); 3598 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp); 3599 emit_insn (GEN_FCN (icode) (x, y)); 3600 if (label) 3601 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label)); 3602 return; 3603 } 3604 3605 if (class != MODE_INT && class != MODE_FLOAT 3606 && class != MODE_COMPLEX_FLOAT) 3607 break; 3608 3609 wider_mode = GET_MODE_WIDER_MODE (wider_mode); 3610 } 3611 while (wider_mode != VOIDmode); 3612 3613 abort (); 3614} 3615 3616/* Generate code to compare X with Y so that the condition codes are 3617 set and to jump to LABEL if the condition is true. If X is a 3618 constant and Y is not a constant, then the comparison is swapped to 3619 ensure that the comparison RTL has the canonical form. 3620 3621 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they 3622 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select 3623 the proper branch condition code. 3624 3625 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y. 3626 3627 MODE is the mode of the inputs (in case they are const_int). 3628 3629 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will 3630 be passed unchanged to emit_cmp_insn, then potentially converted into an 3631 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */ 3632 3633void 3634emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label) 3635 rtx x, y; 3636 enum rtx_code comparison; 3637 rtx size; 3638 enum machine_mode mode; 3639 int unsignedp; 3640 rtx label; 3641{ 3642 rtx op0 = x, op1 = y; 3643 3644 /* Swap operands and condition to ensure canonical RTL. */ 3645 if (swap_commutative_operands_p (x, y)) 3646 { 3647 /* If we're not emitting a branch, this means some caller 3648 is out of sync. */ 3649 if (! label) 3650 abort (); 3651 3652 op0 = y, op1 = x; 3653 comparison = swap_condition (comparison); 3654 } 3655 3656#ifdef HAVE_cc0 3657 /* If OP0 is still a constant, then both X and Y must be constants. Force 3658 X into a register to avoid aborting in emit_cmp_insn due to non-canonical 3659 RTL. */ 3660 if (CONSTANT_P (op0)) 3661 op0 = force_reg (mode, op0); 3662#endif 3663 3664 emit_queue (); 3665 if (unsignedp) 3666 comparison = unsigned_condition (comparison); 3667 3668 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, 3669 ccp_jump); 3670 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label); 3671} 3672 3673/* Like emit_cmp_and_jump_insns, but generate only the comparison. */ 3674 3675void 3676emit_cmp_insn (x, y, comparison, size, mode, unsignedp) 3677 rtx x, y; 3678 enum rtx_code comparison; 3679 rtx size; 3680 enum machine_mode mode; 3681 int unsignedp; 3682{ 3683 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0); 3684} 3685 3686/* Emit a library call comparison between floating point X and Y. 3687 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */ 3688 3689static void 3690prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp) 3691 rtx *px, *py; 3692 enum rtx_code *pcomparison; 3693 enum machine_mode *pmode; 3694 int *punsignedp; 3695{ 3696 enum rtx_code comparison = *pcomparison; 3697 rtx tmp; 3698 rtx x = *px = protect_from_queue (*px, 0); 3699 rtx y = *py = protect_from_queue (*py, 0); 3700 enum machine_mode mode = GET_MODE (x); 3701 rtx libfunc = 0; 3702 rtx result; 3703 3704 if (mode == HFmode) 3705 switch (comparison) 3706 { 3707 case EQ: 3708 libfunc = eqhf2_libfunc; 3709 break; 3710 3711 case NE: 3712 libfunc = nehf2_libfunc; 3713 break; 3714 3715 case GT: 3716 libfunc = gthf2_libfunc; 3717 if (libfunc == NULL_RTX) 3718 { 3719 tmp = x; x = y; y = tmp; 3720 *pcomparison = LT; 3721 libfunc = lthf2_libfunc; 3722 } 3723 break; 3724 3725 case GE: 3726 libfunc = gehf2_libfunc; 3727 if (libfunc == NULL_RTX) 3728 { 3729 tmp = x; x = y; y = tmp; 3730 *pcomparison = LE; 3731 libfunc = lehf2_libfunc; 3732 } 3733 break; 3734 3735 case LT: 3736 libfunc = lthf2_libfunc; 3737 if (libfunc == NULL_RTX) 3738 { 3739 tmp = x; x = y; y = tmp; 3740 *pcomparison = GT; 3741 libfunc = gthf2_libfunc; 3742 } 3743 break; 3744 3745 case LE: 3746 libfunc = lehf2_libfunc; 3747 if (libfunc == NULL_RTX) 3748 { 3749 tmp = x; x = y; y = tmp; 3750 *pcomparison = GE; 3751 libfunc = gehf2_libfunc; 3752 } 3753 break; 3754 3755 case UNORDERED: 3756 libfunc = unordhf2_libfunc; 3757 break; 3758 3759 default: 3760 break; 3761 } 3762 else if (mode == SFmode) 3763 switch (comparison) 3764 { 3765 case EQ: 3766 libfunc = eqsf2_libfunc; 3767 break; 3768 3769 case NE: 3770 libfunc = nesf2_libfunc; 3771 break; 3772 3773 case GT: 3774 libfunc = gtsf2_libfunc; 3775 if (libfunc == NULL_RTX) 3776 { 3777 tmp = x; x = y; y = tmp; 3778 *pcomparison = LT; 3779 libfunc = ltsf2_libfunc; 3780 } 3781 break; 3782 3783 case GE: 3784 libfunc = gesf2_libfunc; 3785 if (libfunc == NULL_RTX) 3786 { 3787 tmp = x; x = y; y = tmp; 3788 *pcomparison = LE; 3789 libfunc = lesf2_libfunc; 3790 } 3791 break; 3792 3793 case LT: 3794 libfunc = ltsf2_libfunc; 3795 if (libfunc == NULL_RTX) 3796 { 3797 tmp = x; x = y; y = tmp; 3798 *pcomparison = GT; 3799 libfunc = gtsf2_libfunc; 3800 } 3801 break; 3802 3803 case LE: 3804 libfunc = lesf2_libfunc; 3805 if (libfunc == NULL_RTX) 3806 { 3807 tmp = x; x = y; y = tmp; 3808 *pcomparison = GE; 3809 libfunc = gesf2_libfunc; 3810 } 3811 break; 3812 3813 case UNORDERED: 3814 libfunc = unordsf2_libfunc; 3815 break; 3816 3817 default: 3818 break; 3819 } 3820 else if (mode == DFmode) 3821 switch (comparison) 3822 { 3823 case EQ: 3824 libfunc = eqdf2_libfunc; 3825 break; 3826 3827 case NE: 3828 libfunc = nedf2_libfunc; 3829 break; 3830 3831 case GT: 3832 libfunc = gtdf2_libfunc; 3833 if (libfunc == NULL_RTX) 3834 { 3835 tmp = x; x = y; y = tmp; 3836 *pcomparison = LT; 3837 libfunc = ltdf2_libfunc; 3838 } 3839 break; 3840 3841 case GE: 3842 libfunc = gedf2_libfunc; 3843 if (libfunc == NULL_RTX) 3844 { 3845 tmp = x; x = y; y = tmp; 3846 *pcomparison = LE; 3847 libfunc = ledf2_libfunc; 3848 } 3849 break; 3850 3851 case LT: 3852 libfunc = ltdf2_libfunc; 3853 if (libfunc == NULL_RTX) 3854 { 3855 tmp = x; x = y; y = tmp; 3856 *pcomparison = GT; 3857 libfunc = gtdf2_libfunc; 3858 } 3859 break; 3860 3861 case LE: 3862 libfunc = ledf2_libfunc; 3863 if (libfunc == NULL_RTX) 3864 { 3865 tmp = x; x = y; y = tmp; 3866 *pcomparison = GE; 3867 libfunc = gedf2_libfunc; 3868 } 3869 break; 3870 3871 case UNORDERED: 3872 libfunc = unorddf2_libfunc; 3873 break; 3874 3875 default: 3876 break; 3877 } 3878 else if (mode == XFmode) 3879 switch (comparison) 3880 { 3881 case EQ: 3882 libfunc = eqxf2_libfunc; 3883 break; 3884 3885 case NE: 3886 libfunc = nexf2_libfunc; 3887 break; 3888 3889 case GT: 3890 libfunc = gtxf2_libfunc; 3891 if (libfunc == NULL_RTX) 3892 { 3893 tmp = x; x = y; y = tmp; 3894 *pcomparison = LT; 3895 libfunc = ltxf2_libfunc; 3896 } 3897 break; 3898 3899 case GE: 3900 libfunc = gexf2_libfunc; 3901 if (libfunc == NULL_RTX) 3902 { 3903 tmp = x; x = y; y = tmp; 3904 *pcomparison = LE; 3905 libfunc = lexf2_libfunc; 3906 } 3907 break; 3908 3909 case LT: 3910 libfunc = ltxf2_libfunc; 3911 if (libfunc == NULL_RTX) 3912 { 3913 tmp = x; x = y; y = tmp; 3914 *pcomparison = GT; 3915 libfunc = gtxf2_libfunc; 3916 } 3917 break; 3918 3919 case LE: 3920 libfunc = lexf2_libfunc; 3921 if (libfunc == NULL_RTX) 3922 { 3923 tmp = x; x = y; y = tmp; 3924 *pcomparison = GE; 3925 libfunc = gexf2_libfunc; 3926 } 3927 break; 3928 3929 case UNORDERED: 3930 libfunc = unordxf2_libfunc; 3931 break; 3932 3933 default: 3934 break; 3935 } 3936 else if (mode == TFmode) 3937 switch (comparison) 3938 { 3939 case EQ: 3940 libfunc = eqtf2_libfunc; 3941 break; 3942 3943 case NE: 3944 libfunc = netf2_libfunc; 3945 break; 3946 3947 case GT: 3948 libfunc = gttf2_libfunc; 3949 if (libfunc == NULL_RTX) 3950 { 3951 tmp = x; x = y; y = tmp; 3952 *pcomparison = LT; 3953 libfunc = lttf2_libfunc; 3954 } 3955 break; 3956 3957 case GE: 3958 libfunc = getf2_libfunc; 3959 if (libfunc == NULL_RTX) 3960 { 3961 tmp = x; x = y; y = tmp; 3962 *pcomparison = LE; 3963 libfunc = letf2_libfunc; 3964 } 3965 break; 3966 3967 case LT: 3968 libfunc = lttf2_libfunc; 3969 if (libfunc == NULL_RTX) 3970 { 3971 tmp = x; x = y; y = tmp; 3972 *pcomparison = GT; 3973 libfunc = gttf2_libfunc; 3974 } 3975 break; 3976 3977 case LE: 3978 libfunc = letf2_libfunc; 3979 if (libfunc == NULL_RTX) 3980 { 3981 tmp = x; x = y; y = tmp; 3982 *pcomparison = GE; 3983 libfunc = getf2_libfunc; 3984 } 3985 break; 3986 3987 case UNORDERED: 3988 libfunc = unordtf2_libfunc; 3989 break; 3990 3991 default: 3992 break; 3993 } 3994 else 3995 { 3996 enum machine_mode wider_mode; 3997 3998 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; 3999 wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 4000 { 4001 if ((cmp_optab->handlers[(int) wider_mode].insn_code 4002 != CODE_FOR_nothing) 4003 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0)) 4004 { 4005 x = protect_from_queue (x, 0); 4006 y = protect_from_queue (y, 0); 4007 *px = convert_to_mode (wider_mode, x, 0); 4008 *py = convert_to_mode (wider_mode, y, 0); 4009 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp); 4010 return; 4011 } 4012 } 4013 abort (); 4014 } 4015 4016 if (libfunc == 0) 4017 abort (); 4018 4019 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK, 4020 word_mode, 2, x, mode, y, mode); 4021 *px = result; 4022 *py = const0_rtx; 4023 *pmode = word_mode; 4024 if (comparison == UNORDERED) 4025 *pcomparison = NE; 4026#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL 4027 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) 4028 *pcomparison = NE; 4029#endif 4030 *punsignedp = 0; 4031} 4032 4033/* Generate code to indirectly jump to a location given in the rtx LOC. */ 4034 4035void 4036emit_indirect_jump (loc) 4037 rtx loc; 4038{ 4039 if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate) 4040 (loc, Pmode))) 4041 loc = copy_to_mode_reg (Pmode, loc); 4042 4043 emit_jump_insn (gen_indirect_jump (loc)); 4044 emit_barrier (); 4045} 4046 4047#ifdef HAVE_conditional_move 4048 4049/* Emit a conditional move instruction if the machine supports one for that 4050 condition and machine mode. 4051 4052 OP0 and OP1 are the operands that should be compared using CODE. CMODE is 4053 the mode to use should they be constants. If it is VOIDmode, they cannot 4054 both be constants. 4055 4056 OP2 should be stored in TARGET if the comparison is true, otherwise OP3 4057 should be stored there. MODE is the mode to use should they be constants. 4058 If it is VOIDmode, they cannot both be constants. 4059 4060 The result is either TARGET (perhaps modified) or NULL_RTX if the operation 4061 is not supported. */ 4062 4063rtx 4064emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode, 4065 unsignedp) 4066 rtx target; 4067 enum rtx_code code; 4068 rtx op0, op1; 4069 enum machine_mode cmode; 4070 rtx op2, op3; 4071 enum machine_mode mode; 4072 int unsignedp; 4073{ 4074 rtx tem, subtarget, comparison, insn; 4075 enum insn_code icode; 4076 enum rtx_code reversed; 4077 4078 /* If one operand is constant, make it the second one. Only do this 4079 if the other operand is not constant as well. */ 4080 4081 if (swap_commutative_operands_p (op0, op1)) 4082 { 4083 tem = op0; 4084 op0 = op1; 4085 op1 = tem; 4086 code = swap_condition (code); 4087 } 4088 4089 /* get_condition will prefer to generate LT and GT even if the old 4090 comparison was against zero, so undo that canonicalization here since 4091 comparisons against zero are cheaper. */ 4092 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1) 4093 code = LE, op1 = const0_rtx; 4094 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1) 4095 code = GE, op1 = const0_rtx; 4096 4097 if (cmode == VOIDmode) 4098 cmode = GET_MODE (op0); 4099 4100 if (swap_commutative_operands_p (op2, op3) 4101 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL)) 4102 != UNKNOWN)) 4103 { 4104 tem = op2; 4105 op2 = op3; 4106 op3 = tem; 4107 code = reversed; 4108 } 4109 4110 if (mode == VOIDmode) 4111 mode = GET_MODE (op2); 4112 4113 icode = movcc_gen_code[mode]; 4114 4115 if (icode == CODE_FOR_nothing) 4116 return 0; 4117 4118 if (flag_force_mem) 4119 { 4120 op2 = force_not_mem (op2); 4121 op3 = force_not_mem (op3); 4122 } 4123 4124 if (target) 4125 target = protect_from_queue (target, 1); 4126 else 4127 target = gen_reg_rtx (mode); 4128 4129 subtarget = target; 4130 4131 emit_queue (); 4132 4133 op2 = protect_from_queue (op2, 0); 4134 op3 = protect_from_queue (op3, 0); 4135 4136 /* If the insn doesn't accept these operands, put them in pseudos. */ 4137 4138 if (! (*insn_data[icode].operand[0].predicate) 4139 (subtarget, insn_data[icode].operand[0].mode)) 4140 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode); 4141 4142 if (! (*insn_data[icode].operand[2].predicate) 4143 (op2, insn_data[icode].operand[2].mode)) 4144 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2); 4145 4146 if (! (*insn_data[icode].operand[3].predicate) 4147 (op3, insn_data[icode].operand[3].mode)) 4148 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3); 4149 4150 /* Everything should now be in the suitable form, so emit the compare insn 4151 and then the conditional move. */ 4152 4153 comparison 4154 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX); 4155 4156 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */ 4157 /* We can get const0_rtx or const_true_rtx in some circumstances. Just 4158 return NULL and let the caller figure out how best to deal with this 4159 situation. */ 4160 if (GET_CODE (comparison) != code) 4161 return NULL_RTX; 4162 4163 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3); 4164 4165 /* If that failed, then give up. */ 4166 if (insn == 0) 4167 return 0; 4168 4169 emit_insn (insn); 4170 4171 if (subtarget != target) 4172 convert_move (target, subtarget, 0); 4173 4174 return target; 4175} 4176 4177/* Return nonzero if a conditional move of mode MODE is supported. 4178 4179 This function is for combine so it can tell whether an insn that looks 4180 like a conditional move is actually supported by the hardware. If we 4181 guess wrong we lose a bit on optimization, but that's it. */ 4182/* ??? sparc64 supports conditionally moving integers values based on fp 4183 comparisons, and vice versa. How do we handle them? */ 4184 4185int 4186can_conditionally_move_p (mode) 4187 enum machine_mode mode; 4188{ 4189 if (movcc_gen_code[mode] != CODE_FOR_nothing) 4190 return 1; 4191 4192 return 0; 4193} 4194 4195#endif /* HAVE_conditional_move */ 4196 4197/* These functions generate an insn body and return it 4198 rather than emitting the insn. 4199 4200 They do not protect from queued increments, 4201 because they may be used 1) in protect_from_queue itself 4202 and 2) in other passes where there is no queue. */ 4203 4204/* Generate and return an insn body to add Y to X. */ 4205 4206rtx 4207gen_add2_insn (x, y) 4208 rtx x, y; 4209{ 4210 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 4211 4212 if (! ((*insn_data[icode].operand[0].predicate) 4213 (x, insn_data[icode].operand[0].mode)) 4214 || ! ((*insn_data[icode].operand[1].predicate) 4215 (x, insn_data[icode].operand[1].mode)) 4216 || ! ((*insn_data[icode].operand[2].predicate) 4217 (y, insn_data[icode].operand[2].mode))) 4218 abort (); 4219 4220 return (GEN_FCN (icode) (x, x, y)); 4221} 4222 4223/* Generate and return an insn body to add r1 and c, 4224 storing the result in r0. */ 4225rtx 4226gen_add3_insn (r0, r1, c) 4227 rtx r0, r1, c; 4228{ 4229 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code; 4230 4231 if (icode == CODE_FOR_nothing 4232 || ! ((*insn_data[icode].operand[0].predicate) 4233 (r0, insn_data[icode].operand[0].mode)) 4234 || ! ((*insn_data[icode].operand[1].predicate) 4235 (r1, insn_data[icode].operand[1].mode)) 4236 || ! ((*insn_data[icode].operand[2].predicate) 4237 (c, insn_data[icode].operand[2].mode))) 4238 return NULL_RTX; 4239 4240 return (GEN_FCN (icode) (r0, r1, c)); 4241} 4242 4243int 4244have_add2_insn (x, y) 4245 rtx x, y; 4246{ 4247 int icode; 4248 4249 if (GET_MODE (x) == VOIDmode) 4250 abort (); 4251 4252 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 4253 4254 if (icode == CODE_FOR_nothing) 4255 return 0; 4256 4257 if (! ((*insn_data[icode].operand[0].predicate) 4258 (x, insn_data[icode].operand[0].mode)) 4259 || ! ((*insn_data[icode].operand[1].predicate) 4260 (x, insn_data[icode].operand[1].mode)) 4261 || ! ((*insn_data[icode].operand[2].predicate) 4262 (y, insn_data[icode].operand[2].mode))) 4263 return 0; 4264 4265 return 1; 4266} 4267 4268/* Generate and return an insn body to subtract Y from X. */ 4269 4270rtx 4271gen_sub2_insn (x, y) 4272 rtx x, y; 4273{ 4274 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 4275 4276 if (! ((*insn_data[icode].operand[0].predicate) 4277 (x, insn_data[icode].operand[0].mode)) 4278 || ! ((*insn_data[icode].operand[1].predicate) 4279 (x, insn_data[icode].operand[1].mode)) 4280 || ! ((*insn_data[icode].operand[2].predicate) 4281 (y, insn_data[icode].operand[2].mode))) 4282 abort (); 4283 4284 return (GEN_FCN (icode) (x, x, y)); 4285} 4286 4287/* Generate and return an insn body to subtract r1 and c, 4288 storing the result in r0. */ 4289rtx 4290gen_sub3_insn (r0, r1, c) 4291 rtx r0, r1, c; 4292{ 4293 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code; 4294 4295 if (icode == CODE_FOR_nothing 4296 || ! ((*insn_data[icode].operand[0].predicate) 4297 (r0, insn_data[icode].operand[0].mode)) 4298 || ! ((*insn_data[icode].operand[1].predicate) 4299 (r1, insn_data[icode].operand[1].mode)) 4300 || ! ((*insn_data[icode].operand[2].predicate) 4301 (c, insn_data[icode].operand[2].mode))) 4302 return NULL_RTX; 4303 4304 return (GEN_FCN (icode) (r0, r1, c)); 4305} 4306 4307int 4308have_sub2_insn (x, y) 4309 rtx x, y; 4310{ 4311 int icode; 4312 4313 if (GET_MODE (x) == VOIDmode) 4314 abort (); 4315 4316 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 4317 4318 if (icode == CODE_FOR_nothing) 4319 return 0; 4320 4321 if (! ((*insn_data[icode].operand[0].predicate) 4322 (x, insn_data[icode].operand[0].mode)) 4323 || ! ((*insn_data[icode].operand[1].predicate) 4324 (x, insn_data[icode].operand[1].mode)) 4325 || ! ((*insn_data[icode].operand[2].predicate) 4326 (y, insn_data[icode].operand[2].mode))) 4327 return 0; 4328 4329 return 1; 4330} 4331 4332/* Generate the body of an instruction to copy Y into X. 4333 It may be a list of insns, if one insn isn't enough. */ 4334 4335rtx 4336gen_move_insn (x, y) 4337 rtx x, y; 4338{ 4339 enum machine_mode mode = GET_MODE (x); 4340 enum insn_code insn_code; 4341 rtx seq; 4342 4343 if (mode == VOIDmode) 4344 mode = GET_MODE (y); 4345 4346 insn_code = mov_optab->handlers[(int) mode].insn_code; 4347 4348 /* Handle MODE_CC modes: If we don't have a special move insn for this mode, 4349 find a mode to do it in. If we have a movcc, use it. Otherwise, 4350 find the MODE_INT mode of the same width. */ 4351 4352 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing) 4353 { 4354 enum machine_mode tmode = VOIDmode; 4355 rtx x1 = x, y1 = y; 4356 4357 if (mode != CCmode 4358 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing) 4359 tmode = CCmode; 4360 else 4361 for (tmode = QImode; tmode != VOIDmode; 4362 tmode = GET_MODE_WIDER_MODE (tmode)) 4363 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode)) 4364 break; 4365 4366 if (tmode == VOIDmode) 4367 abort (); 4368 4369 /* Get X and Y in TMODE. We can't use gen_lowpart here because it 4370 may call change_address which is not appropriate if we were 4371 called when a reload was in progress. We don't have to worry 4372 about changing the address since the size in bytes is supposed to 4373 be the same. Copy the MEM to change the mode and move any 4374 substitutions from the old MEM to the new one. */ 4375 4376 if (reload_in_progress) 4377 { 4378 x = gen_lowpart_common (tmode, x1); 4379 if (x == 0 && GET_CODE (x1) == MEM) 4380 { 4381 x = adjust_address_nv (x1, tmode, 0); 4382 copy_replacements (x1, x); 4383 } 4384 4385 y = gen_lowpart_common (tmode, y1); 4386 if (y == 0 && GET_CODE (y1) == MEM) 4387 { 4388 y = adjust_address_nv (y1, tmode, 0); 4389 copy_replacements (y1, y); 4390 } 4391 } 4392 else 4393 { 4394 x = gen_lowpart (tmode, x); 4395 y = gen_lowpart (tmode, y); 4396 } 4397 4398 insn_code = mov_optab->handlers[(int) tmode].insn_code; 4399 return (GEN_FCN (insn_code) (x, y)); 4400 } 4401 4402 start_sequence (); 4403 emit_move_insn_1 (x, y); 4404 seq = get_insns (); 4405 end_sequence (); 4406 return seq; 4407} 4408 4409/* Return the insn code used to extend FROM_MODE to TO_MODE. 4410 UNSIGNEDP specifies zero-extension instead of sign-extension. If 4411 no such operation exists, CODE_FOR_nothing will be returned. */ 4412 4413enum insn_code 4414can_extend_p (to_mode, from_mode, unsignedp) 4415 enum machine_mode to_mode, from_mode; 4416 int unsignedp; 4417{ 4418#ifdef HAVE_ptr_extend 4419 if (unsignedp < 0) 4420 return CODE_FOR_ptr_extend; 4421 else 4422#endif 4423 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0]; 4424} 4425 4426/* Generate the body of an insn to extend Y (with mode MFROM) 4427 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ 4428 4429rtx 4430gen_extend_insn (x, y, mto, mfrom, unsignedp) 4431 rtx x, y; 4432 enum machine_mode mto, mfrom; 4433 int unsignedp; 4434{ 4435 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y)); 4436} 4437 4438/* can_fix_p and can_float_p say whether the target machine 4439 can directly convert a given fixed point type to 4440 a given floating point type, or vice versa. 4441 The returned value is the CODE_FOR_... value to use, 4442 or CODE_FOR_nothing if these modes cannot be directly converted. 4443 4444 *TRUNCP_PTR is set to 1 if it is necessary to output 4445 an explicit FTRUNC insn before the fix insn; otherwise 0. */ 4446 4447static enum insn_code 4448can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr) 4449 enum machine_mode fltmode, fixmode; 4450 int unsignedp; 4451 int *truncp_ptr; 4452{ 4453 *truncp_ptr = 0; 4454 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0] 4455 != CODE_FOR_nothing) 4456 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]; 4457 4458 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing) 4459 { 4460 *truncp_ptr = 1; 4461 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0]; 4462 } 4463 return CODE_FOR_nothing; 4464} 4465 4466static enum insn_code 4467can_float_p (fltmode, fixmode, unsignedp) 4468 enum machine_mode fixmode, fltmode; 4469 int unsignedp; 4470{ 4471 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0]; 4472} 4473 4474/* Generate code to convert FROM to floating point 4475 and store in TO. FROM must be fixed point and not VOIDmode. 4476 UNSIGNEDP nonzero means regard FROM as unsigned. 4477 Normally this is done by correcting the final value 4478 if it is negative. */ 4479 4480void 4481expand_float (to, from, unsignedp) 4482 rtx to, from; 4483 int unsignedp; 4484{ 4485 enum insn_code icode; 4486 rtx target = to; 4487 enum machine_mode fmode, imode; 4488 4489 /* Crash now, because we won't be able to decide which mode to use. */ 4490 if (GET_MODE (from) == VOIDmode) 4491 abort (); 4492 4493 /* Look for an insn to do the conversion. Do it in the specified 4494 modes if possible; otherwise convert either input, output or both to 4495 wider mode. If the integer mode is wider than the mode of FROM, 4496 we can do the conversion signed even if the input is unsigned. */ 4497 4498 for (fmode = GET_MODE (to); fmode != VOIDmode; 4499 fmode = GET_MODE_WIDER_MODE (fmode)) 4500 for (imode = GET_MODE (from); imode != VOIDmode; 4501 imode = GET_MODE_WIDER_MODE (imode)) 4502 { 4503 int doing_unsigned = unsignedp; 4504 4505 if (fmode != GET_MODE (to) 4506 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from))) 4507 continue; 4508 4509 icode = can_float_p (fmode, imode, unsignedp); 4510 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp) 4511 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0; 4512 4513 if (icode != CODE_FOR_nothing) 4514 { 4515 to = protect_from_queue (to, 1); 4516 from = protect_from_queue (from, 0); 4517 4518 if (imode != GET_MODE (from)) 4519 from = convert_to_mode (imode, from, unsignedp); 4520 4521 if (fmode != GET_MODE (to)) 4522 target = gen_reg_rtx (fmode); 4523 4524 emit_unop_insn (icode, target, from, 4525 doing_unsigned ? UNSIGNED_FLOAT : FLOAT); 4526 4527 if (target != to) 4528 convert_move (to, target, 0); 4529 return; 4530 } 4531 } 4532 4533 /* Unsigned integer, and no way to convert directly. 4534 Convert as signed, then conditionally adjust the result. */ 4535 if (unsignedp) 4536 { 4537 rtx label = gen_label_rtx (); 4538 rtx temp; 4539 REAL_VALUE_TYPE offset; 4540 4541 emit_queue (); 4542 4543 to = protect_from_queue (to, 1); 4544 from = protect_from_queue (from, 0); 4545 4546 if (flag_force_mem) 4547 from = force_not_mem (from); 4548 4549 /* Look for a usable floating mode FMODE wider than the source and at 4550 least as wide as the target. Using FMODE will avoid rounding woes 4551 with unsigned values greater than the signed maximum value. */ 4552 4553 for (fmode = GET_MODE (to); fmode != VOIDmode; 4554 fmode = GET_MODE_WIDER_MODE (fmode)) 4555 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode) 4556 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing) 4557 break; 4558 4559 if (fmode == VOIDmode) 4560 { 4561 /* There is no such mode. Pretend the target is wide enough. */ 4562 fmode = GET_MODE (to); 4563 4564 /* Avoid double-rounding when TO is narrower than FROM. */ 4565 if ((significand_size (fmode) + 1) 4566 < GET_MODE_BITSIZE (GET_MODE (from))) 4567 { 4568 rtx temp1; 4569 rtx neglabel = gen_label_rtx (); 4570 4571 /* Don't use TARGET if it isn't a register, is a hard register, 4572 or is the wrong mode. */ 4573 if (GET_CODE (target) != REG 4574 || REGNO (target) < FIRST_PSEUDO_REGISTER 4575 || GET_MODE (target) != fmode) 4576 target = gen_reg_rtx (fmode); 4577 4578 imode = GET_MODE (from); 4579 do_pending_stack_adjust (); 4580 4581 /* Test whether the sign bit is set. */ 4582 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode, 4583 0, neglabel); 4584 4585 /* The sign bit is not set. Convert as signed. */ 4586 expand_float (target, from, 0); 4587 emit_jump_insn (gen_jump (label)); 4588 emit_barrier (); 4589 4590 /* The sign bit is set. 4591 Convert to a usable (positive signed) value by shifting right 4592 one bit, while remembering if a nonzero bit was shifted 4593 out; i.e., compute (from & 1) | (from >> 1). */ 4594 4595 emit_label (neglabel); 4596 temp = expand_binop (imode, and_optab, from, const1_rtx, 4597 NULL_RTX, 1, OPTAB_LIB_WIDEN); 4598 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node, 4599 NULL_RTX, 1); 4600 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 4601 OPTAB_LIB_WIDEN); 4602 expand_float (target, temp, 0); 4603 4604 /* Multiply by 2 to undo the shift above. */ 4605 temp = expand_binop (fmode, add_optab, target, target, 4606 target, 0, OPTAB_LIB_WIDEN); 4607 if (temp != target) 4608 emit_move_insn (target, temp); 4609 4610 do_pending_stack_adjust (); 4611 emit_label (label); 4612 goto done; 4613 } 4614 } 4615 4616 /* If we are about to do some arithmetic to correct for an 4617 unsigned operand, do it in a pseudo-register. */ 4618 4619 if (GET_MODE (to) != fmode 4620 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER) 4621 target = gen_reg_rtx (fmode); 4622 4623 /* Convert as signed integer to floating. */ 4624 expand_float (target, from, 0); 4625 4626 /* If FROM is negative (and therefore TO is negative), 4627 correct its value by 2**bitwidth. */ 4628 4629 do_pending_stack_adjust (); 4630 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 4631 0, label); 4632 4633 4634 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from))); 4635 temp = expand_binop (fmode, add_optab, target, 4636 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode), 4637 target, 0, OPTAB_LIB_WIDEN); 4638 if (temp != target) 4639 emit_move_insn (target, temp); 4640 4641 do_pending_stack_adjust (); 4642 emit_label (label); 4643 goto done; 4644 } 4645 4646 /* No hardware instruction available; call a library routine to convert from 4647 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */ 4648 { 4649 rtx libfcn; 4650 rtx insns; 4651 rtx value; 4652 4653 to = protect_from_queue (to, 1); 4654 from = protect_from_queue (from, 0); 4655 4656 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode)) 4657 from = convert_to_mode (SImode, from, unsignedp); 4658 4659 if (flag_force_mem) 4660 from = force_not_mem (from); 4661 4662 if (GET_MODE (to) == SFmode) 4663 { 4664 if (GET_MODE (from) == SImode) 4665 libfcn = floatsisf_libfunc; 4666 else if (GET_MODE (from) == DImode) 4667 libfcn = floatdisf_libfunc; 4668 else if (GET_MODE (from) == TImode) 4669 libfcn = floattisf_libfunc; 4670 else 4671 abort (); 4672 } 4673 else if (GET_MODE (to) == DFmode) 4674 { 4675 if (GET_MODE (from) == SImode) 4676 libfcn = floatsidf_libfunc; 4677 else if (GET_MODE (from) == DImode) 4678 libfcn = floatdidf_libfunc; 4679 else if (GET_MODE (from) == TImode) 4680 libfcn = floattidf_libfunc; 4681 else 4682 abort (); 4683 } 4684 else if (GET_MODE (to) == XFmode) 4685 { 4686 if (GET_MODE (from) == SImode) 4687 libfcn = floatsixf_libfunc; 4688 else if (GET_MODE (from) == DImode) 4689 libfcn = floatdixf_libfunc; 4690 else if (GET_MODE (from) == TImode) 4691 libfcn = floattixf_libfunc; 4692 else 4693 abort (); 4694 } 4695 else if (GET_MODE (to) == TFmode) 4696 { 4697 if (GET_MODE (from) == SImode) 4698 libfcn = floatsitf_libfunc; 4699 else if (GET_MODE (from) == DImode) 4700 libfcn = floatditf_libfunc; 4701 else if (GET_MODE (from) == TImode) 4702 libfcn = floattitf_libfunc; 4703 else 4704 abort (); 4705 } 4706 else 4707 abort (); 4708 4709 start_sequence (); 4710 4711 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST, 4712 GET_MODE (to), 1, from, 4713 GET_MODE (from)); 4714 insns = get_insns (); 4715 end_sequence (); 4716 4717 emit_libcall_block (insns, target, value, 4718 gen_rtx_FLOAT (GET_MODE (to), from)); 4719 } 4720 4721 done: 4722 4723 /* Copy result to requested destination 4724 if we have been computing in a temp location. */ 4725 4726 if (target != to) 4727 { 4728 if (GET_MODE (target) == GET_MODE (to)) 4729 emit_move_insn (to, target); 4730 else 4731 convert_move (to, target, 0); 4732 } 4733} 4734 4735/* expand_fix: generate code to convert FROM to fixed point 4736 and store in TO. FROM must be floating point. */ 4737 4738static rtx 4739ftruncify (x) 4740 rtx x; 4741{ 4742 rtx temp = gen_reg_rtx (GET_MODE (x)); 4743 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0); 4744} 4745 4746void 4747expand_fix (to, from, unsignedp) 4748 rtx to, from; 4749 int unsignedp; 4750{ 4751 enum insn_code icode; 4752 rtx target = to; 4753 enum machine_mode fmode, imode; 4754 int must_trunc = 0; 4755 rtx libfcn = 0; 4756 4757 /* We first try to find a pair of modes, one real and one integer, at 4758 least as wide as FROM and TO, respectively, in which we can open-code 4759 this conversion. If the integer mode is wider than the mode of TO, 4760 we can do the conversion either signed or unsigned. */ 4761 4762 for (fmode = GET_MODE (from); fmode != VOIDmode; 4763 fmode = GET_MODE_WIDER_MODE (fmode)) 4764 for (imode = GET_MODE (to); imode != VOIDmode; 4765 imode = GET_MODE_WIDER_MODE (imode)) 4766 { 4767 int doing_unsigned = unsignedp; 4768 4769 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc); 4770 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp) 4771 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0; 4772 4773 if (icode != CODE_FOR_nothing) 4774 { 4775 to = protect_from_queue (to, 1); 4776 from = protect_from_queue (from, 0); 4777 4778 if (fmode != GET_MODE (from)) 4779 from = convert_to_mode (fmode, from, 0); 4780 4781 if (must_trunc) 4782 from = ftruncify (from); 4783 4784 if (imode != GET_MODE (to)) 4785 target = gen_reg_rtx (imode); 4786 4787 emit_unop_insn (icode, target, from, 4788 doing_unsigned ? UNSIGNED_FIX : FIX); 4789 if (target != to) 4790 convert_move (to, target, unsignedp); 4791 return; 4792 } 4793 } 4794 4795 /* For an unsigned conversion, there is one more way to do it. 4796 If we have a signed conversion, we generate code that compares 4797 the real value to the largest representable positive number. If if 4798 is smaller, the conversion is done normally. Otherwise, subtract 4799 one plus the highest signed number, convert, and add it back. 4800 4801 We only need to check all real modes, since we know we didn't find 4802 anything with a wider integer mode. */ 4803 4804 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT) 4805 for (fmode = GET_MODE (from); fmode != VOIDmode; 4806 fmode = GET_MODE_WIDER_MODE (fmode)) 4807 /* Make sure we won't lose significant bits doing this. */ 4808 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to)) 4809 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, 4810 &must_trunc)) 4811 { 4812 int bitsize; 4813 REAL_VALUE_TYPE offset; 4814 rtx limit, lab1, lab2, insn; 4815 4816 bitsize = GET_MODE_BITSIZE (GET_MODE (to)); 4817 real_2expN (&offset, bitsize - 1); 4818 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode); 4819 lab1 = gen_label_rtx (); 4820 lab2 = gen_label_rtx (); 4821 4822 emit_queue (); 4823 to = protect_from_queue (to, 1); 4824 from = protect_from_queue (from, 0); 4825 4826 if (flag_force_mem) 4827 from = force_not_mem (from); 4828 4829 if (fmode != GET_MODE (from)) 4830 from = convert_to_mode (fmode, from, 0); 4831 4832 /* See if we need to do the subtraction. */ 4833 do_pending_stack_adjust (); 4834 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from), 4835 0, lab1); 4836 4837 /* If not, do the signed "fix" and branch around fixup code. */ 4838 expand_fix (to, from, 0); 4839 emit_jump_insn (gen_jump (lab2)); 4840 emit_barrier (); 4841 4842 /* Otherwise, subtract 2**(N-1), convert to signed number, 4843 then add 2**(N-1). Do the addition using XOR since this 4844 will often generate better code. */ 4845 emit_label (lab1); 4846 target = expand_binop (GET_MODE (from), sub_optab, from, limit, 4847 NULL_RTX, 0, OPTAB_LIB_WIDEN); 4848 expand_fix (to, target, 0); 4849 target = expand_binop (GET_MODE (to), xor_optab, to, 4850 gen_int_mode 4851 ((HOST_WIDE_INT) 1 << (bitsize - 1), 4852 GET_MODE (to)), 4853 to, 1, OPTAB_LIB_WIDEN); 4854 4855 if (target != to) 4856 emit_move_insn (to, target); 4857 4858 emit_label (lab2); 4859 4860 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code 4861 != CODE_FOR_nothing) 4862 { 4863 /* Make a place for a REG_NOTE and add it. */ 4864 insn = emit_move_insn (to, to); 4865 set_unique_reg_note (insn, 4866 REG_EQUAL, 4867 gen_rtx_fmt_e (UNSIGNED_FIX, 4868 GET_MODE (to), 4869 copy_rtx (from))); 4870 } 4871 4872 return; 4873 } 4874 4875 /* We can't do it with an insn, so use a library call. But first ensure 4876 that the mode of TO is at least as wide as SImode, since those are the 4877 only library calls we know about. */ 4878 4879 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode)) 4880 { 4881 target = gen_reg_rtx (SImode); 4882 4883 expand_fix (target, from, unsignedp); 4884 } 4885 else if (GET_MODE (from) == SFmode) 4886 { 4887 if (GET_MODE (to) == SImode) 4888 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc; 4889 else if (GET_MODE (to) == DImode) 4890 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc; 4891 else if (GET_MODE (to) == TImode) 4892 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc; 4893 else 4894 abort (); 4895 } 4896 else if (GET_MODE (from) == DFmode) 4897 { 4898 if (GET_MODE (to) == SImode) 4899 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc; 4900 else if (GET_MODE (to) == DImode) 4901 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc; 4902 else if (GET_MODE (to) == TImode) 4903 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc; 4904 else 4905 abort (); 4906 } 4907 else if (GET_MODE (from) == XFmode) 4908 { 4909 if (GET_MODE (to) == SImode) 4910 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc; 4911 else if (GET_MODE (to) == DImode) 4912 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc; 4913 else if (GET_MODE (to) == TImode) 4914 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc; 4915 else 4916 abort (); 4917 } 4918 else if (GET_MODE (from) == TFmode) 4919 { 4920 if (GET_MODE (to) == SImode) 4921 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc; 4922 else if (GET_MODE (to) == DImode) 4923 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc; 4924 else if (GET_MODE (to) == TImode) 4925 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc; 4926 else 4927 abort (); 4928 } 4929 else 4930 abort (); 4931 4932 if (libfcn) 4933 { 4934 rtx insns; 4935 rtx value; 4936 4937 to = protect_from_queue (to, 1); 4938 from = protect_from_queue (from, 0); 4939 4940 if (flag_force_mem) 4941 from = force_not_mem (from); 4942 4943 start_sequence (); 4944 4945 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST, 4946 GET_MODE (to), 1, from, 4947 GET_MODE (from)); 4948 insns = get_insns (); 4949 end_sequence (); 4950 4951 emit_libcall_block (insns, target, value, 4952 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX, 4953 GET_MODE (to), from)); 4954 } 4955 4956 if (target != to) 4957 { 4958 if (GET_MODE (to) == GET_MODE (target)) 4959 emit_move_insn (to, target); 4960 else 4961 convert_move (to, target, 0); 4962 } 4963} 4964 4965/* Report whether we have an instruction to perform the operation 4966 specified by CODE on operands of mode MODE. */ 4967int 4968have_insn_for (code, mode) 4969 enum rtx_code code; 4970 enum machine_mode mode; 4971{ 4972 return (code_to_optab[(int) code] != 0 4973 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code 4974 != CODE_FOR_nothing)); 4975} 4976 4977/* Create a blank optab. */ 4978static optab 4979new_optab () 4980{ 4981 int i; 4982 optab op = (optab) ggc_alloc (sizeof (struct optab)); 4983 for (i = 0; i < NUM_MACHINE_MODES; i++) 4984 { 4985 op->handlers[i].insn_code = CODE_FOR_nothing; 4986 op->handlers[i].libfunc = 0; 4987 } 4988 4989 return op; 4990} 4991 4992/* Same, but fill in its code as CODE, and write it into the 4993 code_to_optab table. */ 4994static inline optab 4995init_optab (code) 4996 enum rtx_code code; 4997{ 4998 optab op = new_optab (); 4999 op->code = code; 5000 code_to_optab[(int) code] = op; 5001 return op; 5002} 5003 5004/* Same, but fill in its code as CODE, and do _not_ write it into 5005 the code_to_optab table. */ 5006static inline optab 5007init_optabv (code) 5008 enum rtx_code code; 5009{ 5010 optab op = new_optab (); 5011 op->code = code; 5012 return op; 5013} 5014 5015/* Initialize the libfunc fields of an entire group of entries in some 5016 optab. Each entry is set equal to a string consisting of a leading 5017 pair of underscores followed by a generic operation name followed by 5018 a mode name (downshifted to lower case) followed by a single character 5019 representing the number of operands for the given operation (which is 5020 usually one of the characters '2', '3', or '4'). 5021 5022 OPTABLE is the table in which libfunc fields are to be initialized. 5023 FIRST_MODE is the first machine mode index in the given optab to 5024 initialize. 5025 LAST_MODE is the last machine mode index in the given optab to 5026 initialize. 5027 OPNAME is the generic (string) name of the operation. 5028 SUFFIX is the character which specifies the number of operands for 5029 the given generic operation. 5030*/ 5031 5032static void 5033init_libfuncs (optable, first_mode, last_mode, opname, suffix) 5034 optab optable; 5035 int first_mode; 5036 int last_mode; 5037 const char *opname; 5038 int suffix; 5039{ 5040 int mode; 5041 unsigned opname_len = strlen (opname); 5042 5043 for (mode = first_mode; (int) mode <= (int) last_mode; 5044 mode = (enum machine_mode) ((int) mode + 1)) 5045 { 5046 const char *mname = GET_MODE_NAME (mode); 5047 unsigned mname_len = strlen (mname); 5048 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1); 5049 char *p; 5050 const char *q; 5051 5052 p = libfunc_name; 5053 *p++ = '_'; 5054 *p++ = '_'; 5055 for (q = opname; *q; ) 5056 *p++ = *q++; 5057 for (q = mname; *q; q++) 5058 *p++ = TOLOWER (*q); 5059 *p++ = suffix; 5060 *p = '\0'; 5061 5062 optable->handlers[(int) mode].libfunc 5063 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name, 5064 p - libfunc_name)); 5065 } 5066} 5067 5068/* Initialize the libfunc fields of an entire group of entries in some 5069 optab which correspond to all integer mode operations. The parameters 5070 have the same meaning as similarly named ones for the `init_libfuncs' 5071 routine. (See above). */ 5072 5073static void 5074init_integral_libfuncs (optable, opname, suffix) 5075 optab optable; 5076 const char *opname; 5077 int suffix; 5078{ 5079 init_libfuncs (optable, SImode, TImode, opname, suffix); 5080} 5081 5082/* Initialize the libfunc fields of an entire group of entries in some 5083 optab which correspond to all real mode operations. The parameters 5084 have the same meaning as similarly named ones for the `init_libfuncs' 5085 routine. (See above). */ 5086 5087static void 5088init_floating_libfuncs (optable, opname, suffix) 5089 optab optable; 5090 const char *opname; 5091 int suffix; 5092{ 5093 init_libfuncs (optable, SFmode, TFmode, opname, suffix); 5094} 5095 5096rtx 5097init_one_libfunc (name) 5098 const char *name; 5099{ 5100 /* Create a FUNCTION_DECL that can be passed to 5101 targetm.encode_section_info. */ 5102 /* ??? We don't have any type information except for this is 5103 a function. Pretend this is "int foo()". */ 5104 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), 5105 build_function_type (integer_type_node, NULL_TREE)); 5106 DECL_ARTIFICIAL (decl) = 1; 5107 DECL_EXTERNAL (decl) = 1; 5108 TREE_PUBLIC (decl) = 1; 5109 5110 /* Return the symbol_ref from the mem rtx. */ 5111 return XEXP (DECL_RTL (decl), 0); 5112} 5113 5114/* Call this once to initialize the contents of the optabs 5115 appropriately for the current target machine. */ 5116 5117void 5118init_optabs () 5119{ 5120 unsigned int i, j, k; 5121 5122 /* Start by initializing all tables to contain CODE_FOR_nothing. */ 5123 5124 for (i = 0; i < ARRAY_SIZE (fixtab); i++) 5125 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++) 5126 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++) 5127 fixtab[i][j][k] = CODE_FOR_nothing; 5128 5129 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++) 5130 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++) 5131 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++) 5132 fixtrunctab[i][j][k] = CODE_FOR_nothing; 5133 5134 for (i = 0; i < ARRAY_SIZE (floattab); i++) 5135 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++) 5136 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++) 5137 floattab[i][j][k] = CODE_FOR_nothing; 5138 5139 for (i = 0; i < ARRAY_SIZE (extendtab); i++) 5140 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++) 5141 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++) 5142 extendtab[i][j][k] = CODE_FOR_nothing; 5143 5144 for (i = 0; i < NUM_RTX_CODE; i++) 5145 setcc_gen_code[i] = CODE_FOR_nothing; 5146 5147#ifdef HAVE_conditional_move 5148 for (i = 0; i < NUM_MACHINE_MODES; i++) 5149 movcc_gen_code[i] = CODE_FOR_nothing; 5150#endif 5151 5152 add_optab = init_optab (PLUS); 5153 addv_optab = init_optabv (PLUS); 5154 sub_optab = init_optab (MINUS); 5155 subv_optab = init_optabv (MINUS); 5156 smul_optab = init_optab (MULT); 5157 smulv_optab = init_optabv (MULT); 5158 smul_highpart_optab = init_optab (UNKNOWN); 5159 umul_highpart_optab = init_optab (UNKNOWN); 5160 smul_widen_optab = init_optab (UNKNOWN); 5161 umul_widen_optab = init_optab (UNKNOWN); 5162 sdiv_optab = init_optab (DIV); 5163 sdivv_optab = init_optabv (DIV); 5164 sdivmod_optab = init_optab (UNKNOWN); 5165 udiv_optab = init_optab (UDIV); 5166 udivmod_optab = init_optab (UNKNOWN); 5167 smod_optab = init_optab (MOD); 5168 umod_optab = init_optab (UMOD); 5169 ftrunc_optab = init_optab (UNKNOWN); 5170 and_optab = init_optab (AND); 5171 ior_optab = init_optab (IOR); 5172 xor_optab = init_optab (XOR); 5173 ashl_optab = init_optab (ASHIFT); 5174 ashr_optab = init_optab (ASHIFTRT); 5175 lshr_optab = init_optab (LSHIFTRT); 5176 rotl_optab = init_optab (ROTATE); 5177 rotr_optab = init_optab (ROTATERT); 5178 smin_optab = init_optab (SMIN); 5179 smax_optab = init_optab (SMAX); 5180 umin_optab = init_optab (UMIN); 5181 umax_optab = init_optab (UMAX); 5182 5183 /* These three have codes assigned exclusively for the sake of 5184 have_insn_for. */ 5185 mov_optab = init_optab (SET); 5186 movstrict_optab = init_optab (STRICT_LOW_PART); 5187 cmp_optab = init_optab (COMPARE); 5188 5189 ucmp_optab = init_optab (UNKNOWN); 5190 tst_optab = init_optab (UNKNOWN); 5191 neg_optab = init_optab (NEG); 5192 negv_optab = init_optabv (NEG); 5193 abs_optab = init_optab (ABS); 5194 absv_optab = init_optabv (ABS); 5195 one_cmpl_optab = init_optab (NOT); 5196 ffs_optab = init_optab (FFS); 5197 sqrt_optab = init_optab (SQRT); 5198 sin_optab = init_optab (UNKNOWN); 5199 cos_optab = init_optab (UNKNOWN); 5200 exp_optab = init_optab (UNKNOWN); 5201 log_optab = init_optab (UNKNOWN); 5202 strlen_optab = init_optab (UNKNOWN); 5203 cbranch_optab = init_optab (UNKNOWN); 5204 cmov_optab = init_optab (UNKNOWN); 5205 cstore_optab = init_optab (UNKNOWN); 5206 push_optab = init_optab (UNKNOWN); 5207 5208 for (i = 0; i < NUM_MACHINE_MODES; i++) 5209 { 5210 movstr_optab[i] = CODE_FOR_nothing; 5211 clrstr_optab[i] = CODE_FOR_nothing; 5212 5213#ifdef HAVE_SECONDARY_RELOADS 5214 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing; 5215#endif 5216 } 5217 5218 /* Fill in the optabs with the insns we support. */ 5219 init_all_optabs (); 5220 5221#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC 5222 /* This flag says the same insns that convert to a signed fixnum 5223 also convert validly to an unsigned one. */ 5224 for (i = 0; i < NUM_MACHINE_MODES; i++) 5225 for (j = 0; j < NUM_MACHINE_MODES; j++) 5226 fixtrunctab[i][j][1] = fixtrunctab[i][j][0]; 5227#endif 5228 5229 /* Initialize the optabs with the names of the library functions. */ 5230 init_integral_libfuncs (add_optab, "add", '3'); 5231 init_floating_libfuncs (add_optab, "add", '3'); 5232 init_integral_libfuncs (addv_optab, "addv", '3'); 5233 init_floating_libfuncs (addv_optab, "add", '3'); 5234 init_integral_libfuncs (sub_optab, "sub", '3'); 5235 init_floating_libfuncs (sub_optab, "sub", '3'); 5236 init_integral_libfuncs (subv_optab, "subv", '3'); 5237 init_floating_libfuncs (subv_optab, "sub", '3'); 5238 init_integral_libfuncs (smul_optab, "mul", '3'); 5239 init_floating_libfuncs (smul_optab, "mul", '3'); 5240 init_integral_libfuncs (smulv_optab, "mulv", '3'); 5241 init_floating_libfuncs (smulv_optab, "mul", '3'); 5242 init_integral_libfuncs (sdiv_optab, "div", '3'); 5243 init_floating_libfuncs (sdiv_optab, "div", '3'); 5244 init_integral_libfuncs (sdivv_optab, "divv", '3'); 5245 init_integral_libfuncs (udiv_optab, "udiv", '3'); 5246 init_integral_libfuncs (sdivmod_optab, "divmod", '4'); 5247 init_integral_libfuncs (udivmod_optab, "udivmod", '4'); 5248 init_integral_libfuncs (smod_optab, "mod", '3'); 5249 init_integral_libfuncs (umod_optab, "umod", '3'); 5250 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2'); 5251 init_integral_libfuncs (and_optab, "and", '3'); 5252 init_integral_libfuncs (ior_optab, "ior", '3'); 5253 init_integral_libfuncs (xor_optab, "xor", '3'); 5254 init_integral_libfuncs (ashl_optab, "ashl", '3'); 5255 init_integral_libfuncs (ashr_optab, "ashr", '3'); 5256 init_integral_libfuncs (lshr_optab, "lshr", '3'); 5257 init_integral_libfuncs (smin_optab, "min", '3'); 5258 init_floating_libfuncs (smin_optab, "min", '3'); 5259 init_integral_libfuncs (smax_optab, "max", '3'); 5260 init_floating_libfuncs (smax_optab, "max", '3'); 5261 init_integral_libfuncs (umin_optab, "umin", '3'); 5262 init_integral_libfuncs (umax_optab, "umax", '3'); 5263 init_integral_libfuncs (neg_optab, "neg", '2'); 5264 init_floating_libfuncs (neg_optab, "neg", '2'); 5265 init_integral_libfuncs (negv_optab, "negv", '2'); 5266 init_floating_libfuncs (negv_optab, "neg", '2'); 5267 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2'); 5268 init_integral_libfuncs (ffs_optab, "ffs", '2'); 5269 5270 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */ 5271 init_integral_libfuncs (cmp_optab, "cmp", '2'); 5272 init_integral_libfuncs (ucmp_optab, "ucmp", '2'); 5273 init_floating_libfuncs (cmp_optab, "cmp", '2'); 5274 5275#ifdef MULSI3_LIBCALL 5276 smul_optab->handlers[(int) SImode].libfunc 5277 = init_one_libfunc (MULSI3_LIBCALL); 5278#endif 5279#ifdef MULDI3_LIBCALL 5280 smul_optab->handlers[(int) DImode].libfunc 5281 = init_one_libfunc (MULDI3_LIBCALL); 5282#endif 5283 5284#ifdef DIVSI3_LIBCALL 5285 sdiv_optab->handlers[(int) SImode].libfunc 5286 = init_one_libfunc (DIVSI3_LIBCALL); 5287#endif 5288#ifdef DIVDI3_LIBCALL 5289 sdiv_optab->handlers[(int) DImode].libfunc 5290 = init_one_libfunc (DIVDI3_LIBCALL); 5291#endif 5292 5293#ifdef UDIVSI3_LIBCALL 5294 udiv_optab->handlers[(int) SImode].libfunc 5295 = init_one_libfunc (UDIVSI3_LIBCALL); 5296#endif 5297#ifdef UDIVDI3_LIBCALL 5298 udiv_optab->handlers[(int) DImode].libfunc 5299 = init_one_libfunc (UDIVDI3_LIBCALL); 5300#endif 5301 5302#ifdef MODSI3_LIBCALL 5303 smod_optab->handlers[(int) SImode].libfunc 5304 = init_one_libfunc (MODSI3_LIBCALL); 5305#endif 5306#ifdef MODDI3_LIBCALL 5307 smod_optab->handlers[(int) DImode].libfunc 5308 = init_one_libfunc (MODDI3_LIBCALL); 5309#endif 5310 5311#ifdef UMODSI3_LIBCALL 5312 umod_optab->handlers[(int) SImode].libfunc 5313 = init_one_libfunc (UMODSI3_LIBCALL); 5314#endif 5315#ifdef UMODDI3_LIBCALL 5316 umod_optab->handlers[(int) DImode].libfunc 5317 = init_one_libfunc (UMODDI3_LIBCALL); 5318#endif 5319 5320 /* Use cabs for DC complex abs, since systems generally have cabs. 5321 Don't define any libcall for SCmode, so that cabs will be used. */ 5322 abs_optab->handlers[(int) DCmode].libfunc 5323 = init_one_libfunc ("cabs"); 5324 5325 /* The ffs function operates on `int'. */ 5326 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc 5327 = init_one_libfunc ("ffs"); 5328 5329 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2"); 5330 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2"); 5331 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2"); 5332 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2"); 5333 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2"); 5334 5335 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2"); 5336 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2"); 5337 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2"); 5338 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2"); 5339 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2"); 5340 5341 abort_libfunc = init_one_libfunc ("abort"); 5342 memcpy_libfunc = init_one_libfunc ("memcpy"); 5343 memmove_libfunc = init_one_libfunc ("memmove"); 5344 bcopy_libfunc = init_one_libfunc ("bcopy"); 5345 memcmp_libfunc = init_one_libfunc ("memcmp"); 5346 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp"); 5347 memset_libfunc = init_one_libfunc ("memset"); 5348 bzero_libfunc = init_one_libfunc ("bzero"); 5349 5350 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS 5351 ? "_Unwind_SjLj_Resume" 5352 : "_Unwind_Resume"); 5353#ifndef DONT_USE_BUILTIN_SETJMP 5354 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp"); 5355 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp"); 5356#else 5357 setjmp_libfunc = init_one_libfunc ("setjmp"); 5358 longjmp_libfunc = init_one_libfunc ("longjmp"); 5359#endif 5360 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register"); 5361 unwind_sjlj_unregister_libfunc 5362 = init_one_libfunc ("_Unwind_SjLj_Unregister"); 5363 5364 eqhf2_libfunc = init_one_libfunc ("__eqhf2"); 5365 nehf2_libfunc = init_one_libfunc ("__nehf2"); 5366 gthf2_libfunc = init_one_libfunc ("__gthf2"); 5367 gehf2_libfunc = init_one_libfunc ("__gehf2"); 5368 lthf2_libfunc = init_one_libfunc ("__lthf2"); 5369 lehf2_libfunc = init_one_libfunc ("__lehf2"); 5370 unordhf2_libfunc = init_one_libfunc ("__unordhf2"); 5371 5372 eqsf2_libfunc = init_one_libfunc ("__eqsf2"); 5373 nesf2_libfunc = init_one_libfunc ("__nesf2"); 5374 gtsf2_libfunc = init_one_libfunc ("__gtsf2"); 5375 gesf2_libfunc = init_one_libfunc ("__gesf2"); 5376 ltsf2_libfunc = init_one_libfunc ("__ltsf2"); 5377 lesf2_libfunc = init_one_libfunc ("__lesf2"); 5378 unordsf2_libfunc = init_one_libfunc ("__unordsf2"); 5379 5380 eqdf2_libfunc = init_one_libfunc ("__eqdf2"); 5381 nedf2_libfunc = init_one_libfunc ("__nedf2"); 5382 gtdf2_libfunc = init_one_libfunc ("__gtdf2"); 5383 gedf2_libfunc = init_one_libfunc ("__gedf2"); 5384 ltdf2_libfunc = init_one_libfunc ("__ltdf2"); 5385 ledf2_libfunc = init_one_libfunc ("__ledf2"); 5386 unorddf2_libfunc = init_one_libfunc ("__unorddf2"); 5387 5388 eqxf2_libfunc = init_one_libfunc ("__eqxf2"); 5389 nexf2_libfunc = init_one_libfunc ("__nexf2"); 5390 gtxf2_libfunc = init_one_libfunc ("__gtxf2"); 5391 gexf2_libfunc = init_one_libfunc ("__gexf2"); 5392 ltxf2_libfunc = init_one_libfunc ("__ltxf2"); 5393 lexf2_libfunc = init_one_libfunc ("__lexf2"); 5394 unordxf2_libfunc = init_one_libfunc ("__unordxf2"); 5395 5396 eqtf2_libfunc = init_one_libfunc ("__eqtf2"); 5397 netf2_libfunc = init_one_libfunc ("__netf2"); 5398 gttf2_libfunc = init_one_libfunc ("__gttf2"); 5399 getf2_libfunc = init_one_libfunc ("__getf2"); 5400 lttf2_libfunc = init_one_libfunc ("__lttf2"); 5401 letf2_libfunc = init_one_libfunc ("__letf2"); 5402 unordtf2_libfunc = init_one_libfunc ("__unordtf2"); 5403 5404 floatsisf_libfunc = init_one_libfunc ("__floatsisf"); 5405 floatdisf_libfunc = init_one_libfunc ("__floatdisf"); 5406 floattisf_libfunc = init_one_libfunc ("__floattisf"); 5407 5408 floatsidf_libfunc = init_one_libfunc ("__floatsidf"); 5409 floatdidf_libfunc = init_one_libfunc ("__floatdidf"); 5410 floattidf_libfunc = init_one_libfunc ("__floattidf"); 5411 5412 floatsixf_libfunc = init_one_libfunc ("__floatsixf"); 5413 floatdixf_libfunc = init_one_libfunc ("__floatdixf"); 5414 floattixf_libfunc = init_one_libfunc ("__floattixf"); 5415 5416 floatsitf_libfunc = init_one_libfunc ("__floatsitf"); 5417 floatditf_libfunc = init_one_libfunc ("__floatditf"); 5418 floattitf_libfunc = init_one_libfunc ("__floattitf"); 5419 5420 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi"); 5421 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi"); 5422 fixsfti_libfunc = init_one_libfunc ("__fixsfti"); 5423 5424 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi"); 5425 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi"); 5426 fixdfti_libfunc = init_one_libfunc ("__fixdfti"); 5427 5428 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi"); 5429 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi"); 5430 fixxfti_libfunc = init_one_libfunc ("__fixxfti"); 5431 5432 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi"); 5433 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi"); 5434 fixtfti_libfunc = init_one_libfunc ("__fixtfti"); 5435 5436 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi"); 5437 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi"); 5438 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti"); 5439 5440 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi"); 5441 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi"); 5442 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti"); 5443 5444 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi"); 5445 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi"); 5446 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti"); 5447 5448 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi"); 5449 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi"); 5450 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti"); 5451 5452 /* For function entry/exit instrumentation. */ 5453 profile_function_entry_libfunc 5454 = init_one_libfunc ("__cyg_profile_func_enter"); 5455 profile_function_exit_libfunc 5456 = init_one_libfunc ("__cyg_profile_func_exit"); 5457 5458 if (HAVE_conditional_trap) 5459 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX); 5460 5461#ifdef INIT_TARGET_OPTABS 5462 /* Allow the target to add more libcalls or rename some, etc. */ 5463 INIT_TARGET_OPTABS; 5464#endif 5465} 5466 5467/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition 5468 CODE. Return 0 on failure. */ 5469 5470rtx 5471gen_cond_trap (code, op1, op2, tcode) 5472 enum rtx_code code ATTRIBUTE_UNUSED; 5473 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED; 5474{ 5475 enum machine_mode mode = GET_MODE (op1); 5476 enum insn_code icode; 5477 rtx insn; 5478 5479 if (!HAVE_conditional_trap) 5480 return 0; 5481 5482 if (mode == VOIDmode) 5483 return 0; 5484 5485 icode = cmp_optab->handlers[(int) mode].insn_code; 5486 if (icode == CODE_FOR_nothing) 5487 return 0; 5488 5489 start_sequence (); 5490 op1 = prepare_operand (icode, op1, 0, mode, mode, 0); 5491 op2 = prepare_operand (icode, op2, 1, mode, mode, 0); 5492 if (!op1 || !op2) 5493 { 5494 end_sequence (); 5495 return 0; 5496 } 5497 emit_insn (GEN_FCN (icode) (op1, op2)); 5498 5499 PUT_CODE (trap_rtx, code); 5500 insn = gen_conditional_trap (trap_rtx, tcode); 5501 if (insn) 5502 { 5503 emit_insn (insn); 5504 insn = get_insns (); 5505 } 5506 end_sequence (); 5507 5508 return insn; 5509} 5510 5511#include "gt-optabs.h" 5512