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