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