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