|
|
1.1 ! root 1: /* Expand the basic unary and binary arithmetic operations, for GNU compiler. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 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: ! 32: /* Each optab contains info on how this target machine ! 33: can perform a particular operation ! 34: for all sizes and kinds of operands. ! 35: ! 36: The operation to be performed is often specified ! 37: by passing one of these optabs as an argument. ! 38: ! 39: See expr.h for documentation of these optabs. */ ! 40: ! 41: optab add_optab; ! 42: optab sub_optab; ! 43: optab smul_optab; ! 44: optab umul_optab; ! 45: optab smul_widen_optab; ! 46: optab umul_widen_optab; ! 47: optab sdiv_optab; ! 48: optab sdivmod_optab; ! 49: optab udiv_optab; ! 50: optab udivmod_optab; ! 51: optab smod_optab; ! 52: optab umod_optab; ! 53: optab flodiv_optab; ! 54: optab ftrunc_optab; ! 55: optab and_optab; ! 56: optab andcb_optab; ! 57: optab ior_optab; ! 58: optab xor_optab; ! 59: optab ashl_optab; ! 60: optab lshr_optab; ! 61: optab lshl_optab; ! 62: optab ashr_optab; ! 63: optab rotl_optab; ! 64: optab rotr_optab; ! 65: ! 66: optab mov_optab; ! 67: optab movstrict_optab; ! 68: ! 69: optab neg_optab; ! 70: optab abs_optab; ! 71: optab one_cmpl_optab; ! 72: optab ffs_optab; ! 73: ! 74: optab cmp_optab; ! 75: optab tst_optab; ! 76: ! 77: /* Generate code to perform an operation specified by BINOPTAB ! 78: on operands OP0 and OP1, with result having machine-mode MODE. ! 79: ! 80: UNSIGNEDP is for the case where we have to widen the operands ! 81: to perform the operation. It says to use zero-extension. ! 82: ! 83: If TARGET is nonzero, the value ! 84: is generated there, if it is convenient to do so. ! 85: In all cases an rtx is returned for the locus of the value; ! 86: this may or may not be TARGET. */ ! 87: ! 88: rtx ! 89: expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) ! 90: enum machine_mode mode; ! 91: optab binoptab; ! 92: rtx op0, op1; ! 93: rtx target; ! 94: int unsignedp; ! 95: enum optab_methods methods; ! 96: { ! 97: register rtx temp; ! 98: int target_is_not_an_operand = 0; ! 99: rtx last = get_last_insn (); ! 100: ! 101: op0 = protect_from_queue (op0, 0); ! 102: op1 = protect_from_queue (op1, 0); ! 103: if (target) ! 104: target = protect_from_queue (target, 1); ! 105: ! 106: /* We may get better code by generating the result in a register ! 107: when the target is not one of the operands. */ ! 108: if (target && ! rtx_equal_p (target, op1) && ! rtx_equal_p (target, op0)) ! 109: target_is_not_an_operand = 1; ! 110: ! 111: if (flag_force_mem) ! 112: { ! 113: op0 = force_not_mem (op0); ! 114: op1 = force_not_mem (op1); ! 115: } ! 116: ! 117: /* If operation is commutative, ! 118: try to make the first operand a register. ! 119: Even better, try to make it the same as the target. ! 120: Also try to make the last operand a constant. */ ! 121: if (binoptab == add_optab ! 122: || binoptab == and_optab ! 123: || binoptab == ior_optab ! 124: || binoptab == xor_optab ! 125: || binoptab == smul_optab ! 126: || binoptab == umul_optab ! 127: || binoptab == smul_widen_optab ! 128: || binoptab == umul_widen_optab) ! 129: { ! 130: if (((target == 0 || GET_CODE (target) == REG) ! 131: ? ((GET_CODE (op1) == REG ! 132: && GET_CODE (op0) != REG) ! 133: || target == op1) ! 134: : rtx_equal_p (op1, target)) ! 135: || ! 136: GET_CODE (op0) == CONST_INT) ! 137: { ! 138: temp = op1; ! 139: op1 = op0; ! 140: op0 = temp; ! 141: } ! 142: } ! 143: ! 144: /* If we can do it with a three-operand insn, do so. */ ! 145: ! 146: if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 147: { ! 148: int icode = (int) binoptab->handlers[(int) mode].insn_code; ! 149: enum machine_mode mode0 = insn_operand_mode[icode][1]; ! 150: enum machine_mode mode1 = insn_operand_mode[icode][2]; ! 151: rtx pat; ! 152: rtx xop0 = op0, xop1 = op1; ! 153: ! 154: if (target) ! 155: temp = target; ! 156: else ! 157: temp = gen_reg_rtx (mode); ! 158: ! 159: /* In case the insn wants input operands in modes different from ! 160: the result, convert the operands. */ ! 161: ! 162: if (GET_MODE (op0) != VOIDmode ! 163: && GET_MODE (op0) != mode0) ! 164: xop0 = convert_to_mode (mode0, xop0, unsignedp); ! 165: ! 166: if (GET_MODE (xop1) != VOIDmode ! 167: && GET_MODE (xop1) != mode1) ! 168: xop1 = convert_to_mode (mode1, xop1, unsignedp); ! 169: ! 170: /* Now, if insn requires register operands, put operands into regs. */ ! 171: ! 172: if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)) ! 173: xop0 = force_reg (mode0, xop0); ! 174: ! 175: if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)) ! 176: xop1 = force_reg (mode1, xop1); ! 177: ! 178: if (! (*insn_operand_predicate[icode][0]) (temp, mode)) ! 179: temp = gen_reg_rtx (mode); ! 180: ! 181: pat = GEN_FCN (icode) (temp, xop0, xop1); ! 182: if (pat) ! 183: { ! 184: emit_insn (pat); ! 185: return temp; ! 186: } ! 187: else ! 188: delete_insns_since (last); ! 189: } ! 190: ! 191: /* It can't be open-coded in this mode. ! 192: Use a library call if one is available and caller says that's ok. */ ! 193: ! 194: if (binoptab->handlers[(int) mode].lib_call ! 195: && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN)) ! 196: { ! 197: rtx insn_before; ! 198: rtx funexp = gen_rtx (SYMBOL_REF, Pmode, ! 199: binoptab->handlers[(int) mode].lib_call); ! 200: ! 201: /* Pass the address through a pseudoreg, if desired, ! 202: before the "beginning" of the library call (for deletion). */ ! 203: #ifndef NO_FUNCTION_CSE ! 204: if (! flag_no_function_cse) ! 205: funexp = copy_to_mode_reg (Pmode, funexp); ! 206: #endif ! 207: insn_before = get_last_insn (); ! 208: ! 209: /* Cannot pass FUNEXP since emit_library_call insists ! 210: on getting a SYMBOL_REF. But cse will make this SYMBOL_REF ! 211: be replaced with the copy we made just above. */ ! 212: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 213: binoptab->handlers[(int) mode].lib_call), ! 214: mode, 2, op0, mode, op1, mode); ! 215: target = hard_libcall_value (mode); ! 216: temp = copy_to_reg (target); ! 217: REG_NOTES (get_last_insn ()) ! 218: = gen_rtx (EXPR_LIST, REG_EQUAL, ! 219: gen_rtx (binoptab->code, mode, op0, op1), ! 220: gen_rtx (INSN_LIST, REG_RETVAL, ! 221: NEXT_INSN (insn_before), 0)); ! 222: return temp; ! 223: } ! 224: ! 225: /* It can't be done in this mode. Can we do it in a wider mode? */ ! 226: ! 227: if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN)) ! 228: return 0; /* Caller says, don't even try. */ ! 229: ! 230: /* Compute the value of METHODS to pass to recursive calls. ! 231: Don't allow widening to be tried recursively. */ ! 232: ! 233: methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT); ! 234: ! 235: if ((mode == HImode || mode == QImode) ! 236: && (binoptab->handlers[(int) SImode].insn_code != CODE_FOR_nothing ! 237: || (methods == OPTAB_LIB ! 238: && binoptab->handlers[(int) SImode].lib_call))) ! 239: { ! 240: rtx xop0 = op0, xop1 = op1; ! 241: ! 242: if (GET_MODE (xop0) != VOIDmode) ! 243: { ! 244: temp = gen_reg_rtx (SImode); ! 245: convert_move (temp, xop0, unsignedp); ! 246: xop0 = temp; ! 247: } ! 248: if (GET_MODE (xop1) != VOIDmode) ! 249: { ! 250: temp = gen_reg_rtx (SImode); ! 251: convert_move (temp, xop1, unsignedp); ! 252: xop1 = temp; ! 253: } ! 254: ! 255: temp = expand_binop (SImode, binoptab, xop0, xop1, 0, ! 256: unsignedp, methods); ! 257: if (temp) ! 258: return gen_lowpart (mode, temp); ! 259: else ! 260: delete_insns_since (last); ! 261: } ! 262: if ((mode == HImode || mode == QImode || mode == SImode) ! 263: && (binoptab->handlers[(int) DImode].insn_code != CODE_FOR_nothing ! 264: || (methods == OPTAB_LIB ! 265: && binoptab->handlers[(int) DImode].lib_call))) ! 266: { ! 267: rtx xop0 = op0, xop1 = op1; ! 268: ! 269: temp = gen_reg_rtx (DImode); ! 270: convert_move (temp, xop0, unsignedp); ! 271: xop0 = temp; ! 272: temp = gen_reg_rtx (DImode); ! 273: convert_move (temp, xop1, unsignedp); ! 274: xop1 = temp; ! 275: ! 276: temp = expand_binop (DImode, binoptab, xop0, xop1, 0, ! 277: unsignedp, methods); ! 278: if (temp) ! 279: return gen_lowpart (mode, temp); ! 280: else ! 281: delete_insns_since (last); ! 282: } ! 283: if (mode == SFmode ! 284: && (binoptab->handlers[(int) DFmode].insn_code != CODE_FOR_nothing ! 285: || (methods == OPTAB_LIB ! 286: && binoptab->handlers[(int) DFmode].lib_call))) ! 287: { ! 288: rtx xop0 = op0, xop1 = op1; ! 289: ! 290: temp = gen_reg_rtx (DFmode); ! 291: convert_move (temp, xop0, 0); ! 292: xop0 = temp; ! 293: temp = gen_reg_rtx (DFmode); ! 294: convert_move (temp, xop1, 0); ! 295: xop1 = temp; ! 296: ! 297: temp = expand_binop (DFmode, binoptab, xop0, xop1, 0, 0, methods); ! 298: if (temp) ! 299: { ! 300: if (target == 0) ! 301: target = gen_reg_rtx (SFmode); ! 302: convert_move (target, temp, 0); ! 303: return target; ! 304: } ! 305: else ! 306: delete_insns_since (last); ! 307: } ! 308: return 0; ! 309: } ! 310: ! 311: /* Generate code to perform an operation specified by BINOPTAB ! 312: on operands OP0 and OP1, with two results to TARG1 and TARG2. ! 313: We assume that the order of the operands for the instruction ! 314: is TARG0, OP0, OP1, TARG1, which would fit a pattern like ! 315: [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))]. ! 316: ! 317: Either TARG0 or TARG1 may be zero, but what that means is that ! 318: that result is not actually wanted. We will generate it into ! 319: a dummy pseudo-reg and discard it. They may not both be zero. ! 320: ! 321: Returns 1 if this operation can be performed; 0 if not. */ ! 322: ! 323: int ! 324: expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp) ! 325: optab binoptab; ! 326: rtx op0, op1; ! 327: rtx targ0, targ1; ! 328: int unsignedp; ! 329: { ! 330: enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1); ! 331: ! 332: op0 = protect_from_queue (op0, 0); ! 333: op1 = protect_from_queue (op1, 0); ! 334: ! 335: if (flag_force_mem) ! 336: { ! 337: op0 = force_not_mem (op0); ! 338: op1 = force_not_mem (op1); ! 339: } ! 340: ! 341: if (targ0) ! 342: targ0 = protect_from_queue (targ0, 1); ! 343: else ! 344: targ0 = gen_reg_rtx (mode); ! 345: if (targ1) ! 346: targ1 = protect_from_queue (targ1, 1); ! 347: else ! 348: targ1 = gen_reg_rtx (mode); ! 349: ! 350: if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 351: { ! 352: emit_insn (GEN_FCN (binoptab->handlers[(int) mode].insn_code) ! 353: (targ0, op0, op1, targ1)); ! 354: return 1; ! 355: } ! 356: ! 357: /* It can't be done in this mode. Can we do it in a wider mode? */ ! 358: ! 359: if ((mode == HImode || mode == QImode) ! 360: && binoptab->handlers[(int) SImode].insn_code != CODE_FOR_nothing) ! 361: { ! 362: expand_twoval_binop_convert (binoptab, SImode, op0, op1, ! 363: targ0, targ1, unsignedp); ! 364: return 1; ! 365: } ! 366: if ((mode == HImode || mode == QImode || mode == SImode) ! 367: && binoptab->handlers[(int) DImode].insn_code != CODE_FOR_nothing) ! 368: { ! 369: expand_twoval_binop_convert (binoptab, DImode, op0, op1, ! 370: targ0, targ1, unsignedp); ! 371: return 1; ! 372: } ! 373: if (mode == SFmode ! 374: && binoptab->handlers[(int) DFmode].insn_code != CODE_FOR_nothing) ! 375: { ! 376: expand_twoval_binop_convert (binoptab, DFmode, op0, op1, ! 377: targ0, targ1, unsignedp); ! 378: return 1; ! 379: } ! 380: return 0; ! 381: } ! 382: ! 383: int ! 384: expand_twoval_binop_convert (binoptab, mode, op0, op1, targ0, targ1, unsignedp) ! 385: register optab binoptab; ! 386: register rtx op0, op1, targ0, targ1; ! 387: int unsignedp; ! 388: { ! 389: register rtx t0 = gen_reg_rtx (SImode); ! 390: register rtx t1 = gen_reg_rtx (SImode); ! 391: register rtx temp; ! 392: ! 393: temp = gen_reg_rtx (SImode); ! 394: convert_move (temp, op0, unsignedp); ! 395: op0 = temp; ! 396: temp = gen_reg_rtx (SImode); ! 397: convert_move (temp, op1, unsignedp); ! 398: op1 = temp; ! 399: ! 400: expand_twoval_binop (binoptab, op0, op1, t0, t1, unsignedp); ! 401: convert_move (targ0, t0, unsignedp); ! 402: convert_move (targ1, t1, unsignedp); ! 403: return 1; ! 404: } ! 405: ! 406: /* Generate code to perform an operation specified by UNOPTAB ! 407: on operand OP0, with result having machine-mode MODE. ! 408: ! 409: UNSIGNEDP is for the case where we have to widen the operands ! 410: to perform the operation. It says to use zero-extension. ! 411: ! 412: If TARGET is nonzero, the value ! 413: is generated there, if it is convenient to do so. ! 414: In all cases an rtx is returned for the locus of the value; ! 415: this may or may not be TARGET. */ ! 416: ! 417: rtx ! 418: expand_unop (mode, unoptab, op0, target, unsignedp) ! 419: enum machine_mode mode; ! 420: optab unoptab; ! 421: rtx op0; ! 422: rtx target; ! 423: int unsignedp; ! 424: { ! 425: register rtx temp; ! 426: ! 427: op0 = protect_from_queue (op0, 0); ! 428: ! 429: if (flag_force_mem) ! 430: { ! 431: op0 = force_not_mem (op0); ! 432: } ! 433: ! 434: if (target) ! 435: target = protect_from_queue (target, 1); ! 436: ! 437: if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 438: { ! 439: int icode = (int) unoptab->handlers[(int) mode].insn_code; ! 440: enum machine_mode mode0 = insn_operand_mode[icode][1]; ! 441: ! 442: if (target) ! 443: temp = target; ! 444: else ! 445: temp = gen_reg_rtx (mode); ! 446: ! 447: if (GET_MODE (op0) != VOIDmode ! 448: && GET_MODE (op0) != mode0) ! 449: op0 = convert_to_mode (mode0, op0, unsignedp); ! 450: ! 451: /* Now, if insn requires register operands, put operands into regs. */ ! 452: ! 453: if (! (*insn_operand_predicate[icode][1]) (op0, mode0)) ! 454: op0 = force_reg (mode0, op0); ! 455: ! 456: if (! (*insn_operand_predicate[icode][0]) (temp, mode)) ! 457: temp = gen_reg_rtx (mode); ! 458: ! 459: emit_insn (GEN_FCN (icode) (temp, op0)); ! 460: return temp; ! 461: } ! 462: else if (unoptab->handlers[(int) mode].lib_call) ! 463: { ! 464: rtx insn_before; ! 465: rtx funexp = gen_rtx (SYMBOL_REF, Pmode, ! 466: unoptab->handlers[(int) mode].lib_call); ! 467: ! 468: /* Pass the address through a pseudoreg, if desired, ! 469: before the "beginning" of the library call (for deletion). */ ! 470: #ifndef NO_FUNCTION_CSE ! 471: if (! flag_no_function_cse) ! 472: funexp = copy_to_mode_reg (Pmode, funexp); ! 473: #endif ! 474: insn_before = get_last_insn (); ! 475: ! 476: /* Cannot pass FUNEXP since emit_library_call insists ! 477: on getting a SYMBOL_REF. But cse will make this SYMBOL_REF ! 478: be replaced with the copy we made just above. */ ! 479: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 480: unoptab->handlers[(int) mode].lib_call), ! 481: mode, 1, op0, mode); ! 482: target = hard_libcall_value (mode); ! 483: temp = copy_to_reg (target); ! 484: REG_NOTES (get_last_insn ()) ! 485: = gen_rtx (EXPR_LIST, REG_EQUAL, ! 486: gen_rtx (unoptab->code, mode, op0), ! 487: gen_rtx (INSN_LIST, REG_RETVAL, ! 488: NEXT_INSN (insn_before), 0)); ! 489: return temp; ! 490: } ! 491: ! 492: /* It can't be done in this mode. Can we do it in a wider mode? */ ! 493: ! 494: if ((mode == HImode || mode == QImode) ! 495: && (unoptab->handlers[(int) SImode].insn_code != CODE_FOR_nothing ! 496: || unoptab->handlers[(int) SImode].lib_call)) ! 497: { ! 498: if (GET_MODE (op0) != VOIDmode) ! 499: { ! 500: temp = gen_reg_rtx (SImode); ! 501: convert_move (temp, op0, unsignedp); ! 502: op0 = temp; ! 503: } ! 504: ! 505: target = expand_unop (SImode, unoptab, op0, 0, unsignedp); ! 506: return gen_lowpart (mode, target); ! 507: } ! 508: if ((mode == HImode || mode == QImode || mode == SImode) ! 509: && (unoptab->handlers[(int) DImode].insn_code != CODE_FOR_nothing ! 510: || unoptab->handlers[(int) DImode].lib_call)) ! 511: { ! 512: temp = gen_reg_rtx (DImode); ! 513: convert_move (temp, op0, unsignedp); ! 514: op0 = temp; ! 515: ! 516: target = expand_unop (DImode, unoptab, op0, 0, unsignedp); ! 517: return gen_lowpart (mode, target); ! 518: } ! 519: if (mode == SFmode ! 520: && (unoptab->handlers[(int) DFmode].insn_code != CODE_FOR_nothing ! 521: || unoptab->handlers[(int) DFmode].lib_call)) ! 522: { ! 523: temp = gen_reg_rtx (DFmode); ! 524: convert_move (temp, op0, 0); ! 525: op0 = temp; ! 526: ! 527: temp = expand_unop (DFmode, unoptab, op0, 0, 0); ! 528: if (target == 0) ! 529: target = gen_reg_rtx (SFmode); ! 530: convert_move (target, temp, 0); ! 531: return target; ! 532: } ! 533: ! 534: return 0; ! 535: } ! 536: ! 537: /* Generate an instruction whose insn-code is INSN_CODE, ! 538: with two operands: an output TARGET and an input OP0. ! 539: TARGET *must* be nonzero, and the output is always stored there. ! 540: CODE is an rtx code such that (CODE OP0) is an rtx that describes ! 541: the value that is stored into TARGET. */ ! 542: ! 543: void ! 544: emit_unop_insn (icode, target, op0, code) ! 545: int icode; ! 546: rtx target; ! 547: rtx op0; ! 548: enum rtx_code code; ! 549: { ! 550: register rtx temp; ! 551: enum machine_mode mode0 = insn_operand_mode[icode][1]; ! 552: rtx insn; ! 553: rtx prev_insn = get_last_insn (); ! 554: ! 555: temp = target = protect_from_queue (target, 1); ! 556: ! 557: op0 = protect_from_queue (op0, 0); ! 558: ! 559: if (flag_force_mem) ! 560: op0 = force_not_mem (op0); ! 561: ! 562: /* Now, if insn requires register operands, put operands into regs. */ ! 563: ! 564: if (! (*insn_operand_predicate[icode][1]) (op0, mode0)) ! 565: op0 = force_reg (mode0, op0); ! 566: ! 567: if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp)) ! 568: || (flag_force_mem && GET_CODE (temp) == MEM)) ! 569: temp = gen_reg_rtx (GET_MODE (temp)); ! 570: ! 571: insn = emit_insn (GEN_FCN (icode) (temp, op0)); ! 572: ! 573: /* If we just made a multi-insn sequence, ! 574: record in the last insn an equivalent expression for its value ! 575: and a pointer to the first insn. This makes cse possible. */ ! 576: if (code != UNKNOWN && insn != NEXT_INSN (prev_insn)) ! 577: REG_NOTES (insn) ! 578: = gen_rtx (EXPR_LIST, REG_EQUAL, ! 579: gen_rtx (code, GET_MODE (temp), op0), ! 580: 0); ! 581: ! 582: if (temp != target) ! 583: emit_move_insn (target, temp); ! 584: } ! 585: ! 586: /* Generate code to store zero in X. */ ! 587: ! 588: void ! 589: emit_clr_insn (x) ! 590: rtx x; ! 591: { ! 592: emit_move_insn (x, const0_rtx); ! 593: } ! 594: ! 595: /* Generate code to store 1 in X ! 596: assuming it contains zero beforehand. */ ! 597: ! 598: void ! 599: emit_0_to_1_insn (x) ! 600: rtx x; ! 601: { ! 602: emit_move_insn (x, const1_rtx); ! 603: } ! 604: ! 605: /* Generate code to compare X with Y ! 606: so that the condition codes are set. ! 607: If they have mode BLKmode, then SIZE specifies the size of block. */ ! 608: ! 609: void ! 610: emit_cmp_insn (x, y, size, unsignedp) ! 611: rtx x, y; ! 612: rtx size; ! 613: int unsignedp; ! 614: { ! 615: enum machine_mode mode = GET_MODE (x); ! 616: if (mode == VOIDmode) mode = GET_MODE (y); ! 617: /* They could both be VOIDmode if both args are immediate constants, ! 618: but we should fold that at an earlier stage. ! 619: With no special code here, this will call abort, ! 620: reminding the programmer to implement such folding. */ ! 621: ! 622: emit_queue (); ! 623: x = protect_from_queue (x, 0); ! 624: y = protect_from_queue (y, 0); ! 625: ! 626: if (mode != BLKmode && flag_force_mem) ! 627: { ! 628: x = force_not_mem (x); ! 629: y = force_not_mem (y); ! 630: } ! 631: ! 632: if (mode == BLKmode) ! 633: { ! 634: if (size == 0) ! 635: abort (); ! 636: #ifdef HAVE_cmpstrqi ! 637: if (HAVE_cmpstrqi ! 638: && GET_CODE (size) == CONST_INT ! 639: && INTVAL (size) < (1 << BITS_PER_UNIT)) ! 640: emit_insn (gen_cmpstrqi (x, y, convert_to_mode (SImode, size, 1))); ! 641: else ! 642: #endif ! 643: #ifdef HAVE_cmpstrsi ! 644: if (HAVE_cmpstrsi) ! 645: emit_insn (gen_cmpstrsi (x, y, convert_to_mode (SImode, size, 1))); ! 646: else ! 647: #endif ! 648: { ! 649: #ifdef TARGET_MEM_FUNCTIONS ! 650: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcmp"), ! 651: SImode, 3, x, Pmode, y, Pmode, size, Pmode); ! 652: #else ! 653: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcmp"), ! 654: SImode, 3, x, Pmode, y, Pmode, size, Pmode); ! 655: #endif ! 656: emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, 0, 0); ! 657: } ! 658: } ! 659: else if ((y == const0_rtx || y == fconst0_rtx || y == dconst0_rtx) ! 660: && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 661: { ! 662: int icode = (int) tst_optab->handlers[(int) mode].insn_code; ! 663: ! 664: /* Now, if insn requires register operands, put operands into regs. */ ! 665: if (! (*insn_operand_predicate[icode][0]) ! 666: (x, insn_operand_mode[icode][0])) ! 667: x = force_reg (insn_operand_mode[icode][0], x); ! 668: ! 669: emit_insn (GEN_FCN (icode) (x)); ! 670: } ! 671: else if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 672: { ! 673: int icode = (int) cmp_optab->handlers[(int) mode].insn_code; ! 674: ! 675: /* Now, if insn requires register operands, put operands into regs. */ ! 676: if (! (*insn_operand_predicate[icode][0]) ! 677: (x, insn_operand_mode[icode][0])) ! 678: x = force_reg (insn_operand_mode[icode][0], x); ! 679: ! 680: if (! (*insn_operand_predicate[icode][1]) ! 681: (y, insn_operand_mode[icode][1])) ! 682: y = force_reg (insn_operand_mode[icode][1], y); ! 683: ! 684: emit_insn (GEN_FCN (icode) (x, y)); ! 685: } ! 686: else if ((mode == QImode || mode == HImode) ! 687: && cmp_optab->handlers[(int) SImode].insn_code != CODE_FOR_nothing) ! 688: { ! 689: x = convert_to_mode (SImode, x, unsignedp); ! 690: y = convert_to_mode (SImode, y, unsignedp); ! 691: emit_cmp_insn (x, y, 0, unsignedp); ! 692: } ! 693: else if ((mode == QImode || mode == HImode || mode == SImode) ! 694: && cmp_optab->handlers[(int) DImode].insn_code != CODE_FOR_nothing) ! 695: { ! 696: x = convert_to_mode (DImode, x, unsignedp); ! 697: y = convert_to_mode (DImode, y, unsignedp); ! 698: emit_cmp_insn (x, y, 0, unsignedp); ! 699: } ! 700: else if (mode == SFmode ! 701: && cmp_optab->handlers[(int) DFmode].insn_code != CODE_FOR_nothing) ! 702: { ! 703: x = convert_to_mode (DFmode, x, unsignedp); ! 704: y = convert_to_mode (DFmode, y, unsignedp); ! 705: emit_cmp_insn (x, y, 0, unsignedp); ! 706: } ! 707: else if (cmp_optab->handlers[(int) mode].lib_call) ! 708: { ! 709: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 710: cmp_optab->handlers[(int) mode].lib_call), ! 711: SImode, 2, x, mode, y, mode); ! 712: emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, 0, 0); ! 713: } ! 714: else if ((mode == QImode || mode == HImode) ! 715: && (cmp_optab->handlers[(int) SImode].insn_code != CODE_FOR_nothing ! 716: || cmp_optab->handlers[(int) SImode].lib_call != 0)) ! 717: { ! 718: x = convert_to_mode (SImode, x, unsignedp); ! 719: y = convert_to_mode (SImode, y, unsignedp); ! 720: emit_cmp_insn (x, y, 0, unsignedp); ! 721: } ! 722: else if ((mode == QImode || mode == HImode || mode == SImode) ! 723: && (cmp_optab->handlers[(int) DImode].insn_code != CODE_FOR_nothing ! 724: || cmp_optab->handlers[(int) DImode].lib_call != 0)) ! 725: { ! 726: x = convert_to_mode (DImode, x, unsignedp); ! 727: y = convert_to_mode (DImode, y, unsignedp); ! 728: emit_cmp_insn (x, y, 0, unsignedp); ! 729: } ! 730: else if (mode == SFmode ! 731: && (cmp_optab->handlers[(int) DFmode].insn_code != CODE_FOR_nothing ! 732: || cmp_optab->handlers[(int) DFmode].lib_call != 0)) ! 733: { ! 734: x = convert_to_mode (DFmode, x, unsignedp); ! 735: y = convert_to_mode (DFmode, y, unsignedp); ! 736: emit_cmp_insn (x, y, 0, unsignedp); ! 737: } ! 738: else ! 739: abort (); ! 740: } ! 741: ! 742: /* These three functions generate an insn body and return it ! 743: rather than emitting the insn. ! 744: ! 745: They do not protect from queued increments, ! 746: because they may be used 1) in protect_from_queue itself ! 747: and 2) in other passes where there is no queue. */ ! 748: ! 749: /* Generate and return an insn body to add Y to X. */ ! 750: ! 751: rtx ! 752: gen_add2_insn (x, y) ! 753: rtx x, y; ! 754: { ! 755: return (GEN_FCN (add_optab->handlers[(int) GET_MODE (x)].insn_code) ! 756: (x, x, y)); ! 757: } ! 758: ! 759: int ! 760: have_add2_insn (mode) ! 761: enum machine_mode mode; ! 762: { ! 763: return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing; ! 764: } ! 765: ! 766: /* Generate and return an insn body to subtract Y from X. */ ! 767: ! 768: rtx ! 769: gen_sub2_insn (x, y) ! 770: rtx x, y; ! 771: { ! 772: return (GEN_FCN (sub_optab->handlers[(int) GET_MODE (x)].insn_code) ! 773: (x, x, y)); ! 774: } ! 775: ! 776: int ! 777: have_sub2_insn (mode) ! 778: enum machine_mode mode; ! 779: { ! 780: return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing; ! 781: } ! 782: ! 783: /* Generate the body of an instruction to copy Y into X. */ ! 784: ! 785: rtx ! 786: gen_move_insn (x, y) ! 787: rtx x, y; ! 788: { ! 789: register enum machine_mode mode = GET_MODE (x); ! 790: if (mode == VOIDmode) ! 791: mode = GET_MODE (y); ! 792: return (GEN_FCN (mov_optab->handlers[(int) mode].insn_code) (x, y)); ! 793: } ! 794: ! 795: /* Tables of patterns for extending one integer mode to another. */ ! 796: enum insn_code zero_extend_optab[MAX_MACHINE_MODE][MAX_MACHINE_MODE]; ! 797: enum insn_code sign_extend_optab[MAX_MACHINE_MODE][MAX_MACHINE_MODE]; ! 798: ! 799: /* Generate the body of an insn to extend Y (with mode MFROM) ! 800: into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ ! 801: ! 802: rtx ! 803: gen_extend_insn (x, y, mto, mfrom, unsignedp) ! 804: rtx x, y; ! 805: enum machine_mode mto, mfrom; ! 806: int unsignedp; ! 807: { ! 808: return (GEN_FCN ((unsignedp ? zero_extend_optab : sign_extend_optab) ! 809: [(int)mto][(int)mfrom]) ! 810: (x, y)); ! 811: } ! 812: ! 813: static void ! 814: init_extends () ! 815: { ! 816: int i; ! 817: bzero (sign_extend_optab, sizeof sign_extend_optab); ! 818: bzero (zero_extend_optab, sizeof zero_extend_optab); ! 819: sign_extend_optab[(int) SImode][(int) HImode] = CODE_FOR_extendhisi2; ! 820: sign_extend_optab[(int) SImode][(int) QImode] = CODE_FOR_extendqisi2; ! 821: sign_extend_optab[(int) HImode][(int) QImode] = CODE_FOR_extendqihi2; ! 822: zero_extend_optab[(int) SImode][(int) HImode] = CODE_FOR_zero_extendhisi2; ! 823: zero_extend_optab[(int) SImode][(int) QImode] = CODE_FOR_zero_extendqisi2; ! 824: zero_extend_optab[(int) HImode][(int) QImode] = CODE_FOR_zero_extendqihi2; ! 825: } ! 826: ! 827: /* can_fix_p and can_float_p say whether the target machine ! 828: can directly convert a given fixed point type to ! 829: a given floating point type, or vice versa. */ ! 830: ! 831: static rtxfun fixtab[2][2][2]; ! 832: static rtxfun fixtrunctab[2][2][2]; ! 833: static rtxfun floattab[2][2]; ! 834: ! 835: /* *TRUNCP_PTR is set to 1 if it is necessary to output ! 836: an explicit FTRUNC insn before the fix insn; otherwise 0. */ ! 837: ! 838: rtxfun ! 839: can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr) ! 840: enum machine_mode fltmode, fixmode; ! 841: int unsignedp; ! 842: int *truncp_ptr; ! 843: { ! 844: *truncp_ptr = 0; ! 845: if (fixtrunctab[fltmode != SFmode][fixmode == DImode][unsignedp]) ! 846: return fixtrunctab[fltmode != SFmode][fixmode == DImode][unsignedp]; ! 847: if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing) ! 848: { ! 849: *truncp_ptr = 1; ! 850: return fixtab[fltmode != SFmode][fixmode == DImode][unsignedp]; ! 851: } ! 852: return 0; ! 853: } ! 854: ! 855: rtxfun ! 856: can_float_p (fltmode, fixmode) ! 857: enum machine_mode fixmode, fltmode; ! 858: { ! 859: return floattab[fltmode != SFmode][fixmode == DImode]; ! 860: } ! 861: ! 862: void ! 863: init_fixtab () ! 864: { ! 865: #ifdef HAVE_fixsfsi2 ! 866: if (HAVE_fixsfsi2) ! 867: fixtab[0][0][0] = gen_fixsfsi2; ! 868: #endif ! 869: #ifdef HAVE_fixsfdi2 ! 870: if (HAVE_fixsfdi2) ! 871: fixtab[0][1][0] = gen_fixsfdi2; ! 872: #endif ! 873: #ifdef HAVE_fixdfsi2 ! 874: if (HAVE_fixdfsi2) ! 875: fixtab[1][0][0] = gen_fixdfsi2; ! 876: #endif ! 877: #ifdef HAVE_fixdfdi2 ! 878: if (HAVE_fixdfdi2) ! 879: fixtab[1][1][0] = gen_fixdfdi2; ! 880: #endif ! 881: ! 882: #ifdef HAVE_fixunssfsi2 ! 883: if (HAVE_fixunssfsi2) ! 884: fixtab[0][0][1] = gen_fixunssfsi2; ! 885: #endif ! 886: #ifdef HAVE_fixunssfdi2 ! 887: if (HAVE_fixunssfdi2) ! 888: fixtab[0][1][1] = gen_fixunssfdi2; ! 889: #endif ! 890: #ifdef HAVE_fixunsdfsi2 ! 891: if (HAVE_fixunsdfsi2) ! 892: fixtab[1][0][1] = gen_fixunsdfsi2; ! 893: #endif ! 894: #ifdef HAVE_fixunsdfdi2 ! 895: if (HAVE_fixunsdfdi2) ! 896: fixtab[1][1][1] = gen_fixunsdfdi2; ! 897: #endif ! 898: ! 899: #ifdef HAVE_fix_truncsfsi2 ! 900: if (HAVE_fix_truncsfsi2) ! 901: fixtrunctab[0][0][0] = gen_fix_truncsfsi2; ! 902: #endif ! 903: #ifdef HAVE_fix_truncsfdi2 ! 904: if (HAVE_fix_truncsfdi2) ! 905: fixtrunctab[0][1][0] = gen_fix_truncsfdi2; ! 906: #endif ! 907: #ifdef HAVE_fix_truncdfsi2 ! 908: if (HAVE_fix_truncdfsi2) ! 909: fixtrunctab[1][0][0] = gen_fix_truncdfsi2; ! 910: #endif ! 911: #ifdef HAVE_fix_truncdfdi2 ! 912: if (HAVE_fix_truncdfdi2) ! 913: fixtrunctab[1][1][0] = gen_fix_truncdfdi2; ! 914: #endif ! 915: ! 916: #ifdef HAVE_fixuns_truncsfsi2 ! 917: if (HAVE_fixuns_truncsfsi2) ! 918: fixtrunctab[0][0][1] = gen_fixuns_truncsfsi2; ! 919: #endif ! 920: #ifdef HAVE_fixuns_truncsfdi2 ! 921: if (HAVE_fixuns_truncsfdi2) ! 922: fixtrunctab[0][1][1] = gen_fixuns_truncsfdi2; ! 923: #endif ! 924: #ifdef HAVE_fixuns_truncdfsi2 ! 925: if (HAVE_fixuns_truncdfsi2) ! 926: fixtrunctab[1][0][1] = gen_fixuns_truncdfsi2; ! 927: #endif ! 928: #ifdef HAVE_fixuns_truncdfdi2 ! 929: if (HAVE_fixuns_truncdfdi2) ! 930: fixtrunctab[1][1][1] = gen_fixuns_truncdfdi2; ! 931: #endif ! 932: ! 933: #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC ! 934: /* This flag says the same insns that convert to a signed fixnum ! 935: also convert validly to an unsigned one. */ ! 936: { ! 937: int i; ! 938: int j; ! 939: for (i = 0; i < 2; i++) ! 940: for (j = 0; j < 2; j++) ! 941: fixtrunctab[i][j][1] = fixtrunctab[i][j][0]; ! 942: } ! 943: #endif ! 944: } ! 945: ! 946: void ! 947: init_floattab () ! 948: { ! 949: #ifdef HAVE_floatsisf2 ! 950: if (HAVE_floatsisf2) ! 951: floattab[0][0] = gen_floatsisf2; ! 952: #endif ! 953: #ifdef HAVE_floatdisf2 ! 954: if (HAVE_floatdisf2) ! 955: floattab[0][1] = gen_floatdisf2; ! 956: #endif ! 957: #ifdef HAVE_floatsidf2 ! 958: if (HAVE_floatsidf2) ! 959: floattab[1][0] = gen_floatsidf2; ! 960: #endif ! 961: #ifdef HAVE_floatdidf2 ! 962: if (HAVE_floatdidf2) ! 963: floattab[1][1] = gen_floatdidf2; ! 964: #endif ! 965: } ! 966: ! 967: /* Generate code to convert FROM to floating point ! 968: and store in TO. FROM must be fixed point. ! 969: UNSIGNEDP nonzero means regard FROM as unsigned. ! 970: Normally this is done by correcting the final value ! 971: if it is negative. */ ! 972: ! 973: void ! 974: expand_float (real_to, from, unsignedp) ! 975: rtx real_to, from; ! 976: int unsignedp; ! 977: { ! 978: register rtxfun fun; ! 979: register rtx intermediate = 0, to; ! 980: ! 981: to = real_to = protect_from_queue (real_to, 1); ! 982: from = protect_from_queue (from, 0); ! 983: ! 984: if (flag_force_mem) ! 985: { ! 986: from = force_not_mem (from); ! 987: } ! 988: ! 989: /* If we are about to do some arithmetic to correct for an ! 990: unsigned operand, do it in a register. */ ! 991: ! 992: if (unsignedp && GET_CODE (to) != REG) ! 993: to = gen_reg_rtx (GET_MODE (to)); ! 994: ! 995: /* Now do the basic conversion. Do it in the specified modes if possible; ! 996: otherwise convert either input, output or both with wider mode; ! 997: otherwise use a library call. */ ! 998: ! 999: if (fun = can_float_p (GET_MODE (to), GET_MODE (from))) ! 1000: { ! 1001: emit_insn ((*fun) (to, from)); ! 1002: } ! 1003: else if (GET_MODE (to) == SFmode ! 1004: && (fun = can_float_p (GET_MODE (from), DFmode))) ! 1005: { ! 1006: to = gen_reg_rtx (DFmode); ! 1007: emit_insn ((*fun) (to, from)); ! 1008: } ! 1009: /* If we can't float a SI, maybe we can float a DI. ! 1010: If so, convert to DI and then float. */ ! 1011: else if (GET_MODE (from) != DImode ! 1012: && (can_float_p (GET_MODE (to), DImode) ! 1013: || can_float_p (DFmode, DImode))) ! 1014: { ! 1015: register rtx tem = gen_reg_rtx (DImode); ! 1016: convert_move (tem, from, unsignedp); ! 1017: from = tem; ! 1018: /* If we extend FROM then we don't need to correct ! 1019: the final value for unsignedness. */ ! 1020: unsignedp = 0; ! 1021: ! 1022: if (fun = can_float_p (GET_MODE (to), GET_MODE (from))) ! 1023: { ! 1024: emit_insn ((*fun) (to, from)); ! 1025: } ! 1026: else if (fun = can_float_p (DFmode, DImode)) ! 1027: { ! 1028: to = gen_reg_rtx (DFmode); ! 1029: emit_insn ((*fun) (to, from)); ! 1030: } ! 1031: } ! 1032: /* No hardware instruction available; call a library ! 1033: to convert from SImode or DImode into DFmode. */ ! 1034: else ! 1035: { ! 1036: if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode)) ! 1037: { ! 1038: from = convert_to_mode (SImode, from, unsignedp); ! 1039: unsignedp = 0; ! 1040: } ! 1041: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 1042: (GET_MODE (from) == SImode ? "_floatsidf" ! 1043: : "_floatdidf")), ! 1044: DFmode, 1, from, GET_MODE (from)); ! 1045: to = copy_to_reg (hard_libcall_value (DFmode)); ! 1046: } ! 1047: ! 1048: /* If FROM was unsigned but we treated it as signed, ! 1049: then in the case where it is negative (and therefore TO is negative), ! 1050: correct its value by 2**bitwidth. */ ! 1051: ! 1052: if (unsignedp) ! 1053: { ! 1054: rtx label = gen_label_rtx (); ! 1055: rtx temp; ! 1056: double offset; ! 1057: double ldexp (); ! 1058: ! 1059: do_pending_stack_adjust (); ! 1060: emit_cmp_insn (to, GET_MODE (to) == DFmode ? dconst0_rtx : fconst0_rtx, ! 1061: 0, 0); ! 1062: emit_jump_insn (gen_bge (label)); ! 1063: offset = ldexp (1.0, GET_MODE_BITSIZE (GET_MODE (from))); ! 1064: temp = expand_binop (GET_MODE (to), add_optab, to, ! 1065: immed_real_const_1 (offset, GET_MODE (to)), ! 1066: to, 0, OPTAB_LIB_WIDEN); ! 1067: if (temp != to) ! 1068: emit_move_insn (to, temp); ! 1069: do_pending_stack_adjust (); ! 1070: emit_label (label); ! 1071: } ! 1072: ! 1073: /* Copy result to requested destination ! 1074: if we have been computing in a temp location. */ ! 1075: ! 1076: if (to != real_to) ! 1077: { ! 1078: if (GET_MODE (real_to) == GET_MODE (to)) ! 1079: emit_move_insn (real_to, to); ! 1080: else ! 1081: convert_move (real_to, to, 0); ! 1082: } ! 1083: } ! 1084: ! 1085: /* expand_fix: generate code to convert FROM to fixed point ! 1086: and store in TO. FROM must be floating point. */ ! 1087: ! 1088: static rtx ! 1089: ftruncify (x) ! 1090: rtx x; ! 1091: { ! 1092: rtx temp = gen_reg_rtx (GET_MODE (x)); ! 1093: return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0); ! 1094: } ! 1095: ! 1096: void ! 1097: expand_fix (to, from, unsignedp) ! 1098: register rtx to, from; ! 1099: int unsignedp; ! 1100: { ! 1101: register rtxfun fun; ! 1102: register rtx target; ! 1103: int must_trunc = 0; ! 1104: ! 1105: to = protect_from_queue (to, 1); ! 1106: from = protect_from_queue (from, 0); ! 1107: ! 1108: if (flag_force_mem) ! 1109: { ! 1110: from = force_not_mem (from); ! 1111: } ! 1112: ! 1113: if (fun = can_fix_p (GET_MODE (to), GET_MODE (from), unsignedp, &must_trunc)) ! 1114: { ! 1115: if (must_trunc) ! 1116: from = ftruncify (from); ! 1117: emit_insn ((*fun) (to, from)); ! 1118: return; ! 1119: } ! 1120: ! 1121: if (GET_MODE (to) != DImode ! 1122: && (fun = can_fix_p (DImode, GET_MODE (from), unsignedp, &must_trunc))) ! 1123: { ! 1124: register rtx temp = gen_reg_rtx (DImode); ! 1125: if (must_trunc) ! 1126: from = ftruncify (from); ! 1127: emit_insn ((*fun) (temp, from)); ! 1128: convert_move (to, temp, unsignedp); ! 1129: return; ! 1130: } ! 1131: ! 1132: if (GET_MODE (from) != DFmode) ! 1133: { ! 1134: register rtx tem = gen_reg_rtx (DFmode); ! 1135: convert_move (tem, from, 0); ! 1136: from = tem; ! 1137: } ! 1138: ! 1139: if (fun = can_fix_p (GET_MODE (to), GET_MODE (from), unsignedp, &must_trunc)) ! 1140: { ! 1141: if (must_trunc) ! 1142: from = ftruncify (from); ! 1143: emit_insn ((*fun) (to, from)); ! 1144: return; ! 1145: } ! 1146: ! 1147: if (fun = can_fix_p (DImode, DFmode, unsignedp, &must_trunc)) ! 1148: { ! 1149: if (must_trunc) ! 1150: from = ftruncify (from); ! 1151: target = gen_reg_rtx (DImode); ! 1152: emit_insn ((*fun) (target, from)); ! 1153: } ! 1154: else if (GET_MODE (to) != DImode) ! 1155: { ! 1156: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 1157: unsignedp ? "_fixunsdfsi" ! 1158: : "_fixdfsi"), ! 1159: SImode, 1, from, DFmode); ! 1160: target = copy_to_reg (hard_libcall_value (SImode)); ! 1161: } ! 1162: else ! 1163: { ! 1164: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, ! 1165: unsignedp ? "_fixunsdfdi" ! 1166: : "_fixdfdi"), ! 1167: DImode, 1, from, DFmode); ! 1168: target = copy_to_reg (hard_libcall_value (DImode)); ! 1169: } ! 1170: ! 1171: if (GET_MODE (to) == DImode) ! 1172: emit_move_insn (to, target); ! 1173: else ! 1174: convert_move (to, target, 0); ! 1175: } ! 1176: ! 1177: static optab ! 1178: init_optab (code) ! 1179: enum rtx_code code; ! 1180: { ! 1181: int i; ! 1182: optab op = (optab) malloc (sizeof (struct optab)); ! 1183: op->code = code; ! 1184: for (i = 0; i < NUM_MACHINE_MODES; i++) ! 1185: { ! 1186: op->handlers[i].insn_code = CODE_FOR_nothing; ! 1187: op->handlers[i].lib_call = 0; ! 1188: } ! 1189: return op; ! 1190: } ! 1191: ! 1192: /* Call this once to initialize the contents of the optabs ! 1193: appropriately for the current target machine. */ ! 1194: ! 1195: void ! 1196: init_optabs () ! 1197: { ! 1198: init_fixtab (); ! 1199: init_floattab (); ! 1200: init_comparisons (); ! 1201: init_extends (); ! 1202: ! 1203: add_optab = init_optab (PLUS); ! 1204: sub_optab = init_optab (MINUS); ! 1205: smul_optab = init_optab (MULT); ! 1206: umul_optab = init_optab (UMULT); ! 1207: smul_widen_optab = init_optab (MULT); ! 1208: umul_widen_optab = init_optab (UMULT); ! 1209: sdiv_optab = init_optab (DIV); ! 1210: sdivmod_optab = init_optab (UNKNOWN); ! 1211: udiv_optab = init_optab (UDIV); ! 1212: udivmod_optab = init_optab (UNKNOWN); ! 1213: smod_optab = init_optab (MOD); ! 1214: umod_optab = init_optab (UMOD); ! 1215: flodiv_optab = init_optab (DIV); ! 1216: ftrunc_optab = init_optab (UNKNOWN); ! 1217: and_optab = init_optab (AND); ! 1218: andcb_optab = init_optab (UNKNOWN); ! 1219: ior_optab = init_optab (IOR); ! 1220: xor_optab = init_optab (XOR); ! 1221: ashl_optab = init_optab (ASHIFT); ! 1222: ashr_optab = init_optab (ASHIFTRT); ! 1223: lshl_optab = init_optab (LSHIFT); ! 1224: lshr_optab = init_optab (LSHIFTRT); ! 1225: rotl_optab = init_optab (ROTATE); ! 1226: rotr_optab = init_optab (ROTATERT); ! 1227: mov_optab = init_optab (UNKNOWN); ! 1228: movstrict_optab = init_optab (UNKNOWN); ! 1229: cmp_optab = init_optab (UNKNOWN); ! 1230: tst_optab = init_optab (UNKNOWN); ! 1231: neg_optab = init_optab (NEG); ! 1232: abs_optab = init_optab (ABS); ! 1233: one_cmpl_optab = init_optab (NOT); ! 1234: ffs_optab = init_optab (FFS); ! 1235: ! 1236: #ifdef HAVE_addqi3 ! 1237: if (HAVE_addqi3) ! 1238: add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3; ! 1239: #endif ! 1240: #ifdef HAVE_addhi3 ! 1241: if (HAVE_addhi3) ! 1242: add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3; ! 1243: #endif ! 1244: #ifdef HAVE_addsi3 ! 1245: if (HAVE_addsi3) ! 1246: add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3; ! 1247: #endif ! 1248: #ifdef HAVE_adddi3 ! 1249: if (HAVE_adddi3) ! 1250: add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3; ! 1251: #endif ! 1252: #ifdef HAVE_addsf3 ! 1253: if (HAVE_addsf3) ! 1254: add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3; ! 1255: #endif ! 1256: #ifdef HAVE_adddf3 ! 1257: if (HAVE_adddf3) ! 1258: add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3; ! 1259: #endif ! 1260: add_optab->handlers[(int) DImode].lib_call = "_adddi3"; ! 1261: add_optab->handlers[(int) SFmode].lib_call = "_addsf3"; ! 1262: add_optab->handlers[(int) DFmode].lib_call = "_adddf3"; ! 1263: ! 1264: #ifdef HAVE_subqi3 ! 1265: if (HAVE_subqi3) ! 1266: sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3; ! 1267: #endif ! 1268: #ifdef HAVE_subhi3 ! 1269: if (HAVE_subhi3) ! 1270: sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3; ! 1271: #endif ! 1272: #ifdef HAVE_subsi3 ! 1273: if (HAVE_subsi3) ! 1274: sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3; ! 1275: #endif ! 1276: #ifdef HAVE_subdi3 ! 1277: if (HAVE_subdi3) ! 1278: sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3; ! 1279: #endif ! 1280: #ifdef HAVE_subsf3 ! 1281: if (HAVE_subsf3) ! 1282: sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3; ! 1283: #endif ! 1284: #ifdef HAVE_subdf3 ! 1285: if (HAVE_subdf3) ! 1286: sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3; ! 1287: #endif ! 1288: sub_optab->handlers[(int) DImode].lib_call = "_subdi3"; ! 1289: sub_optab->handlers[(int) SFmode].lib_call = "_subsf3"; ! 1290: sub_optab->handlers[(int) DFmode].lib_call = "_subdf3"; ! 1291: ! 1292: #ifdef HAVE_mulqi3 ! 1293: if (HAVE_mulqi3) ! 1294: smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3; ! 1295: #endif ! 1296: #ifdef HAVE_mulhi3 ! 1297: if (HAVE_mulhi3) ! 1298: smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3; ! 1299: #endif ! 1300: #ifdef HAVE_mulsi3 ! 1301: if (HAVE_mulsi3) ! 1302: smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3; ! 1303: #endif ! 1304: #ifdef HAVE_muldi3 ! 1305: if (HAVE_muldi3) ! 1306: smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3; ! 1307: #endif ! 1308: #ifdef HAVE_mulsf3 ! 1309: if (HAVE_mulsf3) ! 1310: smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3; ! 1311: #endif ! 1312: #ifdef HAVE_muldf3 ! 1313: if (HAVE_muldf3) ! 1314: smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3; ! 1315: #endif ! 1316: smul_optab->handlers[(int) SImode].lib_call = "_mulsi3"; ! 1317: smul_optab->handlers[(int) DImode].lib_call = "_muldi3"; ! 1318: smul_optab->handlers[(int) SFmode].lib_call = "_mulsf3"; ! 1319: smul_optab->handlers[(int) DFmode].lib_call = "_muldf3"; ! 1320: ! 1321: #ifdef HAVE_mulqihi3 ! 1322: if (HAVE_mulqihi3) ! 1323: smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3; ! 1324: #endif ! 1325: #ifdef HAVE_mulhisi3 ! 1326: if (HAVE_mulhisi3) ! 1327: smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3; ! 1328: #endif ! 1329: #ifdef HAVE_mulsidi3 ! 1330: if (HAVE_mulsidi3) ! 1331: smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3; ! 1332: #endif ! 1333: ! 1334: #ifdef HAVE_umulqi3 ! 1335: if (HAVE_umulqi3) ! 1336: umul_optab->handlers[(int) QImode].insn_code = CODE_FOR_umulqi3; ! 1337: #endif ! 1338: #ifdef HAVE_umulhi3 ! 1339: if (HAVE_umulhi3) ! 1340: umul_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulhi3; ! 1341: #endif ! 1342: #ifdef HAVE_umulsi3 ! 1343: if (HAVE_umulsi3) ! 1344: umul_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulsi3; ! 1345: #endif ! 1346: #ifdef HAVE_umuldi3 ! 1347: if (HAVE_umuldi3) ! 1348: umul_optab->handlers[(int) DImode].insn_code = CODE_FOR_umuldi3; ! 1349: #endif ! 1350: #ifdef HAVE_umulsf3 ! 1351: if (HAVE_umulsf3) ! 1352: umul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_umulsf3; ! 1353: #endif ! 1354: #ifdef HAVE_umuldf3 ! 1355: if (HAVE_umuldf3) ! 1356: umul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_umuldf3; ! 1357: #endif ! 1358: umul_optab->handlers[(int) SImode].lib_call = "_umulsi3"; ! 1359: umul_optab->handlers[(int) DImode].lib_call = "_umuldi3"; ! 1360: umul_optab->handlers[(int) SFmode].lib_call = "_umulsf3"; ! 1361: umul_optab->handlers[(int) DFmode].lib_call = "_umuldf3"; ! 1362: ! 1363: #ifdef HAVE_umulqihi3 ! 1364: if (HAVE_umulqihi3) ! 1365: umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3; ! 1366: #endif ! 1367: #ifdef HAVE_umulhisi3 ! 1368: if (HAVE_umulhisi3) ! 1369: umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3; ! 1370: #endif ! 1371: #ifdef HAVE_umulsidi3 ! 1372: if (HAVE_umulsidi3) ! 1373: umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3; ! 1374: #endif ! 1375: ! 1376: #ifdef HAVE_divqi3 ! 1377: if (HAVE_divqi3) ! 1378: sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3; ! 1379: #endif ! 1380: #ifdef HAVE_divhi3 ! 1381: if (HAVE_divhi3) ! 1382: sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3; ! 1383: #endif ! 1384: #ifdef HAVE_divsi3 ! 1385: if (HAVE_divsi3) ! 1386: sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3; ! 1387: #endif ! 1388: #ifdef HAVE_divdi3 ! 1389: if (HAVE_divdi3) ! 1390: sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3; ! 1391: #endif ! 1392: sdiv_optab->handlers[(int) SImode].lib_call = "_divsi3"; ! 1393: sdiv_optab->handlers[(int) DImode].lib_call = "_divdi3"; ! 1394: ! 1395: #ifdef HAVE_udivqi3 ! 1396: if (HAVE_udivqi3) ! 1397: udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3; ! 1398: #endif ! 1399: #ifdef HAVE_udivhi3 ! 1400: if (HAVE_udivhi3) ! 1401: udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3; ! 1402: #endif ! 1403: #ifdef HAVE_udivsi3 ! 1404: if (HAVE_udivsi3) ! 1405: udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3; ! 1406: #endif ! 1407: #ifdef HAVE_udivdi3 ! 1408: if (HAVE_udivdi3) ! 1409: udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3; ! 1410: #endif ! 1411: #ifdef UDIVSI3_LIBCALL ! 1412: udiv_optab->handlers[(int) SImode].lib_call = UDIVSI3_LIBCALL; ! 1413: #else ! 1414: udiv_optab->handlers[(int) SImode].lib_call = "_udivsi3"; ! 1415: #endif ! 1416: udiv_optab->handlers[(int) DImode].lib_call = "_udivdi3"; ! 1417: ! 1418: #ifdef HAVE_divmodqi4 ! 1419: if (HAVE_divmodqi4) ! 1420: sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4; ! 1421: #endif ! 1422: #ifdef HAVE_divmodhi4 ! 1423: if (HAVE_divmodhi4) ! 1424: sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4; ! 1425: #endif ! 1426: #ifdef HAVE_divmodsi4 ! 1427: if (HAVE_divmodsi4) ! 1428: sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4; ! 1429: #endif ! 1430: #ifdef HAVE_divmoddi4 ! 1431: if (HAVE_divmoddi4) ! 1432: sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4; ! 1433: #endif ! 1434: ! 1435: #ifdef HAVE_udivmodqi4 ! 1436: if (HAVE_udivmodqi4) ! 1437: udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4; ! 1438: #endif ! 1439: #ifdef HAVE_udivmodhi4 ! 1440: if (HAVE_udivmodhi4) ! 1441: udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4; ! 1442: #endif ! 1443: #ifdef HAVE_udivmodsi4 ! 1444: if (HAVE_udivmodsi4) ! 1445: udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4; ! 1446: #endif ! 1447: #ifdef HAVE_udivmoddi4 ! 1448: if (HAVE_udivmoddi4) ! 1449: udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4; ! 1450: #endif ! 1451: ! 1452: #ifdef HAVE_modqi3 ! 1453: if (HAVE_modqi3) ! 1454: smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3; ! 1455: #endif ! 1456: #ifdef HAVE_modhi3 ! 1457: if (HAVE_modhi3) ! 1458: smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3; ! 1459: #endif ! 1460: #ifdef HAVE_modsi3 ! 1461: if (HAVE_modsi3) ! 1462: smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3; ! 1463: #endif ! 1464: #ifdef HAVE_moddi3 ! 1465: if (HAVE_moddi3) ! 1466: smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3; ! 1467: #endif ! 1468: smod_optab->handlers[(int) SImode].lib_call = "_modsi3"; ! 1469: smod_optab->handlers[(int) DImode].lib_call = "_moddi3"; ! 1470: ! 1471: #ifdef HAVE_umodqi3 ! 1472: if (HAVE_umodqi3) ! 1473: umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3; ! 1474: #endif ! 1475: #ifdef HAVE_umodhi3 ! 1476: if (HAVE_umodhi3) ! 1477: umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3; ! 1478: #endif ! 1479: #ifdef HAVE_umodsi3 ! 1480: if (HAVE_umodsi3) ! 1481: umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3; ! 1482: #endif ! 1483: #ifdef HAVE_umoddi3 ! 1484: if (HAVE_umoddi3) ! 1485: umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3; ! 1486: #endif ! 1487: #ifdef UMODSI3_LIBCALL ! 1488: umod_optab->handlers[(int) SImode].lib_call = UMODSI3_LIBCALL; ! 1489: #else ! 1490: umod_optab->handlers[(int) SImode].lib_call = "_umodsi3"; ! 1491: #endif ! 1492: umod_optab->handlers[(int) DImode].lib_call = "_umoddi3"; ! 1493: ! 1494: #ifdef HAVE_divsf3 ! 1495: if (HAVE_divsf3) ! 1496: flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3; ! 1497: #endif ! 1498: #ifdef HAVE_divdf3 ! 1499: if (HAVE_divdf3) ! 1500: flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3; ! 1501: #endif ! 1502: flodiv_optab->handlers[(int) SFmode].lib_call = "_divsf3"; ! 1503: flodiv_optab->handlers[(int) DFmode].lib_call = "_divdf3"; ! 1504: ! 1505: #ifdef HAVE_ftruncsf2 ! 1506: if (HAVE_ftruncsf2) ! 1507: ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2; ! 1508: #endif ! 1509: #ifdef HAVE_ftruncdf2 ! 1510: if (HAVE_ftruncdf2) ! 1511: ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2; ! 1512: #endif ! 1513: ftrunc_optab->handlers[(int) SFmode].lib_call = "_ftruncsf2"; ! 1514: ftrunc_optab->handlers[(int) DFmode].lib_call = "_ftruncsf2"; ! 1515: ! 1516: #ifdef HAVE_andqi3 ! 1517: if (HAVE_andqi3) ! 1518: and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3; ! 1519: #endif ! 1520: #ifdef HAVE_andhi3 ! 1521: if (HAVE_andhi3) ! 1522: and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3; ! 1523: #endif ! 1524: #ifdef HAVE_andsi3 ! 1525: if (HAVE_andsi3) ! 1526: and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3; ! 1527: #endif ! 1528: and_optab->handlers[(int) DImode].lib_call = "_anddi3"; ! 1529: ! 1530: #ifdef HAVE_andcbqi3 ! 1531: if (HAVE_andcbqi3) ! 1532: andcb_optab->handlers[(int) QImode].insn_code = CODE_FOR_andcbqi3; ! 1533: #endif ! 1534: #ifdef HAVE_andcbhi3 ! 1535: if (HAVE_andcbhi3) ! 1536: andcb_optab->handlers[(int) HImode].insn_code = CODE_FOR_andcbhi3; ! 1537: #endif ! 1538: #ifdef HAVE_andcbsi3 ! 1539: if (HAVE_andcbsi3) ! 1540: andcb_optab->handlers[(int) SImode].insn_code = CODE_FOR_andcbsi3; ! 1541: #endif ! 1542: andcb_optab->handlers[(int) DImode].lib_call = "_andcbdi3"; ! 1543: ! 1544: #ifdef HAVE_iorqi3 ! 1545: if (HAVE_iorqi3) ! 1546: ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3; ! 1547: #endif ! 1548: #ifdef HAVE_iorhi3 ! 1549: if (HAVE_iorhi3) ! 1550: ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3; ! 1551: #endif ! 1552: #ifdef HAVE_iorsi3 ! 1553: if (HAVE_iorsi3) ! 1554: ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3; ! 1555: #endif ! 1556: ior_optab->handlers[(int) DImode].lib_call = "_iordi3"; ! 1557: ! 1558: #ifdef HAVE_xorqi3 ! 1559: if (HAVE_xorqi3) ! 1560: xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3; ! 1561: #endif ! 1562: #ifdef HAVE_xorhi3 ! 1563: if (HAVE_xorhi3) ! 1564: xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3; ! 1565: #endif ! 1566: #ifdef HAVE_xorsi3 ! 1567: if (HAVE_xorsi3) ! 1568: xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3; ! 1569: #endif ! 1570: xor_optab->handlers[(int) DImode].lib_call = "_xordi3"; ! 1571: ! 1572: #ifdef HAVE_ashlqi3 ! 1573: if (HAVE_ashlqi3) ! 1574: ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3; ! 1575: #endif ! 1576: #ifdef HAVE_ashlhi3 ! 1577: if (HAVE_ashlhi3) ! 1578: ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3; ! 1579: #endif ! 1580: #ifdef HAVE_ashlsi3 ! 1581: if (HAVE_ashlsi3) ! 1582: ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3; ! 1583: #endif ! 1584: #ifdef HAVE_ashldi3 ! 1585: if (HAVE_ashldi3) ! 1586: ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3; ! 1587: #endif ! 1588: ashl_optab->handlers[(int) SImode].lib_call = "_ashlsi3"; ! 1589: ashl_optab->handlers[(int) DImode].lib_call = "_ashldi3"; ! 1590: ! 1591: #ifdef HAVE_ashrqi3 ! 1592: if (HAVE_ashrqi3) ! 1593: ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3; ! 1594: #endif ! 1595: #ifdef HAVE_ashrhi3 ! 1596: if (HAVE_ashrhi3) ! 1597: ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3; ! 1598: #endif ! 1599: #ifdef HAVE_ashrsi3 ! 1600: if (HAVE_ashrsi3) ! 1601: ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3; ! 1602: #endif ! 1603: #ifdef HAVE_ashrdi3 ! 1604: if (HAVE_ashrdi3) ! 1605: ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3; ! 1606: #endif ! 1607: ashr_optab->handlers[(int) SImode].lib_call = "_ashrsi3"; ! 1608: ashr_optab->handlers[(int) DImode].lib_call = "_ashrdi3"; ! 1609: ! 1610: #ifdef HAVE_lshlqi3 ! 1611: if (HAVE_lshlqi3) ! 1612: lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3; ! 1613: #endif ! 1614: #ifdef HAVE_lshlhi3 ! 1615: if (HAVE_lshlhi3) ! 1616: lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3; ! 1617: #endif ! 1618: #ifdef HAVE_lshlsi3 ! 1619: if (HAVE_lshlsi3) ! 1620: lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3; ! 1621: #endif ! 1622: #ifdef HAVE_lshldi3 ! 1623: if (HAVE_lshldi3) ! 1624: lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3; ! 1625: #endif ! 1626: lshl_optab->handlers[(int) SImode].lib_call = "_lshlsi3"; ! 1627: lshl_optab->handlers[(int) DImode].lib_call = "_lshldi3"; ! 1628: ! 1629: #ifdef HAVE_lshrqi3 ! 1630: if (HAVE_lshrqi3) ! 1631: lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3; ! 1632: #endif ! 1633: #ifdef HAVE_lshrhi3 ! 1634: if (HAVE_lshrhi3) ! 1635: lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3; ! 1636: #endif ! 1637: #ifdef HAVE_lshrsi3 ! 1638: if (HAVE_lshrsi3) ! 1639: lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3; ! 1640: #endif ! 1641: #ifdef HAVE_lshrdi3 ! 1642: if (HAVE_lshrdi3) ! 1643: lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3; ! 1644: #endif ! 1645: lshr_optab->handlers[(int) SImode].lib_call = "_lshrsi3"; ! 1646: lshr_optab->handlers[(int) DImode].lib_call = "_lshrdi3"; ! 1647: ! 1648: #ifdef HAVE_rotlqi3 ! 1649: if (HAVE_rotlqi3) ! 1650: rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3; ! 1651: #endif ! 1652: #ifdef HAVE_rotlhi3 ! 1653: if (HAVE_rotlhi3) ! 1654: rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3; ! 1655: #endif ! 1656: #ifdef HAVE_rotlsi3 ! 1657: if (HAVE_rotlsi3) ! 1658: rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3; ! 1659: #endif ! 1660: #ifdef HAVE_rotldi3 ! 1661: if (HAVE_rotldi3) ! 1662: rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3; ! 1663: #endif ! 1664: rotl_optab->handlers[(int) SImode].lib_call = "_rotlsi3"; ! 1665: rotl_optab->handlers[(int) DImode].lib_call = "_rotldi3"; ! 1666: ! 1667: #ifdef HAVE_rotrqi3 ! 1668: if (HAVE_rotrqi3) ! 1669: rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3; ! 1670: #endif ! 1671: #ifdef HAVE_rotrhi3 ! 1672: if (HAVE_rotrhi3) ! 1673: rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3; ! 1674: #endif ! 1675: #ifdef HAVE_rotrsi3 ! 1676: if (HAVE_rotrsi3) ! 1677: rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3; ! 1678: #endif ! 1679: #ifdef HAVE_rotrdi3 ! 1680: if (HAVE_rotrdi3) ! 1681: rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3; ! 1682: #endif ! 1683: rotr_optab->handlers[(int) SImode].lib_call = "_rotrsi3"; ! 1684: rotr_optab->handlers[(int) DImode].lib_call = "_rotrdi3"; ! 1685: ! 1686: #ifdef HAVE_negqi2 ! 1687: if (HAVE_negqi2) ! 1688: neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2; ! 1689: #endif ! 1690: #ifdef HAVE_neghi2 ! 1691: if (HAVE_neghi2) ! 1692: neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2; ! 1693: #endif ! 1694: #ifdef HAVE_negsi2 ! 1695: if (HAVE_negsi2) ! 1696: neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2; ! 1697: #endif ! 1698: #ifdef HAVE_negsf2 ! 1699: if (HAVE_negsf2) ! 1700: neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2; ! 1701: #endif ! 1702: #ifdef HAVE_negdf2 ! 1703: if (HAVE_negdf2) ! 1704: neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2; ! 1705: #endif ! 1706: neg_optab->handlers[(int) SImode].lib_call = "_negsi2"; ! 1707: neg_optab->handlers[(int) DImode].lib_call = "_negdi2"; ! 1708: neg_optab->handlers[(int) SFmode].lib_call = "_negsf2"; ! 1709: neg_optab->handlers[(int) DFmode].lib_call = "_negdf2"; ! 1710: ! 1711: #ifdef HAVE_absqi2 ! 1712: if (HAVE_absqi2) ! 1713: abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2; ! 1714: #endif ! 1715: #ifdef HAVE_abshi2 ! 1716: if (HAVE_abshi2) ! 1717: abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2; ! 1718: #endif ! 1719: #ifdef HAVE_abssi2 ! 1720: if (HAVE_abssi2) ! 1721: abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2; ! 1722: #endif ! 1723: #ifdef HAVE_abssf2 ! 1724: if (HAVE_abssf2) ! 1725: abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2; ! 1726: #endif ! 1727: #ifdef HAVE_absdf2 ! 1728: if (HAVE_absdf2) ! 1729: abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2; ! 1730: #endif ! 1731: /* No library calls here! If there is no abs instruction, ! 1732: expand_expr will generate a conditional negation. */ ! 1733: ! 1734: #ifdef HAVE_one_cmplqi2 ! 1735: if (HAVE_one_cmplqi2) ! 1736: one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2; ! 1737: #endif ! 1738: #ifdef HAVE_one_cmplhi2 ! 1739: if (HAVE_one_cmplhi2) ! 1740: one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2; ! 1741: #endif ! 1742: #ifdef HAVE_one_cmplsi2 ! 1743: if (HAVE_one_cmplsi2) ! 1744: one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2; ! 1745: #endif ! 1746: one_cmpl_optab->handlers[(int) SImode].lib_call = "_one_cmplsi2"; ! 1747: one_cmpl_optab->handlers[(int) DImode].lib_call = "_one_cmpldi2"; ! 1748: ! 1749: #ifdef HAVE_ffsqi2 ! 1750: if (HAVE_ffsqi2) ! 1751: ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2; ! 1752: #endif ! 1753: #ifdef HAVE_ffshi2 ! 1754: if (HAVE_ffshi2) ! 1755: ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2; ! 1756: #endif ! 1757: #ifdef HAVE_ffssi2 ! 1758: if (HAVE_ffssi2) ! 1759: ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2; ! 1760: #endif ! 1761: ffs_optab->handlers[(int) SImode].lib_call = "ffs"; ! 1762: ! 1763: #ifdef HAVE_movqi ! 1764: if (HAVE_movqi) ! 1765: mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi; ! 1766: #endif ! 1767: #ifdef HAVE_movhi ! 1768: if (HAVE_movhi) ! 1769: mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi; ! 1770: #endif ! 1771: #ifdef HAVE_movsi ! 1772: if (HAVE_movsi) ! 1773: mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi; ! 1774: #endif ! 1775: #ifdef HAVE_movdi ! 1776: if (HAVE_movdi) ! 1777: mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi; ! 1778: #endif ! 1779: #ifdef HAVE_movsf ! 1780: if (HAVE_movsf) ! 1781: mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf; ! 1782: #endif ! 1783: #ifdef HAVE_movdf ! 1784: if (HAVE_movdf) ! 1785: mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf; ! 1786: #endif ! 1787: ! 1788: #ifdef HAVE_movstrictqi ! 1789: if (HAVE_movstrictqi) ! 1790: movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi; ! 1791: #endif ! 1792: #ifdef HAVE_movstricthi ! 1793: if (HAVE_movstricthi) ! 1794: movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi; ! 1795: #endif ! 1796: #ifdef HAVE_movstrictsi ! 1797: if (HAVE_movstrictsi) ! 1798: movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi; ! 1799: #endif ! 1800: #ifdef HAVE_movstrictdi ! 1801: if (HAVE_movstrictdi) ! 1802: movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi; ! 1803: #endif ! 1804: ! 1805: #ifdef HAVE_cmpqi ! 1806: if (HAVE_cmpqi) ! 1807: cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi; ! 1808: #endif ! 1809: #ifdef HAVE_cmphi ! 1810: if (HAVE_cmphi) ! 1811: cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi; ! 1812: #endif ! 1813: #ifdef HAVE_cmpsi ! 1814: if (HAVE_cmpsi) ! 1815: cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi; ! 1816: #endif ! 1817: #ifdef HAVE_cmpsf ! 1818: if (HAVE_cmpsf) ! 1819: cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf; ! 1820: #endif ! 1821: #ifdef HAVE_cmpdf ! 1822: if (HAVE_cmpdf) ! 1823: cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf; ! 1824: #endif ! 1825: #ifdef HAVE_tstqi ! 1826: if (HAVE_tstqi) ! 1827: tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi; ! 1828: #endif ! 1829: #ifdef HAVE_tsthi ! 1830: if (HAVE_tsthi) ! 1831: tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi; ! 1832: #endif ! 1833: #ifdef HAVE_tstsi ! 1834: if (HAVE_tstsi) ! 1835: tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi; ! 1836: #endif ! 1837: #ifdef HAVE_tstsf ! 1838: if (HAVE_tstsf) ! 1839: tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf; ! 1840: #endif ! 1841: #ifdef HAVE_tstdf ! 1842: if (HAVE_tstdf) ! 1843: tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf; ! 1844: #endif ! 1845: cmp_optab->handlers[(int) SImode].lib_call = "_cmpsi2"; ! 1846: cmp_optab->handlers[(int) DImode].lib_call = "_cmpdi2"; ! 1847: cmp_optab->handlers[(int) SFmode].lib_call = "_cmpsf2"; ! 1848: cmp_optab->handlers[(int) DFmode].lib_call = "_cmpdf2"; ! 1849: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.