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