Annotation of GNUtools/cc/optabs.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.