Home | History | Annotate | Line # | Download | only in gcc
      1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
      2    Copyright (C) 1987-2024 Free Software Foundation, Inc.
      3 
      4 This file is part of GCC.
      5 
      6 GCC is free software; you can redistribute it and/or modify it under
      7 the terms of the GNU General Public License as published by the Free
      8 Software Foundation; either version 3, or (at your option) any later
      9 version.
     10 
     11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14 for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with GCC; see the file COPYING3.  If not see
     18 <http://www.gnu.org/licenses/>.  */
     19 
     20 
     21 #include "config.h"
     22 #include "system.h"
     23 #include "coretypes.h"
     24 #include "backend.h"
     25 #include "target.h"
     26 #include "rtl.h"
     27 #include "tree.h"
     28 #include "memmodel.h"
     29 #include "predict.h"
     30 #include "tm_p.h"
     31 #include "optabs.h"
     32 #include "expmed.h"
     33 #include "emit-rtl.h"
     34 #include "recog.h"
     35 #include "diagnostic-core.h"
     36 #include "rtx-vector-builder.h"
     37 
     38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
     39    is properly defined.  */
     40 #include "stor-layout.h"
     41 #include "except.h"
     42 #include "dojump.h"
     43 #include "explow.h"
     44 #include "expr.h"
     45 #include "optabs-tree.h"
     46 #include "libfuncs.h"
     47 #include "internal-fn.h"
     48 #include "langhooks.h"
     49 #include "gimple.h"
     50 #include "ssa.h"
     51 
     52 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
     53 				   machine_mode *);
     54 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
     55 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
     56 
     57 static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode);
     58 
     59 /* Debug facility for use in GDB.  */
     60 void debug_optab_libfuncs (void);
     61 
     62 /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
     64    the result of operation CODE applied to OP0 (and OP1 if it is a binary
     65    operation).  OP0_MODE is OP0's mode.
     66 
     67    If the last insn does not set TARGET, don't do anything, but return true.
     68 
     69    If the last insn or a previous insn sets TARGET and TARGET is one of OP0
     70    or OP1, don't add the REG_EQUAL note but return false.  Our caller can then
     71    try again, ensuring that TARGET is not one of the operands.  */
     72 
     73 static bool
     74 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
     75 		rtx op1, machine_mode op0_mode)
     76 {
     77   rtx_insn *last_insn;
     78   rtx set;
     79   rtx note;
     80 
     81   gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
     82 
     83   if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
     84       && GET_RTX_CLASS (code) != RTX_BIN_ARITH
     85       && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
     86       && GET_RTX_CLASS (code) != RTX_COMPARE
     87       && GET_RTX_CLASS (code) != RTX_UNARY)
     88     return true;
     89 
     90   if (GET_CODE (target) == ZERO_EXTRACT)
     91     return true;
     92 
     93   for (last_insn = insns;
     94        NEXT_INSN (last_insn) != NULL_RTX;
     95        last_insn = NEXT_INSN (last_insn))
     96     ;
     97 
     98   /* If TARGET is in OP0 or OP1, punt.  We'd end up with a note referencing
     99      a value changing in the insn, so the note would be invalid for CSE.  */
    100   if (reg_overlap_mentioned_p (target, op0)
    101       || (op1 && reg_overlap_mentioned_p (target, op1)))
    102     {
    103       if (MEM_P (target)
    104 	  && (rtx_equal_p (target, op0)
    105 	      || (op1 && rtx_equal_p (target, op1))))
    106 	{
    107 	  /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
    108 	     over expanding it as temp = MEM op X, MEM = temp.  If the target
    109 	     supports MEM = MEM op X instructions, it is sometimes too hard
    110 	     to reconstruct that form later, especially if X is also a memory,
    111 	     and due to multiple occurrences of addresses the address might
    112 	     be forced into register unnecessarily.
    113 	     Note that not emitting the REG_EQUIV note might inhibit
    114 	     CSE in some cases.  */
    115 	  set = single_set (last_insn);
    116 	  if (set
    117 	      && GET_CODE (SET_SRC (set)) == code
    118 	      && MEM_P (SET_DEST (set))
    119 	      && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
    120 		  || (op1 && rtx_equal_p (SET_DEST (set),
    121 					  XEXP (SET_SRC (set), 1)))))
    122 	    return true;
    123 	}
    124       return false;
    125     }
    126 
    127   set = set_for_reg_notes (last_insn);
    128   if (set == NULL_RTX)
    129     return true;
    130 
    131   if (! rtx_equal_p (SET_DEST (set), target)
    132       /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
    133       && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
    134 	  || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
    135     return true;
    136 
    137   if (GET_RTX_CLASS (code) == RTX_UNARY)
    138     switch (code)
    139       {
    140       case FFS:
    141       case CLZ:
    142       case CTZ:
    143       case CLRSB:
    144       case POPCOUNT:
    145       case PARITY:
    146       case BSWAP:
    147 	if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
    148 	  {
    149 	    note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
    150 	    if (GET_MODE_UNIT_SIZE (op0_mode)
    151 		> GET_MODE_UNIT_SIZE (GET_MODE (target)))
    152 	      note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
    153 					 note, op0_mode);
    154 	    else
    155 	      note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
    156 					 note, op0_mode);
    157 	    break;
    158 	  }
    159 	/* FALLTHRU */
    160       default:
    161 	note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
    162 	break;
    163       }
    164   else
    165     note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
    166 
    167   set_unique_reg_note (last_insn, REG_EQUAL, note);
    168 
    169   return true;
    170 }
    171 
    172 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
    174    for a widening operation would be.  In most cases this would be OP0, but if
    175    that's a constant it'll be VOIDmode, which isn't useful.  */
    176 
    177 static machine_mode
    178 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
    179 {
    180   machine_mode m0 = GET_MODE (op0);
    181   machine_mode m1 = GET_MODE (op1);
    182   machine_mode result;
    183 
    184   if (m0 == VOIDmode && m1 == VOIDmode)
    185     return to_mode;
    186   else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
    187     result = m1;
    188   else
    189     result = m0;
    190 
    191   if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
    192     return to_mode;
    193 
    194   return result;
    195 }
    196 
    197 /* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
    199    says whether OP is signed or unsigned.  NO_EXTEND is true if we need
    200    not actually do a sign-extend or zero-extend, but can leave the
    201    higher-order bits of the result rtx undefined, for example, in the case
    202    of logical operations, but not right shifts.  */
    203 
    204 static rtx
    205 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
    206 	       int unsignedp, bool no_extend)
    207 {
    208   rtx result;
    209   scalar_int_mode int_mode;
    210 
    211   /* If we don't have to extend and this is a constant, return it.  */
    212   if (no_extend && GET_MODE (op) == VOIDmode)
    213     return op;
    214 
    215   /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
    216      extend since it will be more efficient to do so unless the signedness of
    217      a promoted object differs from our extension.  */
    218   if (! no_extend
    219       || !is_a <scalar_int_mode> (mode, &int_mode)
    220       || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
    221 	  && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
    222     return convert_modes (mode, oldmode, op, unsignedp);
    223 
    224   /* If MODE is no wider than a single word, we return a lowpart or paradoxical
    225      SUBREG.  */
    226   if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
    227     return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
    228 
    229   /* Otherwise, get an object of MODE, clobber it, and set the low-order
    230      part to OP.  */
    231 
    232   result = gen_reg_rtx (int_mode);
    233   emit_clobber (result);
    234   emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
    235   return result;
    236 }
    237 
    238 /* Expand vector widening operations.
    240 
    241    There are two different classes of operations handled here:
    242    1) Operations whose result is wider than all the arguments to the operation.
    243       Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
    244       In this case OP0 and optionally OP1 would be initialized,
    245       but WIDE_OP wouldn't (not relevant for this case).
    246    2) Operations whose result is of the same size as the last argument to the
    247       operation, but wider than all the other arguments to the operation.
    248       Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
    249       In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
    250 
    251    E.g, when called to expand the following operations, this is how
    252    the arguments will be initialized:
    253                                 nops    OP0     OP1     WIDE_OP
    254    widening-sum                 2       oprnd0  -       oprnd1
    255    widening-dot-product         3       oprnd0  oprnd1  oprnd2
    256    widening-mult                2       oprnd0  oprnd1  -
    257    type-promotion (vec-unpack)  1       oprnd0  -       -  */
    258 
    259 rtx
    260 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
    261 			   rtx target, int unsignedp)
    262 {
    263   class expand_operand eops[4];
    264   tree oprnd0, oprnd1, oprnd2;
    265   machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
    266   optab widen_pattern_optab;
    267   enum insn_code icode;
    268   int nops = TREE_CODE_LENGTH (ops->code);
    269   int op;
    270   bool sbool = false;
    271 
    272   oprnd0 = ops->op0;
    273   oprnd1 = nops >= 2 ? ops->op1 : NULL_TREE;
    274   oprnd2 = nops >= 3 ? ops->op2 : NULL_TREE;
    275 
    276   tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
    277   if (ops->code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
    278       || ops->code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
    279     /* The sign is from the result type rather than operand's type
    280        for these ops.  */
    281     widen_pattern_optab
    282       = optab_for_tree_code (ops->code, ops->type, optab_default);
    283   else if ((ops->code == VEC_UNPACK_HI_EXPR
    284 	    || ops->code == VEC_UNPACK_LO_EXPR)
    285 	   && VECTOR_BOOLEAN_TYPE_P (ops->type)
    286 	   && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0))
    287 	   && TYPE_MODE (ops->type) == TYPE_MODE (TREE_TYPE (oprnd0))
    288 	   && SCALAR_INT_MODE_P (TYPE_MODE (ops->type)))
    289     {
    290       /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
    291 	 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
    292 	 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
    293 	 the pattern number of elements in the wider vector.  */
    294       widen_pattern_optab
    295 	= (ops->code == VEC_UNPACK_HI_EXPR
    296 	   ? vec_unpacks_sbool_hi_optab : vec_unpacks_sbool_lo_optab);
    297       sbool = true;
    298     }
    299   else if (ops->code == DOT_PROD_EXPR)
    300     {
    301       enum optab_subtype subtype = optab_default;
    302       signop sign1 = TYPE_SIGN (TREE_TYPE (oprnd0));
    303       signop sign2 = TYPE_SIGN (TREE_TYPE (oprnd1));
    304       if (sign1 == sign2)
    305 	;
    306       else if (sign1 == SIGNED && sign2 == UNSIGNED)
    307 	{
    308 	  subtype = optab_vector_mixed_sign;
    309 	  /* Same as optab_vector_mixed_sign but flip the operands.  */
    310 	  std::swap (op0, op1);
    311 	}
    312       else if (sign1 == UNSIGNED && sign2 == SIGNED)
    313 	subtype = optab_vector_mixed_sign;
    314       else
    315 	gcc_unreachable ();
    316 
    317       widen_pattern_optab
    318 	= optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), subtype);
    319     }
    320   else
    321     widen_pattern_optab
    322       = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
    323   if (ops->code == WIDEN_MULT_PLUS_EXPR
    324       || ops->code == WIDEN_MULT_MINUS_EXPR)
    325     icode = find_widening_optab_handler (widen_pattern_optab,
    326 					 TYPE_MODE (TREE_TYPE (ops->op2)),
    327 					 tmode0);
    328   else
    329     icode = optab_handler (widen_pattern_optab, tmode0);
    330   gcc_assert (icode != CODE_FOR_nothing);
    331 
    332   if (nops >= 2)
    333     tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
    334   else if (sbool)
    335     {
    336       nops = 2;
    337       op1 = GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0)).to_constant ());
    338       tmode1 = tmode0;
    339     }
    340 
    341   /* The last operand is of a wider mode than the rest of the operands.  */
    342   if (nops == 2)
    343     wmode = tmode1;
    344   else if (nops == 3)
    345     {
    346       gcc_assert (tmode1 == tmode0);
    347       gcc_assert (op1);
    348       wmode = TYPE_MODE (TREE_TYPE (oprnd2));
    349     }
    350 
    351   op = 0;
    352   create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
    353   create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
    354   if (op1)
    355     create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
    356   if (wide_op)
    357     create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
    358   expand_insn (icode, op, eops);
    359   return eops[0].value;
    360 }
    361 
    362 /* Generate code to perform an operation specified by TERNARY_OPTAB
    363    on operands OP0, OP1 and OP2, with result having machine-mode MODE.
    364 
    365    UNSIGNEDP is for the case where we have to widen the operands
    366    to perform the operation.  It says to use zero-extension.
    367 
    368    If TARGET is nonzero, the value
    369    is generated there, if it is convenient to do so.
    370    In all cases an rtx is returned for the locus of the value;
    371    this may or may not be TARGET.  */
    372 
    373 rtx
    374 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
    375 		   rtx op1, rtx op2, rtx target, int unsignedp)
    376 {
    377   class expand_operand ops[4];
    378   enum insn_code icode = optab_handler (ternary_optab, mode);
    379 
    380   gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
    381 
    382   create_output_operand (&ops[0], target, mode);
    383   create_convert_operand_from (&ops[1], op0, mode, unsignedp);
    384   create_convert_operand_from (&ops[2], op1, mode, unsignedp);
    385   create_convert_operand_from (&ops[3], op2, mode, unsignedp);
    386   expand_insn (icode, 4, ops);
    387   return ops[0].value;
    388 }
    389 
    390 
    391 /* Like expand_binop, but return a constant rtx if the result can be
    392    calculated at compile time.  The arguments and return value are
    393    otherwise the same as for expand_binop.  */
    394 
    395 rtx
    396 simplify_expand_binop (machine_mode mode, optab binoptab,
    397 		       rtx op0, rtx op1, rtx target, int unsignedp,
    398 		       enum optab_methods methods)
    399 {
    400   if (CONSTANT_P (op0) && CONSTANT_P (op1))
    401     {
    402       rtx x = simplify_binary_operation (optab_to_code (binoptab),
    403 					 mode, op0, op1);
    404       if (x)
    405 	return x;
    406     }
    407 
    408   return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
    409 }
    410 
    411 /* Like simplify_expand_binop, but always put the result in TARGET.
    412    Return true if the expansion succeeded.  */
    413 
    414 bool
    415 force_expand_binop (machine_mode mode, optab binoptab,
    416 		    rtx op0, rtx op1, rtx target, int unsignedp,
    417 		    enum optab_methods methods)
    418 {
    419   rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
    420 				 target, unsignedp, methods);
    421   if (x == 0)
    422     return false;
    423   if (x != target)
    424     emit_move_insn (target, x);
    425   return true;
    426 }
    427 
    428 /* Create a new vector value in VMODE with all elements set to OP.  The
    429    mode of OP must be the element mode of VMODE.  If OP is a constant,
    430    then the return value will be a constant.  */
    431 
    432 rtx
    433 expand_vector_broadcast (machine_mode vmode, rtx op)
    434 {
    435   int n;
    436   rtvec vec;
    437 
    438   gcc_checking_assert (VECTOR_MODE_P (vmode));
    439 
    440   if (valid_for_const_vector_p (vmode, op))
    441     return gen_const_vec_duplicate (vmode, op);
    442 
    443   insn_code icode = optab_handler (vec_duplicate_optab, vmode);
    444   if (icode != CODE_FOR_nothing)
    445     {
    446       class expand_operand ops[2];
    447       create_output_operand (&ops[0], NULL_RTX, vmode);
    448       create_input_operand (&ops[1], op, GET_MODE (op));
    449       expand_insn (icode, 2, ops);
    450       return ops[0].value;
    451     }
    452 
    453   if (!GET_MODE_NUNITS (vmode).is_constant (&n))
    454     return NULL;
    455 
    456   /* ??? If the target doesn't have a vec_init, then we have no easy way
    457      of performing this operation.  Most of this sort of generic support
    458      is hidden away in the vector lowering support in gimple.  */
    459   icode = convert_optab_handler (vec_init_optab, vmode,
    460 				 GET_MODE_INNER (vmode));
    461   if (icode == CODE_FOR_nothing)
    462     return NULL;
    463 
    464   vec = rtvec_alloc (n);
    465   for (int i = 0; i < n; ++i)
    466     RTVEC_ELT (vec, i) = op;
    467   rtx ret = gen_reg_rtx (vmode);
    468   emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
    469 
    470   return ret;
    471 }
    472 
    473 /* This subroutine of expand_doubleword_shift handles the cases in which
    474    the effective shift value is >= BITS_PER_WORD.  The arguments and return
    475    value are the same as for the parent routine, except that SUPERWORD_OP1
    476    is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
    477    INTO_TARGET may be null if the caller has decided to calculate it.  */
    478 
    479 static bool
    480 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
    481 			rtx outof_target, rtx into_target,
    482 			int unsignedp, enum optab_methods methods)
    483 {
    484   if (into_target != 0)
    485     if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
    486 			     into_target, unsignedp, methods))
    487       return false;
    488 
    489   if (outof_target != 0)
    490     {
    491       /* For a signed right shift, we must fill OUTOF_TARGET with copies
    492 	 of the sign bit, otherwise we must fill it with zeros.  */
    493       if (binoptab != ashr_optab)
    494 	emit_move_insn (outof_target, CONST0_RTX (word_mode));
    495       else
    496 	if (!force_expand_binop (word_mode, binoptab, outof_input,
    497 				 gen_int_shift_amount (word_mode,
    498 						       BITS_PER_WORD - 1),
    499 				 outof_target, unsignedp, methods))
    500 	  return false;
    501     }
    502   return true;
    503 }
    504 
    505 /* This subroutine of expand_doubleword_shift handles the cases in which
    506    the effective shift value is < BITS_PER_WORD.  The arguments and return
    507    value are the same as for the parent routine.  */
    508 
    509 static bool
    510 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
    511 		      rtx outof_input, rtx into_input, rtx op1,
    512 		      rtx outof_target, rtx into_target,
    513 		      int unsignedp, enum optab_methods methods,
    514 		      unsigned HOST_WIDE_INT shift_mask)
    515 {
    516   optab reverse_unsigned_shift, unsigned_shift;
    517   rtx tmp, carries;
    518 
    519   reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
    520   unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
    521 
    522   /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
    523      We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
    524      the opposite direction to BINOPTAB.  */
    525   if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
    526     {
    527       carries = outof_input;
    528       tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
    529 					    op1_mode), op1_mode);
    530       tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
    531 				   0, true, methods);
    532     }
    533   else
    534     {
    535       /* We must avoid shifting by BITS_PER_WORD bits since that is either
    536 	 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
    537 	 has unknown behavior.  Do a single shift first, then shift by the
    538 	 remainder.  It's OK to use ~OP1 as the remainder if shift counts
    539 	 are truncated to the mode size.  */
    540       carries = simplify_expand_binop (word_mode, reverse_unsigned_shift,
    541 				       outof_input, const1_rtx, 0,
    542 				       unsignedp, methods);
    543       if (carries == const0_rtx)
    544 	tmp = const0_rtx;
    545       else if (shift_mask == BITS_PER_WORD - 1)
    546 	tmp = expand_unop (op1_mode, one_cmpl_optab, op1, 0, true);
    547       else
    548 	{
    549 	  tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
    550 						op1_mode), op1_mode);
    551 	  tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
    552 				       0, true, methods);
    553 	}
    554     }
    555   if (tmp == 0 || carries == 0)
    556     return false;
    557   if (carries != const0_rtx && tmp != const0_rtx)
    558     carries = simplify_expand_binop (word_mode, reverse_unsigned_shift,
    559 				     carries, tmp, 0, unsignedp, methods);
    560   if (carries == 0)
    561     return false;
    562 
    563   if (into_input != const0_rtx)
    564     {
    565       /* Shift INTO_INPUT logically by OP1.  This is the last use of
    566 	 INTO_INPUT so the result can go directly into INTO_TARGET if
    567 	 convenient.  */
    568       tmp = simplify_expand_binop (word_mode, unsigned_shift, into_input,
    569 				   op1, into_target, unsignedp, methods);
    570       if (tmp == 0)
    571 	return false;
    572 
    573       /* Now OR in the bits carried over from OUTOF_INPUT.  */
    574       if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
    575 			       into_target, unsignedp, methods))
    576 	return false;
    577     }
    578   else
    579     emit_move_insn (into_target, carries);
    580 
    581   /* Use a standard word_mode shift for the out-of half.  */
    582   if (outof_target != 0)
    583     if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
    584 			     outof_target, unsignedp, methods))
    585       return false;
    586 
    587   return true;
    588 }
    589 
    590 
    591 /* Try implementing expand_doubleword_shift using conditional moves.
    592    The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
    593    otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
    594    are the shift counts to use in the former and latter case.  All other
    595    arguments are the same as the parent routine.  */
    596 
    597 static bool
    598 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
    599 				  enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
    600 				  rtx outof_input, rtx into_input,
    601 				  rtx subword_op1, rtx superword_op1,
    602 				  rtx outof_target, rtx into_target,
    603 				  int unsignedp, enum optab_methods methods,
    604 				  unsigned HOST_WIDE_INT shift_mask)
    605 {
    606   rtx outof_superword, into_superword;
    607 
    608   /* Put the superword version of the output into OUTOF_SUPERWORD and
    609      INTO_SUPERWORD.  */
    610   outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
    611   if (outof_target != 0 && subword_op1 == superword_op1)
    612     {
    613       /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
    614 	 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
    615       into_superword = outof_target;
    616       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
    617 				   outof_superword, 0, unsignedp, methods))
    618 	return false;
    619     }
    620   else
    621     {
    622       into_superword = gen_reg_rtx (word_mode);
    623       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
    624 				   outof_superword, into_superword,
    625 				   unsignedp, methods))
    626 	return false;
    627     }
    628 
    629   /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
    630   if (!expand_subword_shift (op1_mode, binoptab,
    631 			     outof_input, into_input, subword_op1,
    632 			     outof_target, into_target,
    633 			     unsignedp, methods, shift_mask))
    634     return false;
    635 
    636   /* Select between them.  Do the INTO half first because INTO_SUPERWORD
    637      might be the current value of OUTOF_TARGET.  */
    638   if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode },
    639 			      into_target, into_superword, word_mode, false))
    640     return false;
    641 
    642   if (outof_target != 0)
    643     if (!emit_conditional_move (outof_target,
    644 				{ cmp_code, cmp1, cmp2, op1_mode },
    645 				outof_target, outof_superword,
    646 				word_mode, false))
    647       return false;
    648 
    649   return true;
    650 }
    651 
    652 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
    653    OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
    654    input operand; the shift moves bits in the direction OUTOF_INPUT->
    655    INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
    656    of the target.  OP1 is the shift count and OP1_MODE is its mode.
    657    If OP1 is constant, it will have been truncated as appropriate
    658    and is known to be nonzero.
    659 
    660    If SHIFT_MASK is zero, the result of word shifts is undefined when the
    661    shift count is outside the range [0, BITS_PER_WORD).  This routine must
    662    avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
    663 
    664    If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
    665    masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
    666    fill with zeros or sign bits as appropriate.
    667 
    668    If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
    669    a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
    670    Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
    671    In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
    672    are undefined.
    673 
    674    BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
    675    may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
    676    OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
    677    function wants to calculate it itself.
    678 
    679    Return true if the shift could be successfully synthesized.  */
    680 
    681 static bool
    682 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
    683 			 rtx outof_input, rtx into_input, rtx op1,
    684 			 rtx outof_target, rtx into_target,
    685 			 int unsignedp, enum optab_methods methods,
    686 			 unsigned HOST_WIDE_INT shift_mask)
    687 {
    688   rtx superword_op1, tmp, cmp1, cmp2;
    689   enum rtx_code cmp_code;
    690 
    691   /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
    692      fill the result with sign or zero bits as appropriate.  If so, the value
    693      of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
    694      this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
    695      and INTO_INPUT), then emit code to set up OUTOF_TARGET.
    696 
    697      This isn't worthwhile for constant shifts since the optimizers will
    698      cope better with in-range shift counts.  */
    699   if (shift_mask >= BITS_PER_WORD
    700       && outof_target != 0
    701       && !CONSTANT_P (op1))
    702     {
    703       if (!expand_doubleword_shift (op1_mode, binoptab,
    704 				    outof_input, into_input, op1,
    705 				    0, into_target,
    706 				    unsignedp, methods, shift_mask))
    707 	return false;
    708       if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
    709 			       outof_target, unsignedp, methods))
    710 	return false;
    711       return true;
    712     }
    713 
    714   /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
    715      is true when the effective shift value is less than BITS_PER_WORD.
    716      Set SUPERWORD_OP1 to the shift count that should be used to shift
    717      OUTOF_INPUT into INTO_TARGET when the condition is false.  */
    718   tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
    719   if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
    720     {
    721       /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
    722 	 is a subword shift count.  */
    723       cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
    724 				    0, true, methods);
    725       cmp2 = CONST0_RTX (op1_mode);
    726       cmp_code = EQ;
    727       superword_op1 = op1;
    728     }
    729   else
    730     {
    731       /* Set CMP1 to OP1 - BITS_PER_WORD.  */
    732       cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
    733 				    0, true, methods);
    734       cmp2 = CONST0_RTX (op1_mode);
    735       cmp_code = LT;
    736       superword_op1 = cmp1;
    737     }
    738   if (cmp1 == 0)
    739     return false;
    740 
    741   /* If we can compute the condition at compile time, pick the
    742      appropriate subroutine.  */
    743   tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
    744   if (tmp != 0 && CONST_INT_P (tmp))
    745     {
    746       if (tmp == const0_rtx)
    747 	return expand_superword_shift (binoptab, outof_input, superword_op1,
    748 				       outof_target, into_target,
    749 				       unsignedp, methods);
    750       else
    751 	return expand_subword_shift (op1_mode, binoptab,
    752 				     outof_input, into_input, op1,
    753 				     outof_target, into_target,
    754 				     unsignedp, methods, shift_mask);
    755     }
    756 
    757   /* Try using conditional moves to generate straight-line code.  */
    758   if (HAVE_conditional_move)
    759     {
    760       rtx_insn *start = get_last_insn ();
    761       if (expand_doubleword_shift_condmove (op1_mode, binoptab,
    762 					    cmp_code, cmp1, cmp2,
    763 					    outof_input, into_input,
    764 					    op1, superword_op1,
    765 					    outof_target, into_target,
    766 					    unsignedp, methods, shift_mask))
    767 	return true;
    768       delete_insns_since (start);
    769     }
    770 
    771   /* As a last resort, use branches to select the correct alternative.  */
    772   rtx_code_label *subword_label = gen_label_rtx ();
    773   rtx_code_label *done_label = gen_label_rtx ();
    774 
    775   NO_DEFER_POP;
    776   do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
    777 			   0, 0, subword_label,
    778 			   profile_probability::uninitialized ());
    779   OK_DEFER_POP;
    780 
    781   if (!expand_superword_shift (binoptab, outof_input, superword_op1,
    782 			       outof_target, into_target,
    783 			       unsignedp, methods))
    784     return false;
    785 
    786   emit_jump_insn (targetm.gen_jump (done_label));
    787   emit_barrier ();
    788   emit_label (subword_label);
    789 
    790   if (!expand_subword_shift (op1_mode, binoptab,
    791 			     outof_input, into_input, op1,
    792 			     outof_target, into_target,
    793 			     unsignedp, methods, shift_mask))
    794     return false;
    795 
    796   emit_label (done_label);
    797   return true;
    798 }
    799 
    800 /* Subroutine of expand_binop.  Perform a double word multiplication of
    802    operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
    803    as the target's word_mode.  This function return NULL_RTX if anything
    804    goes wrong, in which case it may have already emitted instructions
    805    which need to be deleted.
    806 
    807    If we want to multiply two two-word values and have normal and widening
    808    multiplies of single-word values, we can do this with three smaller
    809    multiplications.
    810 
    811    The multiplication proceeds as follows:
    812 			         _______________________
    813 			        [__op0_high_|__op0_low__]
    814 			         _______________________
    815         *			[__op1_high_|__op1_low__]
    816         _______________________________________________
    817 			         _______________________
    818     (1)				[__op0_low__*__op1_low__]
    819 		     _______________________
    820     (2a)	    [__op0_low__*__op1_high_]
    821 		     _______________________
    822     (2b)	    [__op0_high_*__op1_low__]
    823          _______________________
    824     (3) [__op0_high_*__op1_high_]
    825 
    826 
    827   This gives a 4-word result.  Since we are only interested in the
    828   lower 2 words, partial result (3) and the upper words of (2a) and
    829   (2b) don't need to be calculated.  Hence (2a) and (2b) can be
    830   calculated using non-widening multiplication.
    831 
    832   (1), however, needs to be calculated with an unsigned widening
    833   multiplication.  If this operation is not directly supported we
    834   try using a signed widening multiplication and adjust the result.
    835   This adjustment works as follows:
    836 
    837       If both operands are positive then no adjustment is needed.
    838 
    839       If the operands have different signs, for example op0_low < 0 and
    840       op1_low >= 0, the instruction treats the most significant bit of
    841       op0_low as a sign bit instead of a bit with significance
    842       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
    843       with 2**BITS_PER_WORD - op0_low, and two's complements the
    844       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
    845       the result.
    846 
    847       Similarly, if both operands are negative, we need to add
    848       (op0_low + op1_low) * 2**BITS_PER_WORD.
    849 
    850       We use a trick to adjust quickly.  We logically shift op0_low right
    851       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
    852       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
    853       logical shift exists, we do an arithmetic right shift and subtract
    854       the 0 or -1.  */
    855 
    856 static rtx
    857 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
    858 		       bool umulp, enum optab_methods methods)
    859 {
    860   int low = (WORDS_BIG_ENDIAN ? 1 : 0);
    861   int high = (WORDS_BIG_ENDIAN ? 0 : 1);
    862   rtx wordm1 = (umulp ? NULL_RTX
    863 		: gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
    864   rtx product, adjust, product_high, temp;
    865 
    866   rtx op0_high = operand_subword_force (op0, high, mode);
    867   rtx op0_low = operand_subword_force (op0, low, mode);
    868   rtx op1_high = operand_subword_force (op1, high, mode);
    869   rtx op1_low = operand_subword_force (op1, low, mode);
    870 
    871   /* If we're using an unsigned multiply to directly compute the product
    872      of the low-order words of the operands and perform any required
    873      adjustments of the operands, we begin by trying two more multiplications
    874      and then computing the appropriate sum.
    875 
    876      We have checked above that the required addition is provided.
    877      Full-word addition will normally always succeed, especially if
    878      it is provided at all, so we don't worry about its failure.  The
    879      multiplication may well fail, however, so we do handle that.  */
    880 
    881   if (!umulp)
    882     {
    883       /* ??? This could be done with emit_store_flag where available.  */
    884       temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
    885 			   NULL_RTX, 1, methods);
    886       if (temp)
    887 	op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
    888 				 NULL_RTX, 0, OPTAB_DIRECT);
    889       else
    890 	{
    891 	  temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
    892 			       NULL_RTX, 0, methods);
    893 	  if (!temp)
    894 	    return NULL_RTX;
    895 	  op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
    896 				   NULL_RTX, 0, OPTAB_DIRECT);
    897 	}
    898 
    899       if (!op0_high)
    900 	return NULL_RTX;
    901     }
    902 
    903   adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
    904 			 NULL_RTX, 0, OPTAB_DIRECT);
    905   if (!adjust)
    906     return NULL_RTX;
    907 
    908   /* OP0_HIGH should now be dead.  */
    909 
    910   if (!umulp)
    911     {
    912       /* ??? This could be done with emit_store_flag where available.  */
    913       temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
    914 			   NULL_RTX, 1, methods);
    915       if (temp)
    916 	op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
    917 				 NULL_RTX, 0, OPTAB_DIRECT);
    918       else
    919 	{
    920 	  temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
    921 			       NULL_RTX, 0, methods);
    922 	  if (!temp)
    923 	    return NULL_RTX;
    924 	  op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
    925 				   NULL_RTX, 0, OPTAB_DIRECT);
    926 	}
    927 
    928       if (!op1_high)
    929 	return NULL_RTX;
    930     }
    931 
    932   temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
    933 		       NULL_RTX, 0, OPTAB_DIRECT);
    934   if (!temp)
    935     return NULL_RTX;
    936 
    937   /* OP1_HIGH should now be dead.  */
    938 
    939   adjust = expand_binop (word_mode, add_optab, adjust, temp,
    940 			 NULL_RTX, 0, OPTAB_DIRECT);
    941 
    942   if (target && !REG_P (target))
    943     target = NULL_RTX;
    944 
    945   /* *_widen_optab needs to determine operand mode, make sure at least
    946      one operand has non-VOID mode.  */
    947   if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
    948     op0_low = force_reg (word_mode, op0_low);
    949 
    950   if (umulp)
    951     product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
    952 			    target, 1, OPTAB_DIRECT);
    953   else
    954     product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
    955 			    target, 1, OPTAB_DIRECT);
    956 
    957   if (!product)
    958     return NULL_RTX;
    959 
    960   product_high = operand_subword (product, high, 1, mode);
    961   adjust = expand_binop (word_mode, add_optab, product_high, adjust,
    962 			 NULL_RTX, 0, OPTAB_DIRECT);
    963   emit_move_insn (product_high, adjust);
    964   return product;
    965 }
    966 
    967 /* Subroutine of expand_binop.  Optimize unsigned double-word OP0 % OP1 for
    968    constant OP1.  If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
    969    (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
    970    computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
    971    + (OP0 >> (2 * bit))) % OP1.  Whether we need to sum 2, 3 or 4 values
    972    depends on the bit value, if 2, then carry from the addition needs to be
    973    added too, i.e. like:
    974    sum += __builtin_add_overflow (low, high, &sum)
    975 
    976    Optimize signed double-word OP0 % OP1 similarly, just apply some correction
    977    factor to the sum before doing unsigned remainder, in the form of
    978    sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
    979    then perform unsigned
    980    remainder = sum % OP1;
    981    and finally
    982    remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1);  */
    983 
    984 static rtx
    985 expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
    986 {
    987   if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
    988     return NULL_RTX;
    989 
    990   rtx_insn *last = get_last_insn ();
    991   for (int bit = BITS_PER_WORD; bit >= BITS_PER_WORD / 2; bit--)
    992     {
    993       wide_int w = wi::shifted_mask (bit, 1, false, 2 * BITS_PER_WORD);
    994       if (wi::ne_p (wi::umod_trunc (w, INTVAL (op1)), 1))
    995 	continue;
    996       rtx sum = NULL_RTX, mask = NULL_RTX;
    997       if (bit == BITS_PER_WORD)
    998 	{
    999 	  /* For signed modulo we need to add correction to the sum
   1000 	     and that might again overflow.  */
   1001 	  if (!unsignedp)
   1002 	    continue;
   1003 	  if (optab_handler (uaddv4_optab, word_mode) == CODE_FOR_nothing)
   1004 	    continue;
   1005 	  tree wtype = lang_hooks.types.type_for_mode (word_mode, 1);
   1006 	  if (wtype == NULL_TREE)
   1007 	    continue;
   1008 	  tree ctype = build_complex_type (wtype);
   1009 	  if (TYPE_MODE (ctype) != GET_MODE_COMPLEX_MODE (word_mode))
   1010 	    continue;
   1011 	  machine_mode cmode = TYPE_MODE (ctype);
   1012 	  rtx op00 = operand_subword_force (op0, 0, mode);
   1013 	  rtx op01 = operand_subword_force (op0, 1, mode);
   1014 	  rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
   1015 				     gen_reg_rtx (word_mode));
   1016 	  tree lhs = make_tree (ctype, cres);
   1017 	  tree arg0 = make_tree (wtype, op00);
   1018 	  tree arg1 = make_tree (wtype, op01);
   1019 	  expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
   1020 				  arg1, true, true, true, false, NULL);
   1021 	  sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
   1022 				     XEXP (cres, 1), NULL_RTX, 1,
   1023 				     OPTAB_DIRECT);
   1024 	  if (sum == NULL_RTX)
   1025 	    return NULL_RTX;
   1026 	}
   1027       else
   1028 	{
   1029 	  /* Code below uses GEN_INT, so we need the masks to be representable
   1030 	     in HOST_WIDE_INTs.  */
   1031 	  if (bit >= HOST_BITS_PER_WIDE_INT)
   1032 	    continue;
   1033 	  /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
   1034 	     overflow.  Consider 64-bit -1ULL for word size 32, if we add
   1035 	     0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1.  */
   1036 	  if (bit == BITS_PER_WORD - 1)
   1037 	    continue;
   1038 
   1039 	  int count = (2 * BITS_PER_WORD + bit - 1) / bit;
   1040 	  rtx sum_corr = NULL_RTX;
   1041 
   1042 	  if (!unsignedp)
   1043 	    {
   1044 	      /* For signed modulo, compute it as unsigned modulo of
   1045 		 sum with a correction added to it if OP0 is negative,
   1046 		 such that the result can be computed as unsigned
   1047 		 remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1).  */
   1048 	      w = wi::min_value (2 * BITS_PER_WORD, SIGNED);
   1049 	      wide_int wmod1 = wi::umod_trunc (w, INTVAL (op1));
   1050 	      wide_int wmod2 = wi::smod_trunc (w, INTVAL (op1));
   1051 	      /* wmod2 == -wmod1.  */
   1052 	      wmod2 = wmod2 + (INTVAL (op1) - 1);
   1053 	      if (wi::ne_p (wmod1, wmod2))
   1054 		{
   1055 		  wide_int wcorr = wmod2 - wmod1;
   1056 		  if (wi::neg_p (w))
   1057 		    wcorr = wcorr + INTVAL (op1);
   1058 		  /* Now verify if the count sums can't overflow, and punt
   1059 		     if they could.  */
   1060 		  w = wi::mask (bit, false, 2 * BITS_PER_WORD);
   1061 		  w = w * (count - 1);
   1062 		  w = w + wi::mask (2 * BITS_PER_WORD - (count - 1) * bit,
   1063 				    false, 2 * BITS_PER_WORD);
   1064 		  w = w + wcorr;
   1065 		  w = wi::lrshift (w, BITS_PER_WORD);
   1066 		  if (wi::ne_p (w, 0))
   1067 		    continue;
   1068 
   1069 		  mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
   1070 						mode);
   1071 		  mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
   1072 					      GEN_INT (BITS_PER_WORD - 1),
   1073 					      NULL_RTX, 0, OPTAB_DIRECT);
   1074 		  if (mask == NULL_RTX)
   1075 		    return NULL_RTX;
   1076 		  sum_corr = immed_wide_int_const (wcorr, word_mode);
   1077 		  sum_corr = expand_simple_binop (word_mode, AND, mask,
   1078 						  sum_corr, NULL_RTX, 1,
   1079 						  OPTAB_DIRECT);
   1080 		  if (sum_corr == NULL_RTX)
   1081 		    return NULL_RTX;
   1082 		}
   1083 	    }
   1084 
   1085 	  for (int i = 0; i < count; i++)
   1086 	    {
   1087 	      rtx v = op0;
   1088 	      if (i)
   1089 		v = expand_simple_binop (mode, LSHIFTRT, v, GEN_INT (i * bit),
   1090 					 NULL_RTX, 1, OPTAB_DIRECT);
   1091 	      if (v == NULL_RTX)
   1092 		return NULL_RTX;
   1093 	      v = lowpart_subreg (word_mode, v, mode);
   1094 	      if (v == NULL_RTX)
   1095 		return NULL_RTX;
   1096 	      if (i != count - 1)
   1097 		v = expand_simple_binop (word_mode, AND, v,
   1098 					 GEN_INT ((HOST_WIDE_INT_1U << bit)
   1099 						  - 1), NULL_RTX, 1,
   1100 					 OPTAB_DIRECT);
   1101 	      if (v == NULL_RTX)
   1102 		return NULL_RTX;
   1103 	      if (sum == NULL_RTX)
   1104 		sum = v;
   1105 	      else
   1106 		sum = expand_simple_binop (word_mode, PLUS, sum, v, NULL_RTX,
   1107 					   1, OPTAB_DIRECT);
   1108 	      if (sum == NULL_RTX)
   1109 		return NULL_RTX;
   1110 	    }
   1111 	  if (sum_corr)
   1112 	    {
   1113 	      sum = expand_simple_binop (word_mode, PLUS, sum, sum_corr,
   1114 					 NULL_RTX, 1, OPTAB_DIRECT);
   1115 	      if (sum == NULL_RTX)
   1116 		return NULL_RTX;
   1117 	    }
   1118 	}
   1119       rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum,
   1120 				     gen_int_mode (INTVAL (op1), word_mode),
   1121 				     NULL_RTX, 1, OPTAB_DIRECT);
   1122       if (remainder == NULL_RTX)
   1123 	return NULL_RTX;
   1124 
   1125       if (!unsignedp)
   1126 	{
   1127 	  if (mask == NULL_RTX)
   1128 	    {
   1129 	      mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
   1130 					    mode);
   1131 	      mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
   1132 					  GEN_INT (BITS_PER_WORD - 1),
   1133 					  NULL_RTX, 0, OPTAB_DIRECT);
   1134 	      if (mask == NULL_RTX)
   1135 		return NULL_RTX;
   1136 	    }
   1137 	  mask = expand_simple_binop (word_mode, AND, mask,
   1138 				      gen_int_mode (1 - INTVAL (op1),
   1139 						    word_mode),
   1140 				      NULL_RTX, 1, OPTAB_DIRECT);
   1141 	  if (mask == NULL_RTX)
   1142 	    return NULL_RTX;
   1143 	  remainder = expand_simple_binop (word_mode, PLUS, remainder,
   1144 					   mask, NULL_RTX, 1, OPTAB_DIRECT);
   1145 	  if (remainder == NULL_RTX)
   1146 	    return NULL_RTX;
   1147 	}
   1148 
   1149       remainder = convert_modes (mode, word_mode, remainder, unsignedp);
   1150       /* Punt if we need any library calls.  */
   1151       if (last)
   1152 	last = NEXT_INSN (last);
   1153       else
   1154 	last = get_insns ();
   1155       for (; last; last = NEXT_INSN (last))
   1156 	if (CALL_P (last))
   1157 	  return NULL_RTX;
   1158       return remainder;
   1159     }
   1160   return NULL_RTX;
   1161 }
   1162 
   1163 /* Similarly to the above function, but compute both quotient and remainder.
   1164    Quotient can be computed from the remainder as:
   1165    rem = op0 % op1;  // Handled using expand_doubleword_mod
   1166    quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
   1167 			     // 2 * BITS_PER_WORD
   1168 
   1169    We can also handle cases where op1 is a multiple of power of two constant
   1170    and constant handled by expand_doubleword_mod.
   1171    op11 = 1 << __builtin_ctz (op1);
   1172    op12 = op1 / op11;
   1173    rem1 = op0 % op12;  // Handled using expand_doubleword_mod
   1174    quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
   1175 			       // 2 * BITS_PER_WORD
   1176    rem = (quot1 % op11) * op12 + rem1;
   1177    quot = quot1 / op11;  */
   1178 
   1179 rtx
   1180 expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
   1181 			  bool unsignedp)
   1182 {
   1183   *rem = NULL_RTX;
   1184 
   1185   /* Negative dividend should have been optimized into positive,
   1186      similarly modulo by 1 and modulo by power of two is optimized
   1187      differently too.  */
   1188   if (INTVAL (op1) <= 1 || pow2p_hwi (INTVAL (op1)))
   1189     return NULL_RTX;
   1190 
   1191   rtx op11 = const1_rtx;
   1192   rtx op12 = op1;
   1193   if ((INTVAL (op1) & 1) == 0)
   1194     {
   1195       int bit = ctz_hwi (INTVAL (op1));
   1196       op11 = GEN_INT (HOST_WIDE_INT_1 << bit);
   1197       op12 = GEN_INT (INTVAL (op1) >> bit);
   1198     }
   1199 
   1200   rtx rem1 = expand_doubleword_mod (mode, op0, op12, unsignedp);
   1201   if (rem1 == NULL_RTX)
   1202     return NULL_RTX;
   1203 
   1204   int prec = 2 * BITS_PER_WORD;
   1205   wide_int a = wide_int::from (INTVAL (op12), prec + 1, UNSIGNED);
   1206   wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
   1207   wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
   1208   rtx inv = immed_wide_int_const (m, mode);
   1209 
   1210   rtx_insn *last = get_last_insn ();
   1211   rtx quot1 = expand_simple_binop (mode, MINUS, op0, rem1,
   1212 				   NULL_RTX, unsignedp, OPTAB_DIRECT);
   1213   if (quot1 == NULL_RTX)
   1214     return NULL_RTX;
   1215 
   1216   quot1 = expand_simple_binop (mode, MULT, quot1, inv,
   1217 			       NULL_RTX, unsignedp, OPTAB_DIRECT);
   1218   if (quot1 == NULL_RTX)
   1219     return NULL_RTX;
   1220 
   1221   if (op11 != const1_rtx)
   1222     {
   1223       rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, quot1, op11,
   1224 				NULL_RTX, unsignedp, OPTAB_DIRECT);
   1225       if (rem2 == NULL_RTX)
   1226 	return NULL_RTX;
   1227 
   1228       rem2 = expand_simple_binop (mode, MULT, rem2, op12, NULL_RTX,
   1229 				  unsignedp, OPTAB_DIRECT);
   1230       if (rem2 == NULL_RTX)
   1231 	return NULL_RTX;
   1232 
   1233       rem2 = expand_simple_binop (mode, PLUS, rem2, rem1, NULL_RTX,
   1234 				  unsignedp, OPTAB_DIRECT);
   1235       if (rem2 == NULL_RTX)
   1236 	return NULL_RTX;
   1237 
   1238       rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, quot1, op11,
   1239 				 NULL_RTX, unsignedp, OPTAB_DIRECT);
   1240       if (quot2 == NULL_RTX)
   1241 	return NULL_RTX;
   1242 
   1243       rem1 = rem2;
   1244       quot1 = quot2;
   1245     }
   1246 
   1247   /* Punt if we need any library calls.  */
   1248   if (last)
   1249     last = NEXT_INSN (last);
   1250   else
   1251     last = get_insns ();
   1252   for (; last; last = NEXT_INSN (last))
   1253     if (CALL_P (last))
   1254       return NULL_RTX;
   1255 
   1256   *rem = rem1;
   1257   return quot1;
   1258 }
   1259 
   1260 /* Wrapper around expand_binop which takes an rtx code to specify
   1262    the operation to perform, not an optab pointer.  All other
   1263    arguments are the same.  */
   1264 rtx
   1265 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
   1266 		     rtx op1, rtx target, int unsignedp,
   1267 		     enum optab_methods methods)
   1268 {
   1269   optab binop = code_to_optab (code);
   1270   gcc_assert (binop);
   1271 
   1272   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
   1273 }
   1274 
   1275 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
   1276    binop.  Order them according to commutative_operand_precedence and, if
   1277    possible, try to put TARGET or a pseudo first.  */
   1278 static bool
   1279 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
   1280 {
   1281   int op0_prec = commutative_operand_precedence (op0);
   1282   int op1_prec = commutative_operand_precedence (op1);
   1283 
   1284   if (op0_prec < op1_prec)
   1285     return true;
   1286 
   1287   if (op0_prec > op1_prec)
   1288     return false;
   1289 
   1290   /* With equal precedence, both orders are ok, but it is better if the
   1291      first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
   1292   if (target == 0 || REG_P (target))
   1293     return (REG_P (op1) && !REG_P (op0)) || target == op1;
   1294   else
   1295     return rtx_equal_p (op1, target);
   1296 }
   1297 
   1298 /* Return true if BINOPTAB implements a shift operation.  */
   1299 
   1300 static bool
   1301 shift_optab_p (optab binoptab)
   1302 {
   1303   switch (optab_to_code (binoptab))
   1304     {
   1305     case ASHIFT:
   1306     case SS_ASHIFT:
   1307     case US_ASHIFT:
   1308     case ASHIFTRT:
   1309     case LSHIFTRT:
   1310     case ROTATE:
   1311     case ROTATERT:
   1312       return true;
   1313 
   1314     default:
   1315       return false;
   1316     }
   1317 }
   1318 
   1319 /* Return true if BINOPTAB implements a commutative binary operation.  */
   1320 
   1321 static bool
   1322 commutative_optab_p (optab binoptab)
   1323 {
   1324   return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
   1325 	  || binoptab == smul_widen_optab
   1326 	  || binoptab == umul_widen_optab
   1327 	  || binoptab == smul_highpart_optab
   1328 	  || binoptab == umul_highpart_optab
   1329 	  || binoptab == vec_widen_sadd_optab
   1330 	  || binoptab == vec_widen_uadd_optab
   1331 	  || binoptab == vec_widen_sadd_hi_optab
   1332 	  || binoptab == vec_widen_sadd_lo_optab
   1333 	  || binoptab == vec_widen_uadd_hi_optab
   1334 	  || binoptab == vec_widen_uadd_lo_optab
   1335 	  || binoptab == vec_widen_sadd_even_optab
   1336 	  || binoptab == vec_widen_sadd_odd_optab
   1337 	  || binoptab == vec_widen_uadd_even_optab
   1338 	  || binoptab == vec_widen_uadd_odd_optab);
   1339 }
   1340 
   1341 /* X is to be used in mode MODE as operand OPN to BINOPTAB.  If we're
   1342    optimizing, and if the operand is a constant that costs more than
   1343    1 instruction, force the constant into a register and return that
   1344    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
   1345 
   1346 static rtx
   1347 avoid_expensive_constant (machine_mode mode, optab binoptab,
   1348 			  int opn, rtx x, bool unsignedp)
   1349 {
   1350   bool speed = optimize_insn_for_speed_p ();
   1351 
   1352   if (mode != VOIDmode
   1353       && optimize
   1354       && CONSTANT_P (x)
   1355       && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
   1356 	  > set_src_cost (x, mode, speed)))
   1357     {
   1358       if (CONST_INT_P (x))
   1359 	{
   1360 	  HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
   1361 	  if (intval != INTVAL (x))
   1362 	    x = GEN_INT (intval);
   1363 	}
   1364       else
   1365 	x = convert_modes (mode, VOIDmode, x, unsignedp);
   1366       x = force_reg (mode, x);
   1367     }
   1368   return x;
   1369 }
   1370 
   1371 /* Helper function for expand_binop: handle the case where there
   1372    is an insn ICODE that directly implements the indicated operation.
   1373    Returns null if this is not possible.  */
   1374 static rtx
   1375 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
   1376 		       rtx op0, rtx op1,
   1377 		       rtx target, int unsignedp, enum optab_methods methods,
   1378 		       rtx_insn *last)
   1379 {
   1380   machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
   1381   machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
   1382   machine_mode mode0, mode1, tmp_mode;
   1383   class expand_operand ops[3];
   1384   bool commutative_p;
   1385   rtx_insn *pat;
   1386   rtx xop0 = op0, xop1 = op1;
   1387   bool canonicalize_op1 = false;
   1388 
   1389   /* If it is a commutative operator and the modes would match
   1390      if we would swap the operands, we can save the conversions.  */
   1391   commutative_p = commutative_optab_p (binoptab);
   1392   if (commutative_p
   1393       && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
   1394       && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode0)
   1395     std::swap (xop0, xop1);
   1396 
   1397   /* If we are optimizing, force expensive constants into a register.  */
   1398   xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
   1399   if (!shift_optab_p (binoptab))
   1400     xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
   1401   else
   1402     /* Shifts and rotates often use a different mode for op1 from op0;
   1403        for VOIDmode constants we don't know the mode, so force it
   1404        to be canonicalized using convert_modes.  */
   1405     canonicalize_op1 = true;
   1406 
   1407   /* In case the insn wants input operands in modes different from
   1408      those of the actual operands, convert the operands.  It would
   1409      seem that we don't need to convert CONST_INTs, but we do, so
   1410      that they're properly zero-extended, sign-extended or truncated
   1411      for their mode.  */
   1412 
   1413   mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
   1414   if (xmode0 != VOIDmode && xmode0 != mode0)
   1415     {
   1416       xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
   1417       mode0 = xmode0;
   1418     }
   1419 
   1420   mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
   1421 	   ? GET_MODE (xop1) : mode);
   1422   if (xmode1 != VOIDmode && xmode1 != mode1)
   1423     {
   1424       xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
   1425       mode1 = xmode1;
   1426     }
   1427 
   1428   /* If operation is commutative,
   1429      try to make the first operand a register.
   1430      Even better, try to make it the same as the target.
   1431      Also try to make the last operand a constant.  */
   1432   if (commutative_p
   1433       && swap_commutative_operands_with_target (target, xop0, xop1))
   1434     std::swap (xop0, xop1);
   1435 
   1436   /* Now, if insn's predicates don't allow our operands, put them into
   1437      pseudo regs.  */
   1438 
   1439   if (binoptab == vec_pack_trunc_optab
   1440       || binoptab == vec_pack_usat_optab
   1441       || binoptab == vec_pack_ssat_optab
   1442       || binoptab == vec_pack_ufix_trunc_optab
   1443       || binoptab == vec_pack_sfix_trunc_optab
   1444       || binoptab == vec_packu_float_optab
   1445       || binoptab == vec_packs_float_optab)
   1446     {
   1447       /* The mode of the result is different then the mode of the
   1448 	 arguments.  */
   1449       tmp_mode = insn_data[(int) icode].operand[0].mode;
   1450       if (VECTOR_MODE_P (mode)
   1451 	  && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
   1452 	{
   1453 	  delete_insns_since (last);
   1454 	  return NULL_RTX;
   1455 	}
   1456     }
   1457   else
   1458     tmp_mode = mode;
   1459 
   1460   create_output_operand (&ops[0], target, tmp_mode);
   1461   create_input_operand (&ops[1], xop0, mode0);
   1462   create_input_operand (&ops[2], xop1, mode1);
   1463   pat = maybe_gen_insn (icode, 3, ops);
   1464   if (pat)
   1465     {
   1466       /* If PAT is composed of more than one insn, try to add an appropriate
   1467 	 REG_EQUAL note to it.  If we can't because TEMP conflicts with an
   1468 	 operand, call expand_binop again, this time without a target.  */
   1469       if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
   1470 	  && ! add_equal_note (pat, ops[0].value,
   1471 			       optab_to_code (binoptab),
   1472 			       ops[1].value, ops[2].value, mode0))
   1473 	{
   1474 	  delete_insns_since (last);
   1475 	  return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
   1476 			       unsignedp, methods);
   1477 	}
   1478 
   1479       emit_insn (pat);
   1480       return ops[0].value;
   1481     }
   1482   delete_insns_since (last);
   1483   return NULL_RTX;
   1484 }
   1485 
   1486 /* Generate code to perform an operation specified by BINOPTAB
   1487    on operands OP0 and OP1, with result having machine-mode MODE.
   1488 
   1489    UNSIGNEDP is for the case where we have to widen the operands
   1490    to perform the operation.  It says to use zero-extension.
   1491 
   1492    If TARGET is nonzero, the value
   1493    is generated there, if it is convenient to do so.
   1494    In all cases an rtx is returned for the locus of the value;
   1495    this may or may not be TARGET.  */
   1496 
   1497 rtx
   1498 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
   1499 	      rtx target, int unsignedp, enum optab_methods methods)
   1500 {
   1501   enum optab_methods next_methods
   1502     = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
   1503        ? OPTAB_WIDEN : methods);
   1504   enum mode_class mclass;
   1505   enum insn_code icode;
   1506   machine_mode wider_mode;
   1507   scalar_int_mode int_mode;
   1508   rtx libfunc;
   1509   rtx temp;
   1510   rtx_insn *entry_last = get_last_insn ();
   1511   rtx_insn *last;
   1512 
   1513   mclass = GET_MODE_CLASS (mode);
   1514 
   1515   /* If subtracting an integer constant, convert this into an addition of
   1516      the negated constant.  */
   1517 
   1518   if (binoptab == sub_optab && CONST_INT_P (op1))
   1519     {
   1520       op1 = negate_rtx (mode, op1);
   1521       binoptab = add_optab;
   1522     }
   1523   /* For shifts, constant invalid op1 might be expanded from different
   1524      mode than MODE.  As those are invalid, force them to a register
   1525      to avoid further problems during expansion.  */
   1526   else if (CONST_INT_P (op1)
   1527 	   && shift_optab_p (binoptab)
   1528 	   && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
   1529     {
   1530       op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
   1531       op1 = force_reg (GET_MODE_INNER (mode), op1);
   1532     }
   1533 
   1534   /* Record where to delete back to if we backtrack.  */
   1535   last = get_last_insn ();
   1536 
   1537   /* If we can do it with a three-operand insn, do so.  */
   1538 
   1539   if (methods != OPTAB_MUST_WIDEN)
   1540     {
   1541       if (convert_optab_p (binoptab))
   1542 	{
   1543 	  machine_mode from_mode = widened_mode (mode, op0, op1);
   1544 	  icode = find_widening_optab_handler (binoptab, mode, from_mode);
   1545 	}
   1546       else
   1547 	icode = optab_handler (binoptab, mode);
   1548       if (icode != CODE_FOR_nothing)
   1549 	{
   1550 	  temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
   1551 					target, unsignedp, methods, last);
   1552 	  if (temp)
   1553 	    return temp;
   1554 	}
   1555     }
   1556 
   1557   /* If we were trying to rotate, and that didn't work, try rotating
   1558      the other direction before falling back to shifts and bitwise-or.  */
   1559   if (((binoptab == rotl_optab
   1560 	&& (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
   1561        || (binoptab == rotr_optab
   1562 	   && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
   1563       && is_int_mode (mode, &int_mode))
   1564     {
   1565       optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
   1566       rtx newop1;
   1567       unsigned int bits = GET_MODE_PRECISION (int_mode);
   1568 
   1569       if (CONST_INT_P (op1))
   1570 	newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
   1571       else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
   1572         newop1 = negate_rtx (GET_MODE (op1), op1);
   1573       else
   1574         newop1 = expand_binop (GET_MODE (op1), sub_optab,
   1575 			       gen_int_mode (bits, GET_MODE (op1)), op1,
   1576 			       NULL_RTX, unsignedp, OPTAB_DIRECT);
   1577 
   1578       temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
   1579 				    target, unsignedp, methods, last);
   1580       if (temp)
   1581 	return temp;
   1582     }
   1583 
   1584   /* If this is a multiply, see if we can do a widening operation that
   1585      takes operands of this mode and makes a wider mode.  */
   1586 
   1587   if (binoptab == smul_optab
   1588       && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
   1589       && (convert_optab_handler ((unsignedp
   1590 				  ? umul_widen_optab
   1591 				  : smul_widen_optab),
   1592 				 wider_mode, mode) != CODE_FOR_nothing))
   1593     {
   1594       /* *_widen_optab needs to determine operand mode, make sure at least
   1595 	 one operand has non-VOID mode.  */
   1596       if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   1597 	op0 = force_reg (mode, op0);
   1598       temp = expand_binop (wider_mode,
   1599 			   unsignedp ? umul_widen_optab : smul_widen_optab,
   1600 			   op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
   1601 
   1602       if (temp != 0)
   1603 	{
   1604 	  if (GET_MODE_CLASS (mode) == MODE_INT
   1605 	      && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
   1606 	    return gen_lowpart (mode, temp);
   1607 	  else
   1608 	    return convert_to_mode (mode, temp, unsignedp);
   1609 	}
   1610     }
   1611 
   1612   /* If this is a vector shift by a scalar, see if we can do a vector
   1613      shift by a vector.  If so, broadcast the scalar into a vector.  */
   1614   if (mclass == MODE_VECTOR_INT)
   1615     {
   1616       optab otheroptab = unknown_optab;
   1617 
   1618       if (binoptab == ashl_optab)
   1619 	otheroptab = vashl_optab;
   1620       else if (binoptab == ashr_optab)
   1621 	otheroptab = vashr_optab;
   1622       else if (binoptab == lshr_optab)
   1623 	otheroptab = vlshr_optab;
   1624       else if (binoptab == rotl_optab)
   1625 	otheroptab = vrotl_optab;
   1626       else if (binoptab == rotr_optab)
   1627 	otheroptab = vrotr_optab;
   1628 
   1629       if (otheroptab
   1630 	  && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
   1631 	{
   1632 	  /* The scalar may have been extended to be too wide.  Truncate
   1633 	     it back to the proper size to fit in the broadcast vector.  */
   1634 	  scalar_mode inner_mode = GET_MODE_INNER (mode);
   1635 	  if (!CONST_INT_P (op1)
   1636 	      && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
   1637 		  > GET_MODE_BITSIZE (inner_mode)))
   1638 	    op1 = force_reg (inner_mode,
   1639 			     simplify_gen_unary (TRUNCATE, inner_mode, op1,
   1640 						 GET_MODE (op1)));
   1641 	  rtx vop1 = expand_vector_broadcast (mode, op1);
   1642 	  if (vop1)
   1643 	    {
   1644 	      temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
   1645 					    target, unsignedp, methods, last);
   1646 	      if (temp)
   1647 		return temp;
   1648 	    }
   1649 	}
   1650     }
   1651 
   1652   /* Look for a wider mode of the same class for which we think we
   1653      can open-code the operation.  Check for a widening multiply at the
   1654      wider mode as well.  */
   1655 
   1656   if (CLASS_HAS_WIDER_MODES_P (mclass)
   1657       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
   1658     FOR_EACH_WIDER_MODE (wider_mode, mode)
   1659       {
   1660 	machine_mode next_mode;
   1661 	if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
   1662 	    || (binoptab == smul_optab
   1663 		&& GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
   1664 		&& (find_widening_optab_handler ((unsignedp
   1665 						  ? umul_widen_optab
   1666 						  : smul_widen_optab),
   1667 						 next_mode, mode)
   1668 		    != CODE_FOR_nothing)))
   1669 	  {
   1670 	    rtx xop0 = op0, xop1 = op1;
   1671 	    bool no_extend = false;
   1672 
   1673 	    /* For certain integer operations, we need not actually extend
   1674 	       the narrow operands, as long as we will truncate
   1675 	       the results to the same narrowness.  */
   1676 
   1677 	    if ((binoptab == ior_optab || binoptab == and_optab
   1678 		 || binoptab == xor_optab
   1679 		 || binoptab == add_optab || binoptab == sub_optab
   1680 		 || binoptab == smul_optab || binoptab == ashl_optab)
   1681 		&& mclass == MODE_INT)
   1682 	      {
   1683 		no_extend = true;
   1684 		xop0 = avoid_expensive_constant (mode, binoptab, 0,
   1685 						 xop0, unsignedp);
   1686 		if (binoptab != ashl_optab)
   1687 		  xop1 = avoid_expensive_constant (mode, binoptab, 1,
   1688 						   xop1, unsignedp);
   1689 	      }
   1690 
   1691 	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
   1692 
   1693 	    /* The second operand of a shift must always be extended.  */
   1694 	    xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
   1695 				  no_extend && binoptab != ashl_optab);
   1696 
   1697 	    temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
   1698 				 unsignedp, OPTAB_DIRECT);
   1699 	    if (temp)
   1700 	      {
   1701 		if (mclass != MODE_INT
   1702                     || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
   1703 		  {
   1704 		    if (target == 0)
   1705 		      target = gen_reg_rtx (mode);
   1706 		    convert_move (target, temp, 0);
   1707 		    return target;
   1708 		  }
   1709 		else
   1710 		  return gen_lowpart (mode, temp);
   1711 	      }
   1712 	    else
   1713 	      delete_insns_since (last);
   1714 	  }
   1715       }
   1716 
   1717   /* If operation is commutative,
   1718      try to make the first operand a register.
   1719      Even better, try to make it the same as the target.
   1720      Also try to make the last operand a constant.  */
   1721   if (commutative_optab_p (binoptab)
   1722       && swap_commutative_operands_with_target (target, op0, op1))
   1723     std::swap (op0, op1);
   1724 
   1725   /* These can be done a word at a time.  */
   1726   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
   1727       && is_int_mode (mode, &int_mode)
   1728       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
   1729       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
   1730     {
   1731       int i;
   1732       rtx_insn *insns;
   1733 
   1734       /* If TARGET is the same as one of the operands, the REG_EQUAL note
   1735 	 won't be accurate, so use a new target.  */
   1736       if (target == 0
   1737 	  || target == op0
   1738 	  || target == op1
   1739 	  || reg_overlap_mentioned_p (target, op0)
   1740 	  || reg_overlap_mentioned_p (target, op1)
   1741 	  || !valid_multiword_target_p (target))
   1742 	target = gen_reg_rtx (int_mode);
   1743 
   1744       start_sequence ();
   1745 
   1746       /* Do the actual arithmetic.  */
   1747       machine_mode op0_mode = GET_MODE (op0);
   1748       machine_mode op1_mode = GET_MODE (op1);
   1749       if (op0_mode == VOIDmode)
   1750 	op0_mode = int_mode;
   1751       if (op1_mode == VOIDmode)
   1752 	op1_mode = int_mode;
   1753       for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
   1754 	{
   1755 	  rtx target_piece = operand_subword (target, i, 1, int_mode);
   1756 	  rtx x = expand_binop (word_mode, binoptab,
   1757 				operand_subword_force (op0, i, op0_mode),
   1758 				operand_subword_force (op1, i, op1_mode),
   1759 				target_piece, unsignedp, next_methods);
   1760 
   1761 	  if (x == 0)
   1762 	    break;
   1763 
   1764 	  if (target_piece != x)
   1765 	    emit_move_insn (target_piece, x);
   1766 	}
   1767 
   1768       insns = get_insns ();
   1769       end_sequence ();
   1770 
   1771       if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
   1772 	{
   1773 	  emit_insn (insns);
   1774 	  return target;
   1775 	}
   1776     }
   1777 
   1778   /* Synthesize double word shifts from single word shifts.  */
   1779   if ((binoptab == lshr_optab || binoptab == ashl_optab
   1780        || binoptab == ashr_optab)
   1781       && is_int_mode (mode, &int_mode)
   1782       && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
   1783       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   1784       && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
   1785       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
   1786       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
   1787       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
   1788     {
   1789       unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
   1790       scalar_int_mode op1_mode;
   1791 
   1792       double_shift_mask = targetm.shift_truncation_mask (int_mode);
   1793       shift_mask = targetm.shift_truncation_mask (word_mode);
   1794       op1_mode = (GET_MODE (op1) != VOIDmode
   1795 		  ? as_a <scalar_int_mode> (GET_MODE (op1))
   1796 		  : word_mode);
   1797 
   1798       /* Apply the truncation to constant shifts.  */
   1799       if (double_shift_mask > 0 && CONST_INT_P (op1))
   1800 	op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
   1801 
   1802       if (op1 == CONST0_RTX (op1_mode))
   1803 	return op0;
   1804 
   1805       /* Make sure that this is a combination that expand_doubleword_shift
   1806 	 can handle.  See the comments there for details.  */
   1807       if (double_shift_mask == 0
   1808 	  || (shift_mask == BITS_PER_WORD - 1
   1809 	      && double_shift_mask == BITS_PER_WORD * 2 - 1))
   1810 	{
   1811 	  rtx_insn *insns;
   1812 	  rtx into_target, outof_target;
   1813 	  rtx into_input, outof_input;
   1814 	  int left_shift, outof_word;
   1815 
   1816 	  /* If TARGET is the same as one of the operands, the REG_EQUAL note
   1817 	     won't be accurate, so use a new target.  */
   1818 	  if (target == 0
   1819 	      || target == op0
   1820 	      || target == op1
   1821 	      || reg_overlap_mentioned_p (target, op0)
   1822 	      || reg_overlap_mentioned_p (target, op1)
   1823 	      || !valid_multiword_target_p (target))
   1824 	    target = gen_reg_rtx (int_mode);
   1825 
   1826 	  start_sequence ();
   1827 
   1828 	  /* OUTOF_* is the word we are shifting bits away from, and
   1829 	     INTO_* is the word that we are shifting bits towards, thus
   1830 	     they differ depending on the direction of the shift and
   1831 	     WORDS_BIG_ENDIAN.  */
   1832 
   1833 	  left_shift = binoptab == ashl_optab;
   1834 	  outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
   1835 
   1836 	  outof_target = operand_subword (target, outof_word, 1, int_mode);
   1837 	  into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
   1838 
   1839 	  outof_input = operand_subword_force (op0, outof_word, int_mode);
   1840 	  into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
   1841 
   1842 	  if (expand_doubleword_shift (op1_mode, binoptab,
   1843 				       outof_input, into_input, op1,
   1844 				       outof_target, into_target,
   1845 				       unsignedp, next_methods, shift_mask))
   1846 	    {
   1847 	      insns = get_insns ();
   1848 	      end_sequence ();
   1849 
   1850 	      emit_insn (insns);
   1851 	      return target;
   1852 	    }
   1853 	  end_sequence ();
   1854 	}
   1855     }
   1856 
   1857   /* Synthesize double word rotates from single word shifts.  */
   1858   if ((binoptab == rotl_optab || binoptab == rotr_optab)
   1859       && is_int_mode (mode, &int_mode)
   1860       && CONST_INT_P (op1)
   1861       && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
   1862       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
   1863       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
   1864     {
   1865       rtx_insn *insns;
   1866       rtx into_target, outof_target;
   1867       rtx into_input, outof_input;
   1868       rtx inter;
   1869       int shift_count, left_shift, outof_word;
   1870 
   1871       /* If TARGET is the same as one of the operands, the REG_EQUAL note
   1872 	 won't be accurate, so use a new target. Do this also if target is not
   1873 	 a REG, first because having a register instead may open optimization
   1874 	 opportunities, and second because if target and op0 happen to be MEMs
   1875 	 designating the same location, we would risk clobbering it too early
   1876 	 in the code sequence we generate below.  */
   1877       if (target == 0
   1878 	  || target == op0
   1879 	  || target == op1
   1880 	  || !REG_P (target)
   1881 	  || reg_overlap_mentioned_p (target, op0)
   1882 	  || reg_overlap_mentioned_p (target, op1)
   1883 	  || !valid_multiword_target_p (target))
   1884 	target = gen_reg_rtx (int_mode);
   1885 
   1886       start_sequence ();
   1887 
   1888       shift_count = INTVAL (op1);
   1889 
   1890       /* OUTOF_* is the word we are shifting bits away from, and
   1891 	 INTO_* is the word that we are shifting bits towards, thus
   1892 	 they differ depending on the direction of the shift and
   1893 	 WORDS_BIG_ENDIAN.  */
   1894 
   1895       left_shift = (binoptab == rotl_optab);
   1896       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
   1897 
   1898       outof_target = operand_subword (target, outof_word, 1, int_mode);
   1899       into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
   1900 
   1901       outof_input = operand_subword_force (op0, outof_word, int_mode);
   1902       into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
   1903 
   1904       if (shift_count == BITS_PER_WORD)
   1905 	{
   1906 	  /* This is just a word swap.  */
   1907 	  emit_move_insn (outof_target, into_input);
   1908 	  emit_move_insn (into_target, outof_input);
   1909 	  inter = const0_rtx;
   1910 	}
   1911       else
   1912 	{
   1913 	  rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
   1914 	  HOST_WIDE_INT first_shift_count, second_shift_count;
   1915 	  optab reverse_unsigned_shift, unsigned_shift;
   1916 
   1917 	  reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
   1918 				    ? lshr_optab : ashl_optab);
   1919 
   1920 	  unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
   1921 			    ? ashl_optab : lshr_optab);
   1922 
   1923 	  if (shift_count > BITS_PER_WORD)
   1924 	    {
   1925 	      first_shift_count = shift_count - BITS_PER_WORD;
   1926 	      second_shift_count = 2 * BITS_PER_WORD - shift_count;
   1927 	    }
   1928 	  else
   1929 	    {
   1930 	      first_shift_count = BITS_PER_WORD - shift_count;
   1931 	      second_shift_count = shift_count;
   1932 	    }
   1933 	  rtx first_shift_count_rtx
   1934 	    = gen_int_shift_amount (word_mode, first_shift_count);
   1935 	  rtx second_shift_count_rtx
   1936 	    = gen_int_shift_amount (word_mode, second_shift_count);
   1937 
   1938 	  into_temp1 = expand_binop (word_mode, unsigned_shift,
   1939 				     outof_input, first_shift_count_rtx,
   1940 				     NULL_RTX, unsignedp, next_methods);
   1941 	  into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
   1942 				     into_input, second_shift_count_rtx,
   1943 				     NULL_RTX, unsignedp, next_methods);
   1944 
   1945 	  if (into_temp1 != 0 && into_temp2 != 0)
   1946 	    inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
   1947 				  into_target, unsignedp, next_methods);
   1948 	  else
   1949 	    inter = 0;
   1950 
   1951 	  if (inter != 0 && inter != into_target)
   1952 	    emit_move_insn (into_target, inter);
   1953 
   1954 	  outof_temp1 = expand_binop (word_mode, unsigned_shift,
   1955 				      into_input, first_shift_count_rtx,
   1956 				      NULL_RTX, unsignedp, next_methods);
   1957 	  outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
   1958 				      outof_input, second_shift_count_rtx,
   1959 				      NULL_RTX, unsignedp, next_methods);
   1960 
   1961 	  if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
   1962 	    inter = expand_binop (word_mode, ior_optab,
   1963 				  outof_temp1, outof_temp2,
   1964 				  outof_target, unsignedp, next_methods);
   1965 
   1966 	  if (inter != 0 && inter != outof_target)
   1967 	    emit_move_insn (outof_target, inter);
   1968 	}
   1969 
   1970       insns = get_insns ();
   1971       end_sequence ();
   1972 
   1973       if (inter != 0)
   1974 	{
   1975 	  emit_insn (insns);
   1976 	  return target;
   1977 	}
   1978     }
   1979 
   1980   /* These can be done a word at a time by propagating carries.  */
   1981   if ((binoptab == add_optab || binoptab == sub_optab)
   1982       && is_int_mode (mode, &int_mode)
   1983       && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
   1984       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
   1985     {
   1986       unsigned int i;
   1987       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
   1988       const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
   1989       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
   1990       rtx xop0, xop1, xtarget;
   1991 
   1992       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
   1993 	 value is one of those, use it.  Otherwise, use 1 since it is the
   1994 	 one easiest to get.  */
   1995 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
   1996       int normalizep = STORE_FLAG_VALUE;
   1997 #else
   1998       int normalizep = 1;
   1999 #endif
   2000 
   2001       /* Prepare the operands.  */
   2002       xop0 = force_reg (int_mode, op0);
   2003       xop1 = force_reg (int_mode, op1);
   2004 
   2005       xtarget = gen_reg_rtx (int_mode);
   2006 
   2007       if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
   2008 	target = xtarget;
   2009 
   2010       /* Indicate for flow that the entire target reg is being set.  */
   2011       if (REG_P (target))
   2012 	emit_clobber (xtarget);
   2013 
   2014       /* Do the actual arithmetic.  */
   2015       for (i = 0; i < nwords; i++)
   2016 	{
   2017 	  int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
   2018 	  rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
   2019 	  rtx op0_piece = operand_subword_force (xop0, index, int_mode);
   2020 	  rtx op1_piece = operand_subword_force (xop1, index, int_mode);
   2021 	  rtx x;
   2022 
   2023 	  /* Main add/subtract of the input operands.  */
   2024 	  x = expand_binop (word_mode, binoptab,
   2025 			    op0_piece, op1_piece,
   2026 			    target_piece, unsignedp, next_methods);
   2027 	  if (x == 0)
   2028 	    break;
   2029 
   2030 	  if (i + 1 < nwords)
   2031 	    {
   2032 	      /* Store carry from main add/subtract.  */
   2033 	      carry_out = gen_reg_rtx (word_mode);
   2034 	      carry_out = emit_store_flag_force (carry_out,
   2035 						 (binoptab == add_optab
   2036 						  ? LT : GT),
   2037 						 x, op0_piece,
   2038 						 word_mode, 1, normalizep);
   2039 	    }
   2040 
   2041 	  if (i > 0)
   2042 	    {
   2043 	      rtx newx;
   2044 
   2045 	      /* Add/subtract previous carry to main result.  */
   2046 	      newx = expand_binop (word_mode,
   2047 				   normalizep == 1 ? binoptab : otheroptab,
   2048 				   x, carry_in,
   2049 				   NULL_RTX, 1, next_methods);
   2050 
   2051 	      if (i + 1 < nwords)
   2052 		{
   2053 		  /* Get out carry from adding/subtracting carry in.  */
   2054 		  rtx carry_tmp = gen_reg_rtx (word_mode);
   2055 		  carry_tmp = emit_store_flag_force (carry_tmp,
   2056 						     (binoptab == add_optab
   2057 						      ? LT : GT),
   2058 						     newx, x,
   2059 						     word_mode, 1, normalizep);
   2060 
   2061 		  /* Logical-ior the two poss. carry together.  */
   2062 		  carry_out = expand_binop (word_mode, ior_optab,
   2063 					    carry_out, carry_tmp,
   2064 					    carry_out, 0, next_methods);
   2065 		  if (carry_out == 0)
   2066 		    break;
   2067 		}
   2068 	      emit_move_insn (target_piece, newx);
   2069 	    }
   2070 	  else
   2071 	    {
   2072 	      if (x != target_piece)
   2073 		emit_move_insn (target_piece, x);
   2074 	    }
   2075 
   2076 	  carry_in = carry_out;
   2077 	}
   2078 
   2079       if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
   2080 	{
   2081 	  if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
   2082 	      || ! rtx_equal_p (target, xtarget))
   2083 	    {
   2084 	      rtx_insn *temp = emit_move_insn (target, xtarget);
   2085 
   2086 	      set_dst_reg_note (temp, REG_EQUAL,
   2087 				gen_rtx_fmt_ee (optab_to_code (binoptab),
   2088 						int_mode, copy_rtx (xop0),
   2089 						copy_rtx (xop1)),
   2090 				target);
   2091 	    }
   2092 	  else
   2093 	    target = xtarget;
   2094 
   2095 	  return target;
   2096 	}
   2097 
   2098       else
   2099 	delete_insns_since (last);
   2100     }
   2101 
   2102   /* Attempt to synthesize double word multiplies using a sequence of word
   2103      mode multiplications.  We first attempt to generate a sequence using a
   2104      more efficient unsigned widening multiply, and if that fails we then
   2105      try using a signed widening multiply.  */
   2106 
   2107   if (binoptab == smul_optab
   2108       && is_int_mode (mode, &int_mode)
   2109       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   2110       && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
   2111       && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
   2112     {
   2113       rtx product = NULL_RTX;
   2114       if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
   2115 	  != CODE_FOR_nothing)
   2116 	{
   2117 	  product = expand_doubleword_mult (int_mode, op0, op1, target,
   2118 					    true, methods);
   2119 	  if (!product)
   2120 	    delete_insns_since (last);
   2121 	}
   2122 
   2123       if (product == NULL_RTX
   2124 	  && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
   2125 	      != CODE_FOR_nothing))
   2126 	{
   2127 	  product = expand_doubleword_mult (int_mode, op0, op1, target,
   2128 					    false, methods);
   2129 	  if (!product)
   2130 	    delete_insns_since (last);
   2131 	}
   2132 
   2133       if (product != NULL_RTX)
   2134 	{
   2135 	  if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
   2136 	    {
   2137 	      rtx_insn *move = emit_move_insn (target ? target : product,
   2138 					       product);
   2139 	      set_dst_reg_note (move,
   2140 				REG_EQUAL,
   2141 				gen_rtx_fmt_ee (MULT, int_mode,
   2142 						copy_rtx (op0),
   2143 						copy_rtx (op1)),
   2144 				target ? target : product);
   2145 	    }
   2146 	  return product;
   2147 	}
   2148     }
   2149 
   2150   /* Attempt to synthetize double word modulo by constant divisor.  */
   2151   if ((binoptab == umod_optab
   2152        || binoptab == smod_optab
   2153        || binoptab == udiv_optab
   2154        || binoptab == sdiv_optab)
   2155       && optimize
   2156       && CONST_INT_P (op1)
   2157       && is_int_mode (mode, &int_mode)
   2158       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   2159       && optab_handler ((binoptab == umod_optab || binoptab == udiv_optab)
   2160 			? udivmod_optab : sdivmod_optab,
   2161 			int_mode) == CODE_FOR_nothing
   2162       && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
   2163       && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
   2164       && optimize_insn_for_speed_p ())
   2165     {
   2166       rtx res = NULL_RTX;
   2167       if ((binoptab == umod_optab || binoptab == smod_optab)
   2168 	  && (INTVAL (op1) & 1) == 0)
   2169 	res = expand_doubleword_mod (int_mode, op0, op1,
   2170 				     binoptab == umod_optab);
   2171       else
   2172 	{
   2173 	  rtx quot = expand_doubleword_divmod (int_mode, op0, op1, &res,
   2174 					       binoptab == umod_optab
   2175 					       || binoptab == udiv_optab);
   2176 	  if (quot == NULL_RTX)
   2177 	    res = NULL_RTX;
   2178 	  else if (binoptab == udiv_optab || binoptab == sdiv_optab)
   2179 	    res = quot;
   2180 	}
   2181       if (res != NULL_RTX)
   2182 	{
   2183 	  if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
   2184 	    {
   2185 	      rtx_insn *move = emit_move_insn (target ? target : res,
   2186 					       res);
   2187 	      set_dst_reg_note (move, REG_EQUAL,
   2188 				gen_rtx_fmt_ee (optab_to_code (binoptab),
   2189 						int_mode, copy_rtx (op0), op1),
   2190 				target ? target : res);
   2191 	    }
   2192 	  return res;
   2193 	}
   2194       else
   2195 	delete_insns_since (last);
   2196     }
   2197 
   2198   /* It can't be open-coded in this mode.
   2199      Use a library call if one is available and caller says that's ok.  */
   2200 
   2201   libfunc = optab_libfunc (binoptab, mode);
   2202   if (libfunc
   2203       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
   2204     {
   2205       rtx_insn *insns;
   2206       rtx op1x = op1;
   2207       machine_mode op1_mode = mode;
   2208       rtx value;
   2209 
   2210       start_sequence ();
   2211 
   2212       if (shift_optab_p (binoptab))
   2213 	{
   2214 	  op1_mode = targetm.libgcc_shift_count_mode ();
   2215 	  /* Specify unsigned here,
   2216 	     since negative shift counts are meaningless.  */
   2217 	  op1x = convert_to_mode (op1_mode, op1, 1);
   2218 	}
   2219 
   2220       if (GET_MODE (op0) != VOIDmode
   2221 	  && GET_MODE (op0) != mode)
   2222 	op0 = convert_to_mode (mode, op0, unsignedp);
   2223 
   2224       /* Pass 1 for NO_QUEUE so we don't lose any increments
   2225 	 if the libcall is cse'd or moved.  */
   2226       value = emit_library_call_value (libfunc,
   2227 				       NULL_RTX, LCT_CONST, mode,
   2228 				       op0, mode, op1x, op1_mode);
   2229 
   2230       insns = get_insns ();
   2231       end_sequence ();
   2232 
   2233       bool trapv = trapv_binoptab_p (binoptab);
   2234       target = gen_reg_rtx (mode);
   2235       emit_libcall_block_1 (insns, target, value,
   2236 			    trapv ? NULL_RTX
   2237 			    : gen_rtx_fmt_ee (optab_to_code (binoptab),
   2238 					      mode, op0, op1), trapv);
   2239 
   2240       return target;
   2241     }
   2242 
   2243   delete_insns_since (last);
   2244 
   2245   /* It can't be done in this mode.  Can we do it in a wider mode?  */
   2246 
   2247   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
   2248 	 || methods == OPTAB_MUST_WIDEN))
   2249     {
   2250       /* Caller says, don't even try.  */
   2251       delete_insns_since (entry_last);
   2252       return 0;
   2253     }
   2254 
   2255   /* Compute the value of METHODS to pass to recursive calls.
   2256      Don't allow widening to be tried recursively.  */
   2257 
   2258   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
   2259 
   2260   /* Look for a wider mode of the same class for which it appears we can do
   2261      the operation.  */
   2262 
   2263   if (CLASS_HAS_WIDER_MODES_P (mclass))
   2264     {
   2265       /* This code doesn't make sense for conversion optabs, since we
   2266 	 wouldn't then want to extend the operands to be the same size
   2267 	 as the result.  */
   2268       gcc_assert (!convert_optab_p (binoptab));
   2269       FOR_EACH_WIDER_MODE (wider_mode, mode)
   2270 	{
   2271 	  if (optab_handler (binoptab, wider_mode)
   2272 	      || (methods == OPTAB_LIB
   2273 		  && optab_libfunc (binoptab, wider_mode)))
   2274 	    {
   2275 	      rtx xop0 = op0, xop1 = op1;
   2276 	      bool no_extend = false;
   2277 
   2278 	      /* For certain integer operations, we need not actually extend
   2279 		 the narrow operands, as long as we will truncate
   2280 		 the results to the same narrowness.  */
   2281 
   2282 	      if ((binoptab == ior_optab || binoptab == and_optab
   2283 		   || binoptab == xor_optab
   2284 		   || binoptab == add_optab || binoptab == sub_optab
   2285 		   || binoptab == smul_optab || binoptab == ashl_optab)
   2286 		  && mclass == MODE_INT)
   2287 		no_extend = true;
   2288 
   2289 	      xop0 = widen_operand (xop0, wider_mode, mode,
   2290 				    unsignedp, no_extend);
   2291 
   2292 	      /* The second operand of a shift must always be extended.  */
   2293 	      xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
   2294 				    no_extend && binoptab != ashl_optab);
   2295 
   2296 	      temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
   2297 				   unsignedp, methods);
   2298 	      if (temp)
   2299 		{
   2300 		  if (mclass != MODE_INT
   2301 		      || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
   2302 		    {
   2303 		      if (target == 0)
   2304 			target = gen_reg_rtx (mode);
   2305 		      convert_move (target, temp, 0);
   2306 		      return target;
   2307 		    }
   2308 		  else
   2309 		    return gen_lowpart (mode, temp);
   2310 		}
   2311 	      else
   2312 		delete_insns_since (last);
   2313 	    }
   2314 	}
   2315     }
   2316 
   2317   delete_insns_since (entry_last);
   2318   return 0;
   2319 }
   2320 
   2321 /* Expand a binary operator which has both signed and unsigned forms.
   2323    UOPTAB is the optab for unsigned operations, and SOPTAB is for
   2324    signed operations.
   2325 
   2326    If we widen unsigned operands, we may use a signed wider operation instead
   2327    of an unsigned wider operation, since the result would be the same.  */
   2328 
   2329 rtx
   2330 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
   2331 		   rtx op0, rtx op1, rtx target, int unsignedp,
   2332 		   enum optab_methods methods)
   2333 {
   2334   rtx temp;
   2335   optab direct_optab = unsignedp ? uoptab : soptab;
   2336   bool save_enable;
   2337 
   2338   /* Do it without widening, if possible.  */
   2339   temp = expand_binop (mode, direct_optab, op0, op1, target,
   2340 		       unsignedp, OPTAB_DIRECT);
   2341   if (temp || methods == OPTAB_DIRECT)
   2342     return temp;
   2343 
   2344   /* Try widening to a signed int.  Disable any direct use of any
   2345      signed insn in the current mode.  */
   2346   save_enable = swap_optab_enable (soptab, mode, false);
   2347 
   2348   temp = expand_binop (mode, soptab, op0, op1, target,
   2349 		       unsignedp, OPTAB_WIDEN);
   2350 
   2351   /* For unsigned operands, try widening to an unsigned int.  */
   2352   if (!temp && unsignedp)
   2353     temp = expand_binop (mode, uoptab, op0, op1, target,
   2354 			 unsignedp, OPTAB_WIDEN);
   2355   if (temp || methods == OPTAB_WIDEN)
   2356     goto egress;
   2357 
   2358   /* Use the right width libcall if that exists.  */
   2359   temp = expand_binop (mode, direct_optab, op0, op1, target,
   2360 		       unsignedp, OPTAB_LIB);
   2361   if (temp || methods == OPTAB_LIB)
   2362     goto egress;
   2363 
   2364   /* Must widen and use a libcall, use either signed or unsigned.  */
   2365   temp = expand_binop (mode, soptab, op0, op1, target,
   2366 		       unsignedp, methods);
   2367   if (!temp && unsignedp)
   2368     temp = expand_binop (mode, uoptab, op0, op1, target,
   2369 			 unsignedp, methods);
   2370 
   2371  egress:
   2372   /* Undo the fiddling above.  */
   2373   if (save_enable)
   2374     swap_optab_enable (soptab, mode, true);
   2375   return temp;
   2376 }
   2377 
   2378 /* Generate code to perform an operation specified by UNOPPTAB
   2380    on operand OP0, with two results to TARG0 and TARG1.
   2381    We assume that the order of the operands for the instruction
   2382    is TARG0, TARG1, OP0.
   2383 
   2384    Either TARG0 or TARG1 may be zero, but what that means is that
   2385    the result is not actually wanted.  We will generate it into
   2386    a dummy pseudo-reg and discard it.  They may not both be zero.
   2387 
   2388    Returns true if this operation can be performed; false if not.  */
   2389 
   2390 bool
   2391 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
   2392 		    int unsignedp)
   2393 {
   2394   machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
   2395   enum mode_class mclass;
   2396   machine_mode wider_mode;
   2397   rtx_insn *entry_last = get_last_insn ();
   2398   rtx_insn *last;
   2399 
   2400   mclass = GET_MODE_CLASS (mode);
   2401 
   2402   if (!targ0)
   2403     targ0 = gen_reg_rtx (mode);
   2404   if (!targ1)
   2405     targ1 = gen_reg_rtx (mode);
   2406 
   2407   /* Record where to go back to if we fail.  */
   2408   last = get_last_insn ();
   2409 
   2410   if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
   2411     {
   2412       class expand_operand ops[3];
   2413       enum insn_code icode = optab_handler (unoptab, mode);
   2414 
   2415       create_fixed_operand (&ops[0], targ0);
   2416       create_fixed_operand (&ops[1], targ1);
   2417       create_convert_operand_from (&ops[2], op0, mode, unsignedp);
   2418       if (maybe_expand_insn (icode, 3, ops))
   2419 	return true;
   2420     }
   2421 
   2422   /* It can't be done in this mode.  Can we do it in a wider mode?  */
   2423 
   2424   if (CLASS_HAS_WIDER_MODES_P (mclass))
   2425     {
   2426       FOR_EACH_WIDER_MODE (wider_mode, mode)
   2427 	{
   2428 	  if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
   2429 	    {
   2430 	      rtx t0 = gen_reg_rtx (wider_mode);
   2431 	      rtx t1 = gen_reg_rtx (wider_mode);
   2432 	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
   2433 
   2434 	      if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
   2435 		{
   2436 		  convert_move (targ0, t0, unsignedp);
   2437 		  convert_move (targ1, t1, unsignedp);
   2438 		  return true;
   2439 		}
   2440 	      else
   2441 		delete_insns_since (last);
   2442 	    }
   2443 	}
   2444     }
   2445 
   2446   delete_insns_since (entry_last);
   2447   return false;
   2448 }
   2449 
   2450 /* Generate code to perform an operation specified by BINOPTAB
   2452    on operands OP0 and OP1, with two results to TARG1 and TARG2.
   2453    We assume that the order of the operands for the instruction
   2454    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
   2455    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
   2456 
   2457    Either TARG0 or TARG1 may be zero, but what that means is that
   2458    the result is not actually wanted.  We will generate it into
   2459    a dummy pseudo-reg and discard it.  They may not both be zero.
   2460 
   2461    Returns true if this operation can be performed; false if not.  */
   2462 
   2463 bool
   2464 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
   2465 		     int unsignedp)
   2466 {
   2467   machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
   2468   enum mode_class mclass;
   2469   machine_mode wider_mode;
   2470   rtx_insn *entry_last = get_last_insn ();
   2471   rtx_insn *last;
   2472 
   2473   mclass = GET_MODE_CLASS (mode);
   2474 
   2475   if (!targ0)
   2476     targ0 = gen_reg_rtx (mode);
   2477   if (!targ1)
   2478     targ1 = gen_reg_rtx (mode);
   2479 
   2480   /* Record where to go back to if we fail.  */
   2481   last = get_last_insn ();
   2482 
   2483   if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
   2484     {
   2485       class expand_operand ops[4];
   2486       enum insn_code icode = optab_handler (binoptab, mode);
   2487       machine_mode mode0 = insn_data[icode].operand[1].mode;
   2488       machine_mode mode1 = insn_data[icode].operand[2].mode;
   2489       rtx xop0 = op0, xop1 = op1;
   2490 
   2491       /* If we are optimizing, force expensive constants into a register.  */
   2492       xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
   2493       xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
   2494 
   2495       create_fixed_operand (&ops[0], targ0);
   2496       create_convert_operand_from (&ops[1], xop0, mode, unsignedp);
   2497       create_convert_operand_from (&ops[2], xop1, mode, unsignedp);
   2498       create_fixed_operand (&ops[3], targ1);
   2499       if (maybe_expand_insn (icode, 4, ops))
   2500 	return true;
   2501       delete_insns_since (last);
   2502     }
   2503 
   2504   /* It can't be done in this mode.  Can we do it in a wider mode?  */
   2505 
   2506   if (CLASS_HAS_WIDER_MODES_P (mclass))
   2507     {
   2508       FOR_EACH_WIDER_MODE (wider_mode, mode)
   2509 	{
   2510 	  if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
   2511 	    {
   2512 	      rtx t0 = gen_reg_rtx (wider_mode);
   2513 	      rtx t1 = gen_reg_rtx (wider_mode);
   2514 	      rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
   2515 	      rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
   2516 
   2517 	      if (expand_twoval_binop (binoptab, cop0, cop1,
   2518 				       t0, t1, unsignedp))
   2519 		{
   2520 		  convert_move (targ0, t0, unsignedp);
   2521 		  convert_move (targ1, t1, unsignedp);
   2522 		  return true;
   2523 		}
   2524 	      else
   2525 		delete_insns_since (last);
   2526 	    }
   2527 	}
   2528     }
   2529 
   2530   delete_insns_since (entry_last);
   2531   return false;
   2532 }
   2533 
   2534 /* Expand the two-valued library call indicated by BINOPTAB, but
   2535    preserve only one of the values.  If TARG0 is non-NULL, the first
   2536    value is placed into TARG0; otherwise the second value is placed
   2537    into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
   2538    value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
   2539    This routine assumes that the value returned by the library call is
   2540    as if the return value was of an integral mode twice as wide as the
   2541    mode of OP0.  Returns 1 if the call was successful.  */
   2542 
   2543 bool
   2544 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
   2545 			     rtx targ0, rtx targ1, enum rtx_code code)
   2546 {
   2547   machine_mode mode;
   2548   machine_mode libval_mode;
   2549   rtx libval;
   2550   rtx_insn *insns;
   2551   rtx libfunc;
   2552 
   2553   /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
   2554   gcc_assert (!targ0 != !targ1);
   2555 
   2556   mode = GET_MODE (op0);
   2557   libfunc = optab_libfunc (binoptab, mode);
   2558   if (!libfunc)
   2559     return false;
   2560 
   2561   /* The value returned by the library function will have twice as
   2562      many bits as the nominal MODE.  */
   2563   libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
   2564   start_sequence ();
   2565   libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
   2566 				    libval_mode,
   2567 				    op0, mode,
   2568 				    op1, mode);
   2569   /* Get the part of VAL containing the value that we want.  */
   2570   libval = simplify_gen_subreg (mode, libval, libval_mode,
   2571 				targ0 ? 0 : GET_MODE_SIZE (mode));
   2572   insns = get_insns ();
   2573   end_sequence ();
   2574   /* Move the into the desired location.  */
   2575   emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
   2576 		      gen_rtx_fmt_ee (code, mode, op0, op1));
   2577 
   2578   return true;
   2579 }
   2580 
   2581 
   2582 /* Wrapper around expand_unop which takes an rtx code to specify
   2584    the operation to perform, not an optab pointer.  All other
   2585    arguments are the same.  */
   2586 rtx
   2587 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
   2588 		    rtx target, int unsignedp)
   2589 {
   2590   optab unop = code_to_optab (code);
   2591   gcc_assert (unop);
   2592 
   2593   return expand_unop (mode, unop, op0, target, unsignedp);
   2594 }
   2595 
   2596 /* Try calculating
   2597 	(clz:narrow x)
   2598    as
   2599 	(clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
   2600 
   2601    A similar operation can be used for clrsb.  UNOPTAB says which operation
   2602    we are trying to expand.  */
   2603 static rtx
   2604 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
   2605 {
   2606   opt_scalar_int_mode wider_mode_iter;
   2607   FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
   2608     {
   2609       scalar_int_mode wider_mode = wider_mode_iter.require ();
   2610       if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
   2611 	{
   2612 	  rtx xop0, temp;
   2613 	  rtx_insn *last;
   2614 
   2615 	  last = get_last_insn ();
   2616 
   2617 	  if (target == 0)
   2618 	    target = gen_reg_rtx (mode);
   2619 	  xop0 = widen_operand (op0, wider_mode, mode,
   2620 				unoptab != clrsb_optab, false);
   2621 	  temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
   2622 			      unoptab != clrsb_optab);
   2623 	  if (temp != 0)
   2624 	    temp = expand_binop
   2625 	      (wider_mode, sub_optab, temp,
   2626 	       gen_int_mode (GET_MODE_PRECISION (wider_mode)
   2627 			     - GET_MODE_PRECISION (mode),
   2628 			     wider_mode),
   2629 	       target, true, OPTAB_DIRECT);
   2630 	  if (temp == 0)
   2631 	    delete_insns_since (last);
   2632 
   2633 	  return temp;
   2634 	}
   2635     }
   2636   return 0;
   2637 }
   2638 
   2639 /* Attempt to emit (clrsb:mode op0) as
   2640    (plus:mode (clz:mode (xor:mode op0 (ashr:mode op0 (const_int prec-1))))
   2641 	      (const_int -1))
   2642    if CLZ_DEFINED_VALUE_AT_ZERO (mode, val) is 2 and val is prec,
   2643    or as
   2644    (clz:mode (ior:mode (xor:mode (ashl:mode op0 (const_int 1))
   2645 				 (ashr:mode op0 (const_int prec-1)))
   2646 		       (const_int 1)))
   2647    otherwise.  */
   2648 
   2649 static rtx
   2650 expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target)
   2651 {
   2652   if (optimize_insn_for_size_p ()
   2653       || optab_handler (clz_optab, mode) == CODE_FOR_nothing)
   2654     return NULL_RTX;
   2655 
   2656   start_sequence ();
   2657   HOST_WIDE_INT val = 0;
   2658   if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) != 2
   2659       || val != GET_MODE_PRECISION (mode))
   2660     val = 0;
   2661   else
   2662     val = 1;
   2663 
   2664   rtx temp2 = op0;
   2665   if (!val)
   2666     {
   2667       temp2 = expand_binop (mode, ashl_optab, op0, const1_rtx,
   2668 			    NULL_RTX, 0, OPTAB_DIRECT);
   2669       if (!temp2)
   2670 	{
   2671 	fail:
   2672 	  end_sequence ();
   2673 	  return NULL_RTX;
   2674 	}
   2675     }
   2676 
   2677   rtx temp = expand_binop (mode, ashr_optab, op0,
   2678 			   GEN_INT (GET_MODE_PRECISION (mode) - 1),
   2679 			   NULL_RTX, 0, OPTAB_DIRECT);
   2680   if (!temp)
   2681     goto fail;
   2682 
   2683   temp = expand_binop (mode, xor_optab, temp2, temp, NULL_RTX, 0,
   2684 		       OPTAB_DIRECT);
   2685   if (!temp)
   2686     goto fail;
   2687 
   2688   if (!val)
   2689     {
   2690       temp = expand_binop (mode, ior_optab, temp, const1_rtx,
   2691 			   NULL_RTX, 0, OPTAB_DIRECT);
   2692       if (!temp)
   2693 	goto fail;
   2694     }
   2695   temp = expand_unop_direct (mode, clz_optab, temp, val ? NULL_RTX : target,
   2696 			     true);
   2697   if (!temp)
   2698     goto fail;
   2699   if (val)
   2700     {
   2701       temp = expand_binop (mode, add_optab, temp, constm1_rtx,
   2702 			   target, 0, OPTAB_DIRECT);
   2703       if (!temp)
   2704 	goto fail;
   2705     }
   2706 
   2707   rtx_insn *seq = get_insns ();
   2708   end_sequence ();
   2709 
   2710   add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode);
   2711   emit_insn (seq);
   2712   return temp;
   2713 }
   2714 
   2715 static rtx expand_ffs (scalar_int_mode, rtx, rtx);
   2716 
   2717 /* Try calculating clz, ctz or ffs of a double-word quantity as two clz, ctz or
   2718    ffs operations on word-sized quantities, choosing which based on whether the
   2719    high (for clz) or low (for ctz and ffs) word is nonzero.  */
   2720 static rtx
   2721 expand_doubleword_clz_ctz_ffs (scalar_int_mode mode, rtx op0, rtx target,
   2722 			       optab unoptab)
   2723 {
   2724   rtx xop0 = force_reg (mode, op0);
   2725   rtx subhi = gen_highpart (word_mode, xop0);
   2726   rtx sublo = gen_lowpart (word_mode, xop0);
   2727   rtx_code_label *hi0_label = gen_label_rtx ();
   2728   rtx_code_label *after_label = gen_label_rtx ();
   2729   rtx_insn *seq;
   2730   rtx temp, result;
   2731   int addend = 0;
   2732 
   2733   /* If we were not given a target, use a word_mode register, not a
   2734      'mode' register.  The result will fit, and nobody is expecting
   2735      anything bigger (the return type of __builtin_clz* is int).  */
   2736   if (!target)
   2737     target = gen_reg_rtx (word_mode);
   2738 
   2739   /* In any case, write to a word_mode scratch in both branches of the
   2740      conditional, so we can ensure there is a single move insn setting
   2741      'target' to tag a REG_EQUAL note on.  */
   2742   result = gen_reg_rtx (word_mode);
   2743 
   2744   if (unoptab != clz_optab)
   2745     std::swap (subhi, sublo);
   2746 
   2747   start_sequence ();
   2748 
   2749   /* If the high word is not equal to zero,
   2750      then clz of the full value is clz of the high word.  */
   2751   emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
   2752 			   word_mode, true, hi0_label);
   2753 
   2754   if (optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
   2755     temp = expand_unop_direct (word_mode, unoptab, subhi, result, true);
   2756   else
   2757     {
   2758       gcc_assert (unoptab == ffs_optab);
   2759       temp = expand_ffs (word_mode, subhi, result);
   2760     }
   2761   if (!temp)
   2762     goto fail;
   2763 
   2764   if (temp != result)
   2765     convert_move (result, temp, true);
   2766 
   2767   emit_jump_insn (targetm.gen_jump (after_label));
   2768   emit_barrier ();
   2769 
   2770   /* Else clz of the full value is clz of the low word plus the number
   2771      of bits in the high word.  Similarly for ctz/ffs of the high word,
   2772      except that ffs should be 0 when both words are zero.  */
   2773   emit_label (hi0_label);
   2774 
   2775   if (unoptab == ffs_optab)
   2776     {
   2777       convert_move (result, const0_rtx, true);
   2778       emit_cmp_and_jump_insns (sublo, CONST0_RTX (word_mode), EQ, 0,
   2779 			       word_mode, true, after_label);
   2780     }
   2781 
   2782   if (optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
   2783     temp = expand_unop_direct (word_mode, unoptab, sublo, NULL_RTX, true);
   2784   else
   2785     {
   2786       gcc_assert (unoptab == ffs_optab);
   2787       temp = expand_unop_direct (word_mode, ctz_optab, sublo, NULL_RTX, true);
   2788       addend = 1;
   2789     }
   2790 
   2791   if (!temp)
   2792     goto fail;
   2793 
   2794   temp = expand_binop (word_mode, add_optab, temp,
   2795 		       gen_int_mode (GET_MODE_BITSIZE (word_mode) + addend,
   2796 				     word_mode),
   2797 		       result, true, OPTAB_DIRECT);
   2798   if (!temp)
   2799     goto fail;
   2800   if (temp != result)
   2801     convert_move (result, temp, true);
   2802 
   2803   emit_label (after_label);
   2804   convert_move (target, result, true);
   2805 
   2806   seq = get_insns ();
   2807   end_sequence ();
   2808 
   2809   add_equal_note (seq, target, optab_to_code (unoptab), xop0, NULL_RTX, mode);
   2810   emit_insn (seq);
   2811   return target;
   2812 
   2813  fail:
   2814   end_sequence ();
   2815   return 0;
   2816 }
   2817 
   2818 /* Try calculating popcount of a double-word quantity as two popcount's of
   2819    word-sized quantities and summing up the results.  */
   2820 static rtx
   2821 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
   2822 {
   2823   rtx t0, t1, t;
   2824   rtx_insn *seq;
   2825 
   2826   start_sequence ();
   2827 
   2828   t0 = expand_unop_direct (word_mode, popcount_optab,
   2829 			   operand_subword_force (op0, 0, mode), NULL_RTX,
   2830 			   true);
   2831   t1 = expand_unop_direct (word_mode, popcount_optab,
   2832 			   operand_subword_force (op0, 1, mode), NULL_RTX,
   2833 			   true);
   2834   if (!t0 || !t1)
   2835     {
   2836       end_sequence ();
   2837       return NULL_RTX;
   2838     }
   2839 
   2840   /* If we were not given a target, use a word_mode register, not a
   2841      'mode' register.  The result will fit, and nobody is expecting
   2842      anything bigger (the return type of __builtin_popcount* is int).  */
   2843   if (!target)
   2844     target = gen_reg_rtx (word_mode);
   2845 
   2846   t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
   2847 
   2848   seq = get_insns ();
   2849   end_sequence ();
   2850 
   2851   add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
   2852   emit_insn (seq);
   2853   return t;
   2854 }
   2855 
   2856 /* Try calculating
   2857 	(parity:wide x)
   2858    as
   2859 	(parity:narrow (low (x) ^ high (x))) */
   2860 static rtx
   2861 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
   2862 {
   2863   rtx t = expand_binop (word_mode, xor_optab,
   2864 			operand_subword_force (op0, 0, mode),
   2865 			operand_subword_force (op0, 1, mode),
   2866 			NULL_RTX, 0, OPTAB_DIRECT);
   2867   return expand_unop (word_mode, parity_optab, t, target, true);
   2868 }
   2869 
   2870 /* Try calculating
   2871 	(bswap:narrow x)
   2872    as
   2873 	(lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))).  */
   2874 static rtx
   2875 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
   2876 {
   2877   rtx x;
   2878   rtx_insn *last;
   2879   opt_scalar_int_mode wider_mode_iter;
   2880 
   2881   FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
   2882     if (optab_handler (bswap_optab, wider_mode_iter.require ())
   2883 	!= CODE_FOR_nothing)
   2884       break;
   2885 
   2886   if (!wider_mode_iter.exists ())
   2887     return NULL_RTX;
   2888 
   2889   scalar_int_mode wider_mode = wider_mode_iter.require ();
   2890   last = get_last_insn ();
   2891 
   2892   x = widen_operand (op0, wider_mode, mode, true, true);
   2893   x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
   2894 
   2895   gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
   2896 	      && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
   2897   if (x != 0)
   2898     x = expand_shift (RSHIFT_EXPR, wider_mode, x,
   2899 		      GET_MODE_BITSIZE (wider_mode)
   2900 		      - GET_MODE_BITSIZE (mode),
   2901 		      NULL_RTX, true);
   2902 
   2903   if (x != 0)
   2904     {
   2905       if (target == 0)
   2906 	target = gen_reg_rtx (mode);
   2907       emit_move_insn (target, gen_lowpart (mode, x));
   2908     }
   2909   else
   2910     delete_insns_since (last);
   2911 
   2912   return target;
   2913 }
   2914 
   2915 /* Try calculating bswap as two bswaps of two word-sized operands.  */
   2916 
   2917 static rtx
   2918 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
   2919 {
   2920   rtx t0, t1;
   2921 
   2922   t1 = expand_unop (word_mode, bswap_optab,
   2923 		    operand_subword_force (op, 0, mode), NULL_RTX, true);
   2924   t0 = expand_unop (word_mode, bswap_optab,
   2925 		    operand_subword_force (op, 1, mode), NULL_RTX, true);
   2926 
   2927   if (target == 0 || !valid_multiword_target_p (target))
   2928     target = gen_reg_rtx (mode);
   2929   if (REG_P (target))
   2930     emit_clobber (target);
   2931   emit_move_insn (operand_subword (target, 0, 1, mode), t0);
   2932   emit_move_insn (operand_subword (target, 1, 1, mode), t1);
   2933 
   2934   return target;
   2935 }
   2936 
   2937 /* Try calculating (parity x) as (and (popcount x) 1), where
   2938    popcount can also be done in a wider mode.  */
   2939 static rtx
   2940 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
   2941 {
   2942   enum mode_class mclass = GET_MODE_CLASS (mode);
   2943   opt_scalar_int_mode wider_mode_iter;
   2944   FOR_EACH_MODE_FROM (wider_mode_iter, mode)
   2945     {
   2946       scalar_int_mode wider_mode = wider_mode_iter.require ();
   2947       if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
   2948 	{
   2949 	  rtx xop0, temp;
   2950 	  rtx_insn *last;
   2951 
   2952 	  last = get_last_insn ();
   2953 
   2954 	  if (target == 0 || GET_MODE (target) != wider_mode)
   2955 	    target = gen_reg_rtx (wider_mode);
   2956 
   2957 	  xop0 = widen_operand (op0, wider_mode, mode, true, false);
   2958 	  temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
   2959 			      true);
   2960 	  if (temp != 0)
   2961 	    temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
   2962 				 target, true, OPTAB_DIRECT);
   2963 
   2964 	  if (temp)
   2965 	    {
   2966 	      if (mclass != MODE_INT
   2967 		  || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
   2968 		return convert_to_mode (mode, temp, 0);
   2969 	      else
   2970 		return gen_lowpart (mode, temp);
   2971 	    }
   2972 	  else
   2973 	    delete_insns_since (last);
   2974 	}
   2975     }
   2976   return 0;
   2977 }
   2978 
   2979 /* Try calculating ctz(x) as K - clz(x & -x) ,
   2980    where K is GET_MODE_PRECISION(mode) - 1.
   2981 
   2982    Both __builtin_ctz and __builtin_clz are undefined at zero, so we
   2983    don't have to worry about what the hardware does in that case.  (If
   2984    the clz instruction produces the usual value at 0, which is K, the
   2985    result of this code sequence will be -1; expand_ffs, below, relies
   2986    on this.  It might be nice to have it be K instead, for consistency
   2987    with the (very few) processors that provide a ctz with a defined
   2988    value, but that would take one more instruction, and it would be
   2989    less convenient for expand_ffs anyway.  */
   2990 
   2991 static rtx
   2992 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
   2993 {
   2994   rtx_insn *seq;
   2995   rtx temp;
   2996 
   2997   if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
   2998     return 0;
   2999 
   3000   start_sequence ();
   3001 
   3002   temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
   3003   if (temp)
   3004     temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
   3005 			 true, OPTAB_DIRECT);
   3006   if (temp)
   3007     temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
   3008   if (temp)
   3009     temp = expand_binop (mode, sub_optab,
   3010 			 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
   3011 			 temp, target,
   3012 			 true, OPTAB_DIRECT);
   3013   if (temp == 0)
   3014     {
   3015       end_sequence ();
   3016       return 0;
   3017     }
   3018 
   3019   seq = get_insns ();
   3020   end_sequence ();
   3021 
   3022   add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
   3023   emit_insn (seq);
   3024   return temp;
   3025 }
   3026 
   3027 
   3028 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
   3029    else with the sequence used by expand_clz.
   3030 
   3031    The ffs builtin promises to return zero for a zero value and ctz/clz
   3032    may have an undefined value in that case.  If they do not give us a
   3033    convenient value, we have to generate a test and branch.  */
   3034 static rtx
   3035 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
   3036 {
   3037   HOST_WIDE_INT val = 0;
   3038   bool defined_at_zero = false;
   3039   rtx temp;
   3040   rtx_insn *seq;
   3041 
   3042   if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
   3043     {
   3044       start_sequence ();
   3045 
   3046       temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
   3047       if (!temp)
   3048 	goto fail;
   3049 
   3050       defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
   3051     }
   3052   else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
   3053     {
   3054       start_sequence ();
   3055       temp = expand_ctz (mode, op0, 0);
   3056       if (!temp)
   3057 	goto fail;
   3058 
   3059       if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
   3060 	{
   3061 	  defined_at_zero = true;
   3062 	  val = (GET_MODE_PRECISION (mode) - 1) - val;
   3063 	}
   3064     }
   3065   else
   3066     return 0;
   3067 
   3068   if (defined_at_zero && val == -1)
   3069     /* No correction needed at zero.  */;
   3070   else
   3071     {
   3072       /* We don't try to do anything clever with the situation found
   3073 	 on some processors (eg Alpha) where ctz(0:mode) ==
   3074 	 bitsize(mode).  If someone can think of a way to send N to -1
   3075 	 and leave alone all values in the range 0..N-1 (where N is a
   3076 	 power of two), cheaper than this test-and-branch, please add it.
   3077 
   3078 	 The test-and-branch is done after the operation itself, in case
   3079 	 the operation sets condition codes that can be recycled for this.
   3080 	 (This is true on i386, for instance.)  */
   3081 
   3082       rtx_code_label *nonzero_label = gen_label_rtx ();
   3083       emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
   3084 			       mode, true, nonzero_label);
   3085 
   3086       convert_move (temp, GEN_INT (-1), false);
   3087       emit_label (nonzero_label);
   3088     }
   3089 
   3090   /* temp now has a value in the range -1..bitsize-1.  ffs is supposed
   3091      to produce a value in the range 0..bitsize.  */
   3092   temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
   3093 		       target, false, OPTAB_DIRECT);
   3094   if (!temp)
   3095     goto fail;
   3096 
   3097   seq = get_insns ();
   3098   end_sequence ();
   3099 
   3100   add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
   3101   emit_insn (seq);
   3102   return temp;
   3103 
   3104  fail:
   3105   end_sequence ();
   3106   return 0;
   3107 }
   3108 
   3109 /* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
   3110    conditions, VAL may already be a SUBREG against which we cannot generate
   3111    a further SUBREG.  In this case, we expect forcing the value into a
   3112    register will work around the situation.  */
   3113 
   3114 static rtx
   3115 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
   3116 			   machine_mode imode)
   3117 {
   3118   rtx ret;
   3119   ret = lowpart_subreg (omode, val, imode);
   3120   if (ret == NULL)
   3121     {
   3122       val = force_reg (imode, val);
   3123       ret = lowpart_subreg (omode, val, imode);
   3124       gcc_assert (ret != NULL);
   3125     }
   3126   return ret;
   3127 }
   3128 
   3129 /* Expand a floating point absolute value or negation operation via a
   3130    logical operation on the sign bit.  */
   3131 
   3132 static rtx
   3133 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
   3134 		   rtx op0, rtx target)
   3135 {
   3136   const struct real_format *fmt;
   3137   int bitpos, word, nwords, i;
   3138   scalar_int_mode imode;
   3139   rtx temp;
   3140   rtx_insn *insns;
   3141 
   3142   /* The format has to have a simple sign bit.  */
   3143   fmt = REAL_MODE_FORMAT (mode);
   3144   if (fmt == NULL)
   3145     return NULL_RTX;
   3146 
   3147   bitpos = fmt->signbit_rw;
   3148   if (bitpos < 0)
   3149     return NULL_RTX;
   3150 
   3151   /* Don't create negative zeros if the format doesn't support them.  */
   3152   if (code == NEG && !fmt->has_signed_zero)
   3153     return NULL_RTX;
   3154 
   3155   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   3156     {
   3157       if (!int_mode_for_mode (mode).exists (&imode))
   3158 	return NULL_RTX;
   3159       word = 0;
   3160       nwords = 1;
   3161     }
   3162   else
   3163     {
   3164       imode = word_mode;
   3165 
   3166       if (FLOAT_WORDS_BIG_ENDIAN)
   3167 	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
   3168       else
   3169 	word = bitpos / BITS_PER_WORD;
   3170       bitpos = bitpos % BITS_PER_WORD;
   3171       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
   3172     }
   3173 
   3174   wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
   3175   if (code == ABS)
   3176     mask = ~mask;
   3177 
   3178   if (target == 0
   3179       || target == op0
   3180       || reg_overlap_mentioned_p (target, op0)
   3181       || (nwords > 1 && !valid_multiword_target_p (target)))
   3182     target = gen_reg_rtx (mode);
   3183 
   3184   if (nwords > 1)
   3185     {
   3186       start_sequence ();
   3187 
   3188       for (i = 0; i < nwords; ++i)
   3189 	{
   3190 	  rtx targ_piece = operand_subword (target, i, 1, mode);
   3191 	  rtx op0_piece = operand_subword_force (op0, i, mode);
   3192 
   3193 	  if (i == word)
   3194 	    {
   3195 	      temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
   3196 				   op0_piece,
   3197 				   immed_wide_int_const (mask, imode),
   3198 				   targ_piece, 1, OPTAB_LIB_WIDEN);
   3199 	      if (temp != targ_piece)
   3200 		emit_move_insn (targ_piece, temp);
   3201 	    }
   3202 	  else
   3203 	    emit_move_insn (targ_piece, op0_piece);
   3204 	}
   3205 
   3206       insns = get_insns ();
   3207       end_sequence ();
   3208 
   3209       emit_insn (insns);
   3210     }
   3211   else
   3212     {
   3213       temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
   3214 			   gen_lowpart (imode, op0),
   3215 			   immed_wide_int_const (mask, imode),
   3216 		           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
   3217       target = lowpart_subreg_maybe_copy (mode, temp, imode);
   3218 
   3219       set_dst_reg_note (get_last_insn (), REG_EQUAL,
   3220 			gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
   3221 			target);
   3222     }
   3223 
   3224   return target;
   3225 }
   3226 
   3227 /* As expand_unop, but will fail rather than attempt the operation in a
   3228    different mode or with a libcall.  */
   3229 static rtx
   3230 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
   3231 		    int unsignedp)
   3232 {
   3233   if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
   3234     {
   3235       class expand_operand ops[2];
   3236       enum insn_code icode = optab_handler (unoptab, mode);
   3237       rtx_insn *last = get_last_insn ();
   3238       rtx_insn *pat;
   3239 
   3240       create_output_operand (&ops[0], target, mode);
   3241       create_convert_operand_from (&ops[1], op0, mode, unsignedp);
   3242       pat = maybe_gen_insn (icode, 2, ops);
   3243       if (pat)
   3244 	{
   3245 	  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
   3246 	      && ! add_equal_note (pat, ops[0].value,
   3247 				   optab_to_code (unoptab),
   3248 				   ops[1].value, NULL_RTX, mode))
   3249 	    {
   3250 	      delete_insns_since (last);
   3251 	      return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
   3252 	    }
   3253 
   3254 	  emit_insn (pat);
   3255 
   3256 	  return ops[0].value;
   3257 	}
   3258     }
   3259   return 0;
   3260 }
   3261 
   3262 /* Generate code to perform an operation specified by UNOPTAB
   3263    on operand OP0, with result having machine-mode MODE.
   3264 
   3265    UNSIGNEDP is for the case where we have to widen the operands
   3266    to perform the operation.  It says to use zero-extension.
   3267 
   3268    If TARGET is nonzero, the value
   3269    is generated there, if it is convenient to do so.
   3270    In all cases an rtx is returned for the locus of the value;
   3271    this may or may not be TARGET.  */
   3272 
   3273 rtx
   3274 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
   3275 	     int unsignedp)
   3276 {
   3277   enum mode_class mclass = GET_MODE_CLASS (mode);
   3278   machine_mode wider_mode;
   3279   scalar_int_mode int_mode;
   3280   scalar_float_mode float_mode;
   3281   rtx temp;
   3282   rtx libfunc;
   3283 
   3284   temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
   3285   if (temp)
   3286     return temp;
   3287 
   3288   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
   3289 
   3290   /* Widening (or narrowing) clz needs special treatment.  */
   3291   if (unoptab == clz_optab)
   3292     {
   3293       if (is_a <scalar_int_mode> (mode, &int_mode))
   3294 	{
   3295 	  temp = widen_leading (int_mode, op0, target, unoptab);
   3296 	  if (temp)
   3297 	    return temp;
   3298 
   3299 	  if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   3300 	      && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
   3301 	    {
   3302 	      temp = expand_doubleword_clz_ctz_ffs (int_mode, op0, target,
   3303 						    unoptab);
   3304 	      if (temp)
   3305 		return temp;
   3306 	    }
   3307 	}
   3308 
   3309       goto try_libcall;
   3310     }
   3311 
   3312   if (unoptab == clrsb_optab)
   3313     {
   3314       if (is_a <scalar_int_mode> (mode, &int_mode))
   3315 	{
   3316 	  temp = widen_leading (int_mode, op0, target, unoptab);
   3317 	  if (temp)
   3318 	    return temp;
   3319 	  temp = expand_clrsb_using_clz (int_mode, op0, target);
   3320 	  if (temp)
   3321 	    return temp;
   3322 	}
   3323       goto try_libcall;
   3324     }
   3325 
   3326   if (unoptab == popcount_optab
   3327       && is_a <scalar_int_mode> (mode, &int_mode)
   3328       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   3329       && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
   3330       && optimize_insn_for_speed_p ())
   3331     {
   3332       temp = expand_doubleword_popcount (int_mode, op0, target);
   3333       if (temp)
   3334 	return temp;
   3335     }
   3336 
   3337   if (unoptab == parity_optab
   3338       && is_a <scalar_int_mode> (mode, &int_mode)
   3339       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   3340       && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
   3341 	  || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
   3342       && optimize_insn_for_speed_p ())
   3343     {
   3344       temp = expand_doubleword_parity (int_mode, op0, target);
   3345       if (temp)
   3346 	return temp;
   3347     }
   3348 
   3349   /* Widening (or narrowing) bswap needs special treatment.  */
   3350   if (unoptab == bswap_optab)
   3351     {
   3352       /* HImode is special because in this mode BSWAP is equivalent to ROTATE
   3353 	 or ROTATERT.  First try these directly; if this fails, then try the
   3354 	 obvious pair of shifts with allowed widening, as this will probably
   3355 	 be always more efficient than the other fallback methods.  */
   3356       if (mode == HImode)
   3357 	{
   3358 	  rtx_insn *last;
   3359 	  rtx temp1, temp2;
   3360 
   3361 	  if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
   3362 	    {
   3363 	      temp = expand_binop (mode, rotl_optab, op0,
   3364 				   gen_int_shift_amount (mode, 8),
   3365 				   target, unsignedp, OPTAB_DIRECT);
   3366 	      if (temp)
   3367 		return temp;
   3368 	     }
   3369 
   3370 	  if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
   3371 	    {
   3372 	      temp = expand_binop (mode, rotr_optab, op0,
   3373 				   gen_int_shift_amount (mode, 8),
   3374 				   target, unsignedp, OPTAB_DIRECT);
   3375 	      if (temp)
   3376 		return temp;
   3377 	    }
   3378 
   3379 	  last = get_last_insn ();
   3380 
   3381 	  temp1 = expand_binop (mode, ashl_optab, op0,
   3382 				gen_int_shift_amount (mode, 8), NULL_RTX,
   3383 			        unsignedp, OPTAB_WIDEN);
   3384 	  temp2 = expand_binop (mode, lshr_optab, op0,
   3385 				gen_int_shift_amount (mode, 8), NULL_RTX,
   3386 			        unsignedp, OPTAB_WIDEN);
   3387 	  if (temp1 && temp2)
   3388 	    {
   3389 	      temp = expand_binop (mode, ior_optab, temp1, temp2, target,
   3390 				   unsignedp, OPTAB_WIDEN);
   3391 	      if (temp)
   3392 		return temp;
   3393 	    }
   3394 
   3395 	  delete_insns_since (last);
   3396 	}
   3397 
   3398       if (is_a <scalar_int_mode> (mode, &int_mode))
   3399 	{
   3400 	  temp = widen_bswap (int_mode, op0, target);
   3401 	  if (temp)
   3402 	    return temp;
   3403 
   3404 	  /* We do not provide a 128-bit bswap in libgcc so force the use of
   3405 	     a double bswap for 64-bit targets.  */
   3406 	  if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   3407 	      && (UNITS_PER_WORD == 8
   3408 		  || optab_handler (unoptab, word_mode) != CODE_FOR_nothing))
   3409 	    {
   3410 	      temp = expand_doubleword_bswap (mode, op0, target);
   3411 	      if (temp)
   3412 		return temp;
   3413 	    }
   3414 	}
   3415 
   3416       goto try_libcall;
   3417     }
   3418 
   3419   if (CLASS_HAS_WIDER_MODES_P (mclass))
   3420     FOR_EACH_WIDER_MODE (wider_mode, mode)
   3421       {
   3422 	if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
   3423 	  {
   3424 	    rtx xop0 = op0;
   3425 	    rtx_insn *last = get_last_insn ();
   3426 
   3427 	    /* For certain operations, we need not actually extend
   3428 	       the narrow operand, as long as we will truncate the
   3429 	       results to the same narrowness.  */
   3430 
   3431 	    xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
   3432 				  (unoptab == neg_optab
   3433 				   || unoptab == one_cmpl_optab)
   3434 				  && mclass == MODE_INT);
   3435 
   3436 	    temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
   3437 				unsignedp);
   3438 
   3439 	    if (temp)
   3440 	      {
   3441 		if (mclass != MODE_INT
   3442 		    || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
   3443 		  {
   3444 		    if (target == 0)
   3445 		      target = gen_reg_rtx (mode);
   3446 		    convert_move (target, temp, 0);
   3447 		    return target;
   3448 		  }
   3449 		else
   3450 		  return gen_lowpart (mode, temp);
   3451 	      }
   3452 	    else
   3453 	      delete_insns_since (last);
   3454 	  }
   3455       }
   3456 
   3457   /* These can be done a word at a time.  */
   3458   if (unoptab == one_cmpl_optab
   3459       && is_int_mode (mode, &int_mode)
   3460       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
   3461       && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
   3462     {
   3463       int i;
   3464       rtx_insn *insns;
   3465 
   3466       if (target == 0
   3467 	  || target == op0
   3468 	  || reg_overlap_mentioned_p (target, op0)
   3469 	  || !valid_multiword_target_p (target))
   3470 	target = gen_reg_rtx (int_mode);
   3471 
   3472       start_sequence ();
   3473 
   3474       /* Do the actual arithmetic.  */
   3475       for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
   3476 	{
   3477 	  rtx target_piece = operand_subword (target, i, 1, int_mode);
   3478 	  rtx x = expand_unop (word_mode, unoptab,
   3479 			       operand_subword_force (op0, i, int_mode),
   3480 			       target_piece, unsignedp);
   3481 
   3482 	  if (target_piece != x)
   3483 	    emit_move_insn (target_piece, x);
   3484 	}
   3485 
   3486       insns = get_insns ();
   3487       end_sequence ();
   3488 
   3489       emit_insn (insns);
   3490       return target;
   3491     }
   3492 
   3493   /* Emit ~op0 as op0 ^ -1.  */
   3494   if (unoptab == one_cmpl_optab
   3495       && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   3496       && optab_handler (xor_optab, mode) != CODE_FOR_nothing)
   3497     {
   3498       temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode),
   3499 			   target, unsignedp, OPTAB_DIRECT);
   3500       if (temp)
   3501 	return temp;
   3502     }
   3503 
   3504   if (optab_to_code (unoptab) == NEG)
   3505     {
   3506       /* Try negating floating point values by flipping the sign bit.  */
   3507       if (is_a <scalar_float_mode> (mode, &float_mode))
   3508 	{
   3509 	  temp = expand_absneg_bit (NEG, float_mode, op0, target);
   3510 	  if (temp)
   3511 	    return temp;
   3512 	}
   3513 
   3514       /* If there is no negation pattern, and we have no negative zero,
   3515 	 try subtracting from zero.  */
   3516       if (!HONOR_SIGNED_ZEROS (mode))
   3517 	{
   3518 	  temp = expand_binop (mode, (unoptab == negv_optab
   3519 				      ? subv_optab : sub_optab),
   3520 			       CONST0_RTX (mode), op0, target,
   3521 			       unsignedp, OPTAB_DIRECT);
   3522 	  if (temp)
   3523 	    return temp;
   3524 	}
   3525     }
   3526 
   3527   /* Try calculating parity (x) as popcount (x) % 2.  */
   3528   if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
   3529     {
   3530       temp = expand_parity (int_mode, op0, target);
   3531       if (temp)
   3532 	return temp;
   3533     }
   3534 
   3535   /* Try implementing ffs (x) in terms of clz (x).  */
   3536   if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
   3537     {
   3538       temp = expand_ffs (int_mode, op0, target);
   3539       if (temp)
   3540 	return temp;
   3541     }
   3542 
   3543   /* Try implementing ctz (x) in terms of clz (x).  */
   3544   if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
   3545     {
   3546       temp = expand_ctz (int_mode, op0, target);
   3547       if (temp)
   3548 	return temp;
   3549     }
   3550 
   3551   if ((unoptab == ctz_optab || unoptab == ffs_optab)
   3552       && optimize_insn_for_speed_p ()
   3553       && is_a <scalar_int_mode> (mode, &int_mode)
   3554       && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
   3555       && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
   3556 	  || optab_handler (ctz_optab, word_mode) != CODE_FOR_nothing))
   3557     {
   3558       temp = expand_doubleword_clz_ctz_ffs (int_mode, op0, target, unoptab);
   3559       if (temp)
   3560 	return temp;
   3561     }
   3562 
   3563  try_libcall:
   3564   /* Now try a library call in this mode.  */
   3565   libfunc = optab_libfunc (unoptab, mode);
   3566   if (libfunc)
   3567     {
   3568       rtx_insn *insns;
   3569       rtx value;
   3570       rtx eq_value;
   3571       machine_mode outmode = mode;
   3572 
   3573       /* All of these functions return small values.  Thus we choose to
   3574 	 have them return something that isn't a double-word.  */
   3575       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
   3576 	  || unoptab == clrsb_optab || unoptab == popcount_optab
   3577 	  || unoptab == parity_optab)
   3578 	outmode
   3579 	  = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
   3580 					  optab_libfunc (unoptab, mode)));
   3581 
   3582       start_sequence ();
   3583 
   3584       /* Pass 1 for NO_QUEUE so we don't lose any increments
   3585 	 if the libcall is cse'd or moved.  */
   3586       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
   3587 				       op0, mode);
   3588       insns = get_insns ();
   3589       end_sequence ();
   3590 
   3591       target = gen_reg_rtx (outmode);
   3592       bool trapv = trapv_unoptab_p (unoptab);
   3593       if (trapv)
   3594 	eq_value = NULL_RTX;
   3595       else
   3596 	{
   3597 	  eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
   3598 	  if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
   3599 	    eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
   3600 	  else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
   3601 	    eq_value = simplify_gen_unary (ZERO_EXTEND,
   3602 					   outmode, eq_value, mode);
   3603 	}
   3604       emit_libcall_block_1 (insns, target, value, eq_value, trapv);
   3605 
   3606       return target;
   3607     }
   3608 
   3609   /* It can't be done in this mode.  Can we do it in a wider mode?  */
   3610 
   3611   if (CLASS_HAS_WIDER_MODES_P (mclass))
   3612     {
   3613       FOR_EACH_WIDER_MODE (wider_mode, mode)
   3614 	{
   3615 	  if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
   3616 	      || optab_libfunc (unoptab, wider_mode))
   3617 	    {
   3618 	      rtx xop0 = op0;
   3619 	      rtx_insn *last = get_last_insn ();
   3620 
   3621 	      /* For certain operations, we need not actually extend
   3622 		 the narrow operand, as long as we will truncate the
   3623 		 results to the same narrowness.  */
   3624 	      xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
   3625 				    (unoptab == neg_optab
   3626 				     || unoptab == one_cmpl_optab
   3627 				     || unoptab == bswap_optab)
   3628 				    && mclass == MODE_INT);
   3629 
   3630 	      temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
   3631 				  unsignedp);
   3632 
   3633 	      /* If we are generating clz using wider mode, adjust the
   3634 		 result.  Similarly for clrsb.  */
   3635 	      if ((unoptab == clz_optab || unoptab == clrsb_optab)
   3636 		  && temp != 0)
   3637 		{
   3638 		  scalar_int_mode wider_int_mode
   3639 		    = as_a <scalar_int_mode> (wider_mode);
   3640 		  int_mode = as_a <scalar_int_mode> (mode);
   3641 		  temp = expand_binop
   3642 		    (wider_mode, sub_optab, temp,
   3643 		     gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
   3644 				   - GET_MODE_PRECISION (int_mode),
   3645 				   wider_int_mode),
   3646 		     target, true, OPTAB_DIRECT);
   3647 		}
   3648 
   3649 	      /* Likewise for bswap.  */
   3650 	      if (unoptab == bswap_optab && temp != 0)
   3651 		{
   3652 		  scalar_int_mode wider_int_mode
   3653 		    = as_a <scalar_int_mode> (wider_mode);
   3654 		  int_mode = as_a <scalar_int_mode> (mode);
   3655 		  gcc_assert (GET_MODE_PRECISION (wider_int_mode)
   3656 			      == GET_MODE_BITSIZE (wider_int_mode)
   3657 			      && GET_MODE_PRECISION (int_mode)
   3658 				 == GET_MODE_BITSIZE (int_mode));
   3659 
   3660 		  temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
   3661 				       GET_MODE_BITSIZE (wider_int_mode)
   3662 				       - GET_MODE_BITSIZE (int_mode),
   3663 				       NULL_RTX, true);
   3664 		}
   3665 
   3666 	      if (temp)
   3667 		{
   3668 		  if (mclass != MODE_INT)
   3669 		    {
   3670 		      if (target == 0)
   3671 			target = gen_reg_rtx (mode);
   3672 		      convert_move (target, temp, 0);
   3673 		      return target;
   3674 		    }
   3675 		  else
   3676 		    return gen_lowpart (mode, temp);
   3677 		}
   3678 	      else
   3679 		delete_insns_since (last);
   3680 	    }
   3681 	}
   3682     }
   3683 
   3684   /* One final attempt at implementing negation via subtraction,
   3685      this time allowing widening of the operand.  */
   3686   if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
   3687     {
   3688       rtx temp;
   3689       temp = expand_binop (mode,
   3690                            unoptab == negv_optab ? subv_optab : sub_optab,
   3691                            CONST0_RTX (mode), op0,
   3692                            target, unsignedp, OPTAB_LIB_WIDEN);
   3693       if (temp)
   3694         return temp;
   3695     }
   3696 
   3697   return 0;
   3698 }
   3699 
   3700 /* Emit code to compute the absolute value of OP0, with result to
   3702    TARGET if convenient.  (TARGET may be 0.)  The return value says
   3703    where the result actually is to be found.
   3704 
   3705    MODE is the mode of the operand; the mode of the result is
   3706    different but can be deduced from MODE.
   3707 
   3708  */
   3709 
   3710 rtx
   3711 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
   3712 		   int result_unsignedp)
   3713 {
   3714   rtx temp;
   3715 
   3716   if (GET_MODE_CLASS (mode) != MODE_INT
   3717       || ! flag_trapv)
   3718     result_unsignedp = 1;
   3719 
   3720   /* First try to do it with a special abs instruction.  */
   3721   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
   3722                       op0, target, 0);
   3723   if (temp != 0)
   3724     return temp;
   3725 
   3726   /* For floating point modes, try clearing the sign bit.  */
   3727   scalar_float_mode float_mode;
   3728   if (is_a <scalar_float_mode> (mode, &float_mode))
   3729     {
   3730       temp = expand_absneg_bit (ABS, float_mode, op0, target);
   3731       if (temp)
   3732 	return temp;
   3733     }
   3734 
   3735   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
   3736   if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
   3737       && !HONOR_SIGNED_ZEROS (mode))
   3738     {
   3739       rtx_insn *last = get_last_insn ();
   3740 
   3741       temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
   3742 			  op0, NULL_RTX, 0);
   3743       if (temp != 0)
   3744 	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
   3745 			     OPTAB_WIDEN);
   3746 
   3747       if (temp != 0)
   3748 	return temp;
   3749 
   3750       delete_insns_since (last);
   3751     }
   3752 
   3753   /* If this machine has expensive jumps, we can do integer absolute
   3754      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
   3755      where W is the width of MODE.  */
   3756 
   3757   scalar_int_mode int_mode;
   3758   if (is_int_mode (mode, &int_mode)
   3759       && BRANCH_COST (optimize_insn_for_speed_p (),
   3760 	      	      false) >= 2)
   3761     {
   3762       rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
   3763 				   GET_MODE_PRECISION (int_mode) - 1,
   3764 				   NULL_RTX, 0);
   3765 
   3766       temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
   3767 			   OPTAB_LIB_WIDEN);
   3768       if (temp != 0)
   3769 	temp = expand_binop (int_mode,
   3770 			     result_unsignedp ? sub_optab : subv_optab,
   3771                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
   3772 
   3773       if (temp != 0)
   3774 	return temp;
   3775     }
   3776 
   3777   return NULL_RTX;
   3778 }
   3779 
   3780 rtx
   3781 expand_abs (machine_mode mode, rtx op0, rtx target,
   3782 	    int result_unsignedp, int safe)
   3783 {
   3784   rtx temp;
   3785   rtx_code_label *op1;
   3786 
   3787   if (GET_MODE_CLASS (mode) != MODE_INT
   3788       || ! flag_trapv)
   3789     result_unsignedp = 1;
   3790 
   3791   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
   3792   if (temp != 0)
   3793     return temp;
   3794 
   3795   /* If that does not win, use conditional jump and negate.  */
   3796 
   3797   /* It is safe to use the target if it is the same
   3798      as the source if this is also a pseudo register */
   3799   if (op0 == target && REG_P (op0)
   3800       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
   3801     safe = 1;
   3802 
   3803   op1 = gen_label_rtx ();
   3804   if (target == 0 || ! safe
   3805       || GET_MODE (target) != mode
   3806       || (MEM_P (target) && MEM_VOLATILE_P (target))
   3807       || (REG_P (target)
   3808 	  && REGNO (target) < FIRST_PSEUDO_REGISTER))
   3809     target = gen_reg_rtx (mode);
   3810 
   3811   emit_move_insn (target, op0);
   3812   NO_DEFER_POP;
   3813 
   3814   do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
   3815 			   NULL_RTX, NULL, op1,
   3816 			   profile_probability::uninitialized ());
   3817 
   3818   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
   3819                      target, target, 0);
   3820   if (op0 != target)
   3821     emit_move_insn (target, op0);
   3822   emit_label (op1);
   3823   OK_DEFER_POP;
   3824   return target;
   3825 }
   3826 
   3827 /* Emit code to compute the one's complement absolute value of OP0
   3828    (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
   3829    (TARGET may be NULL_RTX.)  The return value says where the result
   3830    actually is to be found.
   3831 
   3832    MODE is the mode of the operand; the mode of the result is
   3833    different but can be deduced from MODE.  */
   3834 
   3835 rtx
   3836 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
   3837 {
   3838   rtx temp;
   3839 
   3840   /* Not applicable for floating point modes.  */
   3841   if (FLOAT_MODE_P (mode))
   3842     return NULL_RTX;
   3843 
   3844   /* If we have a MAX insn, we can do this as MAX (x, ~x).  */
   3845   if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
   3846     {
   3847       rtx_insn *last = get_last_insn ();
   3848 
   3849       temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
   3850       if (temp != 0)
   3851 	temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
   3852 			     OPTAB_WIDEN);
   3853 
   3854       if (temp != 0)
   3855 	return temp;
   3856 
   3857       delete_insns_since (last);
   3858     }
   3859 
   3860   /* If this machine has expensive jumps, we can do one's complement
   3861      absolute value of X as (((signed) x >> (W-1)) ^ x).  */
   3862 
   3863   scalar_int_mode int_mode;
   3864   if (is_int_mode (mode, &int_mode)
   3865       && BRANCH_COST (optimize_insn_for_speed_p (),
   3866 	             false) >= 2)
   3867     {
   3868       rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
   3869 				   GET_MODE_PRECISION (int_mode) - 1,
   3870 				   NULL_RTX, 0);
   3871 
   3872       temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
   3873 			   OPTAB_LIB_WIDEN);
   3874 
   3875       if (temp != 0)
   3876 	return temp;
   3877     }
   3878 
   3879   return NULL_RTX;
   3880 }
   3881 
   3882 /* A subroutine of expand_copysign, perform the copysign operation using the
   3883    abs and neg primitives advertised to exist on the target.  The assumption
   3884    is that we have a split register file, and leaving op0 in fp registers,
   3885    and not playing with subregs so much, will help the register allocator.  */
   3886 
   3887 static rtx
   3888 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
   3889 		        int bitpos, bool op0_is_abs)
   3890 {
   3891   scalar_int_mode imode;
   3892   enum insn_code icode;
   3893   rtx sign;
   3894   rtx_code_label *label;
   3895 
   3896   if (target == op1)
   3897     target = NULL_RTX;
   3898 
   3899   /* Check if the back end provides an insn that handles signbit for the
   3900      argument's mode. */
   3901   icode = optab_handler (signbit_optab, mode);
   3902   if (icode != CODE_FOR_nothing)
   3903     {
   3904       imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
   3905       sign = gen_reg_rtx (imode);
   3906       emit_unop_insn (icode, sign, op1, UNKNOWN);
   3907     }
   3908   else
   3909     {
   3910       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   3911 	{
   3912 	  if (!int_mode_for_mode (mode).exists (&imode))
   3913 	    return NULL_RTX;
   3914 	  op1 = gen_lowpart (imode, op1);
   3915 	}
   3916       else
   3917 	{
   3918 	  int word;
   3919 
   3920 	  imode = word_mode;
   3921 	  if (FLOAT_WORDS_BIG_ENDIAN)
   3922 	    word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
   3923 	  else
   3924 	    word = bitpos / BITS_PER_WORD;
   3925 	  bitpos = bitpos % BITS_PER_WORD;
   3926 	  op1 = operand_subword_force (op1, word, mode);
   3927 	}
   3928 
   3929       wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
   3930       sign = expand_binop (imode, and_optab, op1,
   3931 			   immed_wide_int_const (mask, imode),
   3932 			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
   3933     }
   3934 
   3935   if (!op0_is_abs)
   3936     {
   3937       op0 = expand_unop (mode, abs_optab, op0, target, 0);
   3938       if (op0 == NULL)
   3939 	return NULL_RTX;
   3940       target = op0;
   3941     }
   3942   else
   3943     {
   3944       if (target == NULL_RTX)
   3945         target = copy_to_reg (op0);
   3946       else
   3947 	emit_move_insn (target, op0);
   3948     }
   3949 
   3950   label = gen_label_rtx ();
   3951   emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
   3952 
   3953   if (CONST_DOUBLE_AS_FLOAT_P (op0))
   3954     op0 = simplify_unary_operation (NEG, mode, op0, mode);
   3955   else
   3956     op0 = expand_unop (mode, neg_optab, op0, target, 0);
   3957   if (op0 != target)
   3958     emit_move_insn (target, op0);
   3959 
   3960   emit_label (label);
   3961 
   3962   return target;
   3963 }
   3964 
   3965 
   3966 /* A subroutine of expand_copysign, perform the entire copysign operation
   3967    with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
   3968    is true if op0 is known to have its sign bit clear.  */
   3969 
   3970 static rtx
   3971 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
   3972 		     int bitpos, bool op0_is_abs)
   3973 {
   3974   scalar_int_mode imode;
   3975   int word, nwords, i;
   3976   rtx temp;
   3977   rtx_insn *insns;
   3978 
   3979   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   3980     {
   3981       if (!int_mode_for_mode (mode).exists (&imode))
   3982 	return NULL_RTX;
   3983       word = 0;
   3984       nwords = 1;
   3985     }
   3986   else
   3987     {
   3988       imode = word_mode;
   3989 
   3990       if (FLOAT_WORDS_BIG_ENDIAN)
   3991 	word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
   3992       else
   3993 	word = bitpos / BITS_PER_WORD;
   3994       bitpos = bitpos % BITS_PER_WORD;
   3995       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
   3996     }
   3997 
   3998   wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
   3999 
   4000   if (target == 0
   4001       || target == op0
   4002       || target == op1
   4003       || reg_overlap_mentioned_p (target, op0)
   4004       || reg_overlap_mentioned_p (target, op1)
   4005       || (nwords > 1 && !valid_multiword_target_p (target)))
   4006     target = gen_reg_rtx (mode);
   4007 
   4008   if (nwords > 1)
   4009     {
   4010       start_sequence ();
   4011 
   4012       for (i = 0; i < nwords; ++i)
   4013 	{
   4014 	  rtx targ_piece = operand_subword (target, i, 1, mode);
   4015 	  rtx op0_piece = operand_subword_force (op0, i, mode);
   4016 
   4017 	  if (i == word)
   4018 	    {
   4019 	      if (!op0_is_abs)
   4020 		op0_piece
   4021 		  = expand_binop (imode, and_optab, op0_piece,
   4022 				  immed_wide_int_const (~mask, imode),
   4023 				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
   4024 	      op1 = expand_binop (imode, and_optab,
   4025 				  operand_subword_force (op1, i, mode),
   4026 				  immed_wide_int_const (mask, imode),
   4027 				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
   4028 
   4029 	      temp = expand_binop (imode, ior_optab, op0_piece, op1,
   4030 				   targ_piece, 1, OPTAB_LIB_WIDEN);
   4031 	      if (temp != targ_piece)
   4032 		emit_move_insn (targ_piece, temp);
   4033 	    }
   4034 	  else
   4035 	    emit_move_insn (targ_piece, op0_piece);
   4036 	}
   4037 
   4038       insns = get_insns ();
   4039       end_sequence ();
   4040 
   4041       emit_insn (insns);
   4042     }
   4043   else
   4044     {
   4045       op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
   4046 		          immed_wide_int_const (mask, imode),
   4047 		          NULL_RTX, 1, OPTAB_LIB_WIDEN);
   4048 
   4049       op0 = gen_lowpart (imode, op0);
   4050       if (!op0_is_abs)
   4051 	op0 = expand_binop (imode, and_optab, op0,
   4052 			    immed_wide_int_const (~mask, imode),
   4053 			    NULL_RTX, 1, OPTAB_LIB_WIDEN);
   4054 
   4055       temp = expand_binop (imode, ior_optab, op0, op1,
   4056 			   gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
   4057       target = lowpart_subreg_maybe_copy (mode, temp, imode);
   4058     }
   4059 
   4060   return target;
   4061 }
   4062 
   4063 /* Expand the C99 copysign operation.  OP0 and OP1 must be the same
   4064    scalar floating point mode.  Return NULL if we do not know how to
   4065    expand the operation inline.  */
   4066 
   4067 rtx
   4068 expand_copysign (rtx op0, rtx op1, rtx target)
   4069 {
   4070   scalar_float_mode mode;
   4071   const struct real_format *fmt;
   4072   bool op0_is_abs;
   4073   rtx temp;
   4074 
   4075   mode = as_a <scalar_float_mode> (GET_MODE (op0));
   4076   gcc_assert (GET_MODE (op1) == mode);
   4077 
   4078   /* First try to do it with a special instruction.  */
   4079   temp = expand_binop (mode, copysign_optab, op0, op1,
   4080 		       target, 0, OPTAB_DIRECT);
   4081   if (temp)
   4082     return temp;
   4083 
   4084   fmt = REAL_MODE_FORMAT (mode);
   4085   if (fmt == NULL || !fmt->has_signed_zero)
   4086     return NULL_RTX;
   4087 
   4088   op0_is_abs = false;
   4089   if (CONST_DOUBLE_AS_FLOAT_P (op0))
   4090     {
   4091       if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
   4092 	op0 = simplify_unary_operation (ABS, mode, op0, mode);
   4093       op0_is_abs = true;
   4094     }
   4095 
   4096   if (fmt->signbit_ro >= 0
   4097       && (CONST_DOUBLE_AS_FLOAT_P (op0)
   4098 	  || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
   4099 	      && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
   4100     {
   4101       temp = expand_copysign_absneg (mode, op0, op1, target,
   4102 				     fmt->signbit_ro, op0_is_abs);
   4103       if (temp)
   4104 	return temp;
   4105     }
   4106 
   4107   if (fmt->signbit_rw < 0)
   4108     return NULL_RTX;
   4109   return expand_copysign_bit (mode, op0, op1, target,
   4110 			      fmt->signbit_rw, op0_is_abs);
   4111 }
   4112 
   4113 /* Generate an instruction whose insn-code is INSN_CODE,
   4115    with two operands: an output TARGET and an input OP0.
   4116    TARGET *must* be nonzero, and the output is always stored there.
   4117    CODE is an rtx code such that (CODE OP0) is an rtx that describes
   4118    the value that is stored into TARGET.
   4119 
   4120    Return false if expansion failed.  */
   4121 
   4122 bool
   4123 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
   4124 		      enum rtx_code code)
   4125 {
   4126   class expand_operand ops[2];
   4127   rtx_insn *pat;
   4128 
   4129   create_output_operand (&ops[0], target, GET_MODE (target));
   4130   create_input_operand (&ops[1], op0, GET_MODE (op0));
   4131   pat = maybe_gen_insn (icode, 2, ops);
   4132   if (!pat)
   4133     return false;
   4134 
   4135   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
   4136       && code != UNKNOWN)
   4137     add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
   4138 		    GET_MODE (op0));
   4139 
   4140   emit_insn (pat);
   4141 
   4142   if (ops[0].value != target)
   4143     emit_move_insn (target, ops[0].value);
   4144   return true;
   4145 }
   4146 /* Generate an instruction whose insn-code is INSN_CODE,
   4147    with two operands: an output TARGET and an input OP0.
   4148    TARGET *must* be nonzero, and the output is always stored there.
   4149    CODE is an rtx code such that (CODE OP0) is an rtx that describes
   4150    the value that is stored into TARGET.  */
   4151 
   4152 void
   4153 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
   4154 {
   4155   bool ok = maybe_emit_unop_insn (icode, target, op0, code);
   4156   gcc_assert (ok);
   4157 }
   4158 
   4159 struct no_conflict_data
   4161 {
   4162   rtx target;
   4163   rtx_insn *first, *insn;
   4164   bool must_stay;
   4165 };
   4166 
   4167 /* Called via note_stores by emit_libcall_block.  Set P->must_stay if
   4168    the currently examined clobber / store has to stay in the list of
   4169    insns that constitute the actual libcall block.  */
   4170 static void
   4171 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
   4172 {
   4173   struct no_conflict_data *p= (struct no_conflict_data *) p0;
   4174 
   4175   /* If this inns directly contributes to setting the target, it must stay.  */
   4176   if (reg_overlap_mentioned_p (p->target, dest))
   4177     p->must_stay = true;
   4178   /* If we haven't committed to keeping any other insns in the list yet,
   4179      there is nothing more to check.  */
   4180   else if (p->insn == p->first)
   4181     return;
   4182   /* If this insn sets / clobbers a register that feeds one of the insns
   4183      already in the list, this insn has to stay too.  */
   4184   else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
   4185 	   || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
   4186 	   || reg_used_between_p (dest, p->first, p->insn)
   4187 	   /* Likewise if this insn depends on a register set by a previous
   4188 	      insn in the list, or if it sets a result (presumably a hard
   4189 	      register) that is set or clobbered by a previous insn.
   4190 	      N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
   4191 	      SET_DEST perform the former check on the address, and the latter
   4192 	      check on the MEM.  */
   4193 	   || (GET_CODE (set) == SET
   4194 	       && (modified_in_p (SET_SRC (set), p->first)
   4195 		   || modified_in_p (SET_DEST (set), p->first)
   4196 		   || modified_between_p (SET_SRC (set), p->first, p->insn)
   4197 		   || modified_between_p (SET_DEST (set), p->first, p->insn))))
   4198     p->must_stay = true;
   4199 }
   4200 
   4201 
   4202 /* Emit code to make a call to a constant function or a library call.
   4204 
   4205    INSNS is a list containing all insns emitted in the call.
   4206    These insns leave the result in RESULT.  Our block is to copy RESULT
   4207    to TARGET, which is logically equivalent to EQUIV.
   4208 
   4209    We first emit any insns that set a pseudo on the assumption that these are
   4210    loading constants into registers; doing so allows them to be safely cse'ed
   4211    between blocks.  Then we emit all the other insns in the block, followed by
   4212    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
   4213    note with an operand of EQUIV.  */
   4214 
   4215 static void
   4216 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
   4217 		      bool equiv_may_trap)
   4218 {
   4219   rtx final_dest = target;
   4220   rtx_insn *next, *last, *insn;
   4221 
   4222   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
   4223      into a MEM later.  Protect the libcall block from this change.  */
   4224   if (! REG_P (target) || REG_USERVAR_P (target))
   4225     target = gen_reg_rtx (GET_MODE (target));
   4226 
   4227   /* If we're using non-call exceptions, a libcall corresponding to an
   4228      operation that may trap may also trap.  */
   4229   /* ??? See the comment in front of make_reg_eh_region_note.  */
   4230   if (cfun->can_throw_non_call_exceptions
   4231       && (equiv_may_trap || may_trap_p (equiv)))
   4232     {
   4233       for (insn = insns; insn; insn = NEXT_INSN (insn))
   4234 	if (CALL_P (insn))
   4235 	  {
   4236 	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
   4237 	    if (note)
   4238 	      {
   4239 		int lp_nr = INTVAL (XEXP (note, 0));
   4240 		if (lp_nr == 0 || lp_nr == INT_MIN)
   4241 		  remove_note (insn, note);
   4242 	      }
   4243 	  }
   4244     }
   4245   else
   4246     {
   4247       /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
   4248 	 reg note to indicate that this call cannot throw or execute a nonlocal
   4249 	 goto (unless there is already a REG_EH_REGION note, in which case
   4250 	 we update it).  */
   4251       for (insn = insns; insn; insn = NEXT_INSN (insn))
   4252 	if (CALL_P (insn))
   4253 	  make_reg_eh_region_note_nothrow_nononlocal (insn);
   4254     }
   4255 
   4256   /* First emit all insns that set pseudos.  Remove them from the list as
   4257      we go.  Avoid insns that set pseudos which were referenced in previous
   4258      insns.  These can be generated by move_by_pieces, for example,
   4259      to update an address.  Similarly, avoid insns that reference things
   4260      set in previous insns.  */
   4261 
   4262   for (insn = insns; insn; insn = next)
   4263     {
   4264       rtx set = single_set (insn);
   4265 
   4266       next = NEXT_INSN (insn);
   4267 
   4268       if (set != 0 && REG_P (SET_DEST (set))
   4269 	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
   4270 	{
   4271 	  struct no_conflict_data data;
   4272 
   4273 	  data.target = const0_rtx;
   4274 	  data.first = insns;
   4275 	  data.insn = insn;
   4276 	  data.must_stay = 0;
   4277 	  note_stores (insn, no_conflict_move_test, &data);
   4278 	  if (! data.must_stay)
   4279 	    {
   4280 	      if (PREV_INSN (insn))
   4281 		SET_NEXT_INSN (PREV_INSN (insn)) = next;
   4282 	      else
   4283 		insns = next;
   4284 
   4285 	      if (next)
   4286 		SET_PREV_INSN (next) = PREV_INSN (insn);
   4287 
   4288 	      add_insn (insn);
   4289 	    }
   4290 	}
   4291 
   4292       /* Some ports use a loop to copy large arguments onto the stack.
   4293 	 Don't move anything outside such a loop.  */
   4294       if (LABEL_P (insn))
   4295 	break;
   4296     }
   4297 
   4298   /* Write the remaining insns followed by the final copy.  */
   4299   for (insn = insns; insn; insn = next)
   4300     {
   4301       next = NEXT_INSN (insn);
   4302 
   4303       add_insn (insn);
   4304     }
   4305 
   4306   last = emit_move_insn (target, result);
   4307   if (equiv)
   4308     set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
   4309 
   4310   if (final_dest != target)
   4311     emit_move_insn (final_dest, target);
   4312 }
   4313 
   4314 void
   4315 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
   4316 {
   4317   emit_libcall_block_1 (insns, target, result, equiv, false);
   4318 }
   4319 
   4320 /* True if we can perform a comparison of mode MODE straightforwardly.
   4322    PURPOSE describes how this comparison will be used.  CODE is the rtx
   4323    comparison code we will be using.
   4324 
   4325    ??? Actually, CODE is slightly weaker than that.  A target is still
   4326    required to implement all of the normal bcc operations, but not
   4327    required to implement all (or any) of the unordered bcc operations.  */
   4328 
   4329 bool
   4330 can_compare_p (enum rtx_code code, machine_mode mode,
   4331 	       enum can_compare_purpose purpose)
   4332 {
   4333   rtx test;
   4334   test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
   4335   do
   4336     {
   4337       enum insn_code icode;
   4338 
   4339       if (purpose == ccp_jump
   4340           && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
   4341           && insn_operand_matches (icode, 0, test))
   4342 	return true;
   4343       if (purpose == ccp_store_flag
   4344           && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
   4345           && insn_operand_matches (icode, 1, test))
   4346 	return true;
   4347       if (purpose == ccp_cmov
   4348 	  && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
   4349 	return true;
   4350 
   4351       mode = GET_MODE_WIDER_MODE (mode).else_void ();
   4352       PUT_MODE (test, mode);
   4353     }
   4354   while (mode != VOIDmode);
   4355 
   4356   return false;
   4357 }
   4358 
   4359 /* Return whether RTL code CODE corresponds to an unsigned optab.  */
   4360 
   4361 static bool
   4362 unsigned_optab_p (enum rtx_code code)
   4363 {
   4364   return code == LTU || code == LEU || code == GTU || code == GEU;
   4365 }
   4366 
   4367 /* Return whether the backend-emitted comparison for code CODE, comparing
   4368    operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
   4369    operand OPNO of pattern ICODE.  */
   4370 
   4371 static bool
   4372 insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
   4373 			  enum rtx_code code, machine_mode mask_mode,
   4374 			  machine_mode value_mode)
   4375 {
   4376   rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
   4377   rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
   4378   rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
   4379   return insn_operand_matches (icode, opno, test);
   4380 }
   4381 
   4382 /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
   4383    for code CODE, comparing operands of mode VALUE_MODE and producing a result
   4384    with MASK_MODE.  */
   4385 
   4386 bool
   4387 can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
   4388 		       machine_mode mask_mode)
   4389 {
   4390   enum insn_code icode
   4391       = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
   4392   if (icode == CODE_FOR_nothing)
   4393     return false;
   4394 
   4395   return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
   4396 }
   4397 
   4398 /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
   4399    code CODE, comparing operands of mode CMP_OP_MODE and producing a result
   4400    with VALUE_MODE.  */
   4401 
   4402 bool
   4403 can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
   4404 		     machine_mode cmp_op_mode)
   4405 {
   4406   enum insn_code icode
   4407       = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
   4408   if (icode == CODE_FOR_nothing)
   4409     return false;
   4410 
   4411   return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
   4412 }
   4413 
   4414 /* Return whether the backend can emit vector set instructions for inserting
   4415    element into vector at variable index position.  */
   4416 
   4417 bool
   4418 can_vec_set_var_idx_p (machine_mode vec_mode)
   4419 {
   4420   if (!VECTOR_MODE_P (vec_mode))
   4421     return false;
   4422 
   4423   machine_mode inner_mode = GET_MODE_INNER (vec_mode);
   4424 
   4425   rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1);
   4426   rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2);
   4427 
   4428   enum insn_code icode = optab_handler (vec_set_optab, vec_mode);
   4429 
   4430   const struct insn_data_d *data = &insn_data[icode];
   4431   machine_mode idx_mode = data->operand[2].mode;
   4432 
   4433   rtx reg3 = alloca_raw_REG (idx_mode, LAST_VIRTUAL_REGISTER + 3);
   4434 
   4435   return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
   4436 	 && insn_operand_matches (icode, 1, reg2)
   4437 	 && insn_operand_matches (icode, 2, reg3);
   4438 }
   4439 
   4440 /* Return whether the backend can emit a vec_extract instruction with
   4441    a non-constant index.  */
   4442 bool
   4443 can_vec_extract_var_idx_p (machine_mode vec_mode, machine_mode extr_mode)
   4444 {
   4445   if (!VECTOR_MODE_P (vec_mode))
   4446     return false;
   4447 
   4448   rtx reg1 = alloca_raw_REG (extr_mode, LAST_VIRTUAL_REGISTER + 1);
   4449   rtx reg2 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 2);
   4450 
   4451   enum insn_code icode = convert_optab_handler (vec_extract_optab,
   4452 						vec_mode, extr_mode);
   4453 
   4454   const struct insn_data_d *data = &insn_data[icode];
   4455   machine_mode idx_mode = data->operand[2].mode;
   4456 
   4457   rtx reg3 = alloca_raw_REG (idx_mode, LAST_VIRTUAL_REGISTER + 3);
   4458 
   4459   return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
   4460 	 && insn_operand_matches (icode, 1, reg2)
   4461 	 && insn_operand_matches (icode, 2, reg3);
   4462 }
   4463 
   4464 /* This function is called when we are going to emit a compare instruction that
   4465    compares the values found in X and Y, using the rtl operator COMPARISON.
   4466 
   4467    If they have mode BLKmode, then SIZE specifies the size of both operands.
   4468 
   4469    UNSIGNEDP nonzero says that the operands are unsigned;
   4470    this matters if they need to be widened (as given by METHODS).
   4471 
   4472    *PTEST is where the resulting comparison RTX is returned or NULL_RTX
   4473    if we failed to produce one.
   4474 
   4475    *PMODE is the mode of the inputs (in case they are const_int).
   4476 
   4477    This function performs all the setup necessary so that the caller only has
   4478    to emit a single comparison insn.  This setup can involve doing a BLKmode
   4479    comparison or emitting a library call to perform the comparison if no insn
   4480    is available to handle it.
   4481    The values which are passed in through pointers can be modified; the caller
   4482    should perform the comparison on the modified values.  Constant
   4483    comparisons must have already been folded.  */
   4484 
   4485 static void
   4486 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
   4487 		  int unsignedp, enum optab_methods methods,
   4488 		  rtx *ptest, machine_mode *pmode)
   4489 {
   4490   machine_mode mode = *pmode;
   4491   rtx libfunc, test;
   4492   machine_mode cmp_mode;
   4493 
   4494   /* The other methods are not needed.  */
   4495   gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
   4496 	      || methods == OPTAB_LIB_WIDEN);
   4497 
   4498   if (CONST_SCALAR_INT_P (y))
   4499     canonicalize_comparison (mode, &comparison, &y);
   4500 
   4501   /* If we are optimizing, force expensive constants into a register.  */
   4502   if (CONSTANT_P (x) && optimize
   4503       && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
   4504           > COSTS_N_INSNS (1))
   4505       && can_create_pseudo_p ())
   4506     x = force_reg (mode, x);
   4507 
   4508   if (CONSTANT_P (y) && optimize
   4509       && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
   4510           > COSTS_N_INSNS (1))
   4511       && can_create_pseudo_p ())
   4512     y = force_reg (mode, y);
   4513 
   4514   /* Don't let both operands fail to indicate the mode.  */
   4515   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
   4516     x = force_reg (mode, x);
   4517   if (mode == VOIDmode)
   4518     mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
   4519 
   4520   /* Handle all BLKmode compares.  */
   4521 
   4522   if (mode == BLKmode)
   4523     {
   4524       machine_mode result_mode;
   4525       enum insn_code cmp_code;
   4526       rtx result;
   4527       rtx opalign
   4528 	= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
   4529 
   4530       gcc_assert (size);
   4531 
   4532       /* Try to use a memory block compare insn - either cmpstr
   4533 	 or cmpmem will do.  */
   4534       opt_scalar_int_mode cmp_mode_iter;
   4535       FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
   4536 	{
   4537 	  scalar_int_mode cmp_mode = cmp_mode_iter.require ();
   4538 	  cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
   4539 	  if (cmp_code == CODE_FOR_nothing)
   4540 	    cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
   4541 	  if (cmp_code == CODE_FOR_nothing)
   4542 	    cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
   4543 	  if (cmp_code == CODE_FOR_nothing)
   4544 	    continue;
   4545 
   4546 	  /* Must make sure the size fits the insn's mode.  */
   4547 	  if (CONST_INT_P (size)
   4548 	      ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
   4549 	      : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
   4550 		 > GET_MODE_BITSIZE (cmp_mode)))
   4551 	    continue;
   4552 
   4553 	  result_mode = insn_data[cmp_code].operand[0].mode;
   4554 	  result = gen_reg_rtx (result_mode);
   4555 	  size = convert_to_mode (cmp_mode, size, 1);
   4556 	  emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
   4557 
   4558           *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
   4559           *pmode = result_mode;
   4560 	  return;
   4561 	}
   4562 
   4563       if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
   4564 	goto fail;
   4565 
   4566       /* Otherwise call a library function.  */
   4567       result = emit_block_comp_via_libcall (x, y, size);
   4568 
   4569       x = result;
   4570       y = const0_rtx;
   4571       mode = TYPE_MODE (integer_type_node);
   4572       methods = OPTAB_LIB_WIDEN;
   4573       unsignedp = false;
   4574     }
   4575 
   4576   /* Don't allow operands to the compare to trap, as that can put the
   4577      compare and branch in different basic blocks.  */
   4578   if (cfun->can_throw_non_call_exceptions)
   4579     {
   4580       if (!can_create_pseudo_p () && (may_trap_p (x) || may_trap_p (y)))
   4581 	goto fail;
   4582       if (may_trap_p (x))
   4583 	x = copy_to_reg (x);
   4584       if (may_trap_p (y))
   4585 	y = copy_to_reg (y);
   4586     }
   4587 
   4588   if (GET_MODE_CLASS (mode) == MODE_CC)
   4589     {
   4590       enum insn_code icode = optab_handler (cbranch_optab, CCmode);
   4591       test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
   4592       if (icode != CODE_FOR_nothing
   4593 	  && insn_operand_matches (icode, 0, test))
   4594 	{
   4595 	  *ptest = test;
   4596 	  return;
   4597 	}
   4598       else
   4599 	goto fail;
   4600     }
   4601 
   4602   test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
   4603   FOR_EACH_WIDER_MODE_FROM (cmp_mode, mode)
   4604     {
   4605       enum insn_code icode;
   4606       icode = optab_handler (cbranch_optab, cmp_mode);
   4607       if (icode != CODE_FOR_nothing
   4608 	  && insn_operand_matches (icode, 0, test))
   4609 	{
   4610 	  rtx_insn *last = get_last_insn ();
   4611 	  rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
   4612 	  rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
   4613 	  if (op0 && op1
   4614 	      && insn_operand_matches (icode, 1, op0)
   4615 	      && insn_operand_matches (icode, 2, op1))
   4616 	    {
   4617 	      XEXP (test, 0) = op0;
   4618 	      XEXP (test, 1) = op1;
   4619 	      *ptest = test;
   4620 	      *pmode = cmp_mode;
   4621 	      return;
   4622 	    }
   4623 	  delete_insns_since (last);
   4624 	}
   4625 
   4626       if (methods == OPTAB_DIRECT)
   4627 	break;
   4628     }
   4629 
   4630   if (methods != OPTAB_LIB_WIDEN)
   4631     goto fail;
   4632 
   4633   if (SCALAR_FLOAT_MODE_P (mode))
   4634     {
   4635       /* Small trick if UNORDERED isn't implemented by the hardware.  */
   4636       if (comparison == UNORDERED && rtx_equal_p (x, y))
   4637 	{
   4638 	  prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
   4639 			    ptest, pmode);
   4640 	  if (*ptest)
   4641 	    return;
   4642 	}
   4643 
   4644       prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
   4645     }
   4646   else
   4647     {
   4648       rtx result;
   4649       machine_mode ret_mode;
   4650 
   4651       /* Handle a libcall just for the mode we are using.  */
   4652       libfunc = optab_libfunc (cmp_optab, mode);
   4653       gcc_assert (libfunc);
   4654 
   4655       /* If we want unsigned, and this mode has a distinct unsigned
   4656 	 comparison routine, use that.  */
   4657       if (unsignedp)
   4658 	{
   4659 	  rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
   4660 	  if (ulibfunc)
   4661 	    libfunc = ulibfunc;
   4662 	}
   4663 
   4664       ret_mode = targetm.libgcc_cmp_return_mode ();
   4665       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
   4666 					ret_mode, x, mode, y, mode);
   4667 
   4668       /* There are two kinds of comparison routines. Biased routines
   4669 	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
   4670 	 of gcc expect that the comparison operation is equivalent
   4671 	 to the modified comparison. For signed comparisons compare the
   4672 	 result against 1 in the biased case, and zero in the unbiased
   4673 	 case. For unsigned comparisons always compare against 1 after
   4674 	 biasing the unbiased result by adding 1. This gives us a way to
   4675 	 represent LTU.
   4676 	 The comparisons in the fixed-point helper library are always
   4677 	 biased.  */
   4678       x = result;
   4679       y = const1_rtx;
   4680 
   4681       if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
   4682 	{
   4683 	  if (unsignedp)
   4684 	    x = plus_constant (ret_mode, result, 1);
   4685 	  else
   4686 	    y = const0_rtx;
   4687 	}
   4688 
   4689       *pmode = ret_mode;
   4690       prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
   4691 			ptest, pmode);
   4692     }
   4693 
   4694   return;
   4695 
   4696  fail:
   4697   *ptest = NULL_RTX;
   4698 }
   4699 
   4700 /* Before emitting an insn with code ICODE, make sure that X, which is going
   4701    to be used for operand OPNUM of the insn, is converted from mode MODE to
   4702    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
   4703    that it is accepted by the operand predicate.  Return the new value.  */
   4704 
   4705 rtx
   4706 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
   4707 		 machine_mode wider_mode, int unsignedp)
   4708 {
   4709   if (mode != wider_mode)
   4710     x = convert_modes (wider_mode, mode, x, unsignedp);
   4711 
   4712   if (!insn_operand_matches (icode, opnum, x))
   4713     {
   4714       machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
   4715       if (reload_completed)
   4716 	return NULL_RTX;
   4717       if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
   4718 	return NULL_RTX;
   4719       x = copy_to_mode_reg (op_mode, x);
   4720     }
   4721 
   4722   return x;
   4723 }
   4724 
   4725 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
   4726    we can do the branch.  */
   4727 
   4728 static void
   4729 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
   4730 			  direct_optab cmp_optab, profile_probability prob,
   4731 			  bool test_branch)
   4732 {
   4733   machine_mode optab_mode;
   4734   enum mode_class mclass;
   4735   enum insn_code icode;
   4736   rtx_insn *insn;
   4737 
   4738   mclass = GET_MODE_CLASS (mode);
   4739   optab_mode = (mclass == MODE_CC) ? CCmode : mode;
   4740   icode = optab_handler (cmp_optab, optab_mode);
   4741 
   4742   gcc_assert (icode != CODE_FOR_nothing);
   4743   gcc_assert (test_branch || insn_operand_matches (icode, 0, test));
   4744   if (test_branch)
   4745     insn = emit_jump_insn (GEN_FCN (icode) (XEXP (test, 0),
   4746 					    XEXP (test, 1), label));
   4747   else
   4748     insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
   4749 					    XEXP (test, 1), label));
   4750 
   4751   if (prob.initialized_p ()
   4752       && profile_status_for_fn (cfun) != PROFILE_ABSENT
   4753       && insn
   4754       && JUMP_P (insn)
   4755       && any_condjump_p (insn)
   4756       && !find_reg_note (insn, REG_BR_PROB, 0))
   4757     add_reg_br_prob_note (insn, prob);
   4758 }
   4759 
   4760 /* PTEST points to a comparison that compares its first operand with zero.
   4761    Check to see if it can be performed as a bit-test-and-branch instead.
   4762    On success, return the instruction that performs the bit-test-and-branch
   4763    and replace the second operand of *PTEST with the bit number to test.
   4764    On failure, return CODE_FOR_nothing and leave *PTEST unchanged.
   4765 
   4766    Note that the comparison described by *PTEST should not be taken
   4767    literally after a successful return.  *PTEST is just a convenient
   4768    place to store the two operands of the bit-and-test.
   4769 
   4770    VAL must contain the original tree expression for the first operand
   4771    of *PTEST.  */
   4772 
   4773 static enum insn_code
   4774 validate_test_and_branch (tree val, rtx *ptest, machine_mode *pmode, optab *res)
   4775 {
   4776   if (!val || TREE_CODE (val) != SSA_NAME)
   4777     return CODE_FOR_nothing;
   4778 
   4779   machine_mode mode = TYPE_MODE (TREE_TYPE (val));
   4780   rtx test = *ptest;
   4781   direct_optab optab;
   4782 
   4783   if (GET_CODE (test) == EQ)
   4784     optab = tbranch_eq_optab;
   4785   else if (GET_CODE (test) == NE)
   4786     optab = tbranch_ne_optab;
   4787   else
   4788     return CODE_FOR_nothing;
   4789 
   4790   *res = optab;
   4791 
   4792   /* If the target supports the testbit comparison directly, great.  */
   4793   auto icode = direct_optab_handler (optab, mode);
   4794   if (icode == CODE_FOR_nothing)
   4795     return icode;
   4796 
   4797   if (tree_zero_one_valued_p (val))
   4798     {
   4799       auto pos = BITS_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 : 0;
   4800       XEXP (test, 1) = gen_int_mode (pos, mode);
   4801       *ptest = test;
   4802       *pmode = mode;
   4803       return icode;
   4804     }
   4805 
   4806   wide_int wcst = get_nonzero_bits (val);
   4807   if (wcst == -1)
   4808     return CODE_FOR_nothing;
   4809 
   4810   int bitpos;
   4811 
   4812   if ((bitpos = wi::exact_log2 (wcst)) == -1)
   4813     return CODE_FOR_nothing;
   4814 
   4815   auto pos = BITS_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 - bitpos : bitpos;
   4816   XEXP (test, 1) = gen_int_mode (pos, mode);
   4817   *ptest = test;
   4818   *pmode = mode;
   4819   return icode;
   4820 }
   4821 
   4822 /* Generate code to compare X with Y so that the condition codes are
   4823    set and to jump to LABEL if the condition is true.  If X is a
   4824    constant and Y is not a constant, then the comparison is swapped to
   4825    ensure that the comparison RTL has the canonical form.
   4826 
   4827    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
   4828    need to be widened.  UNSIGNEDP is also used to select the proper
   4829    branch condition code.
   4830 
   4831    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
   4832 
   4833    MODE is the mode of the inputs (in case they are const_int).
   4834 
   4835    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
   4836    It will be potentially converted into an unsigned variant based on
   4837    UNSIGNEDP to select a proper jump instruction.
   4838 
   4839    PROB is the probability of jumping to LABEL.  If the comparison is against
   4840    zero then VAL contains the expression from which the non-zero RTL is
   4841    derived.  */
   4842 
   4843 void
   4844 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
   4845 			 machine_mode mode, int unsignedp, tree val, rtx label,
   4846                          profile_probability prob)
   4847 {
   4848   rtx op0 = x, op1 = y;
   4849   rtx test;
   4850 
   4851   /* Swap operands and condition to ensure canonical RTL.  */
   4852   if (swap_commutative_operands_p (x, y)
   4853       && can_compare_p (swap_condition (comparison), mode, ccp_jump))
   4854     {
   4855       op0 = y, op1 = x;
   4856       comparison = swap_condition (comparison);
   4857     }
   4858 
   4859   /* If OP0 is still a constant, then both X and Y must be constants
   4860      or the opposite comparison is not supported.  Force X into a register
   4861      to create canonical RTL.  */
   4862   if (CONSTANT_P (op0))
   4863     op0 = force_reg (mode, op0);
   4864 
   4865   if (unsignedp)
   4866     comparison = unsigned_condition (comparison);
   4867 
   4868   prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
   4869 		    &test, &mode);
   4870 
   4871   /* Check if we're comparing a truth type with 0, and if so check if
   4872      the target supports tbranch.  */
   4873   machine_mode tmode = mode;
   4874   direct_optab optab;
   4875   if (op1 == CONST0_RTX (GET_MODE (op1))
   4876       && validate_test_and_branch (val, &test, &tmode,
   4877 				   &optab) != CODE_FOR_nothing)
   4878     {
   4879       emit_cmp_and_jump_insn_1 (test, tmode, label, optab, prob, true);
   4880       return;
   4881     }
   4882 
   4883   emit_cmp_and_jump_insn_1 (test, mode, label, cbranch_optab, prob, false);
   4884 }
   4885 
   4886 /* Overloaded version of emit_cmp_and_jump_insns in which VAL is unknown.  */
   4887 
   4888 void
   4889 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
   4890 			 machine_mode mode, int unsignedp, rtx label,
   4891 			 profile_probability prob)
   4892 {
   4893   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, NULL,
   4894 			   label, prob);
   4895 }
   4896 
   4897 
   4898 /* Emit a library call comparison between floating point X and Y.
   4899    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
   4900 
   4901 static void
   4902 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
   4903 		       rtx *ptest, machine_mode *pmode)
   4904 {
   4905   enum rtx_code swapped = swap_condition (comparison);
   4906   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
   4907   machine_mode orig_mode = GET_MODE (x);
   4908   machine_mode mode;
   4909   rtx true_rtx, false_rtx;
   4910   rtx value, target, equiv;
   4911   rtx_insn *insns;
   4912   rtx libfunc = 0;
   4913   bool reversed_p = false;
   4914   scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
   4915 
   4916   FOR_EACH_WIDER_MODE_FROM (mode, orig_mode)
   4917     {
   4918       if (code_to_optab (comparison)
   4919 	  && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
   4920 	break;
   4921 
   4922       if (code_to_optab (swapped)
   4923 	  && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
   4924 	{
   4925 	  std::swap (x, y);
   4926 	  comparison = swapped;
   4927 	  break;
   4928 	}
   4929 
   4930       if (code_to_optab (reversed)
   4931 	  && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
   4932 	{
   4933 	  comparison = reversed;
   4934 	  reversed_p = true;
   4935 	  break;
   4936 	}
   4937     }
   4938 
   4939   gcc_assert (mode != VOIDmode);
   4940 
   4941   if (mode != orig_mode)
   4942     {
   4943       x = convert_to_mode (mode, x, 0);
   4944       y = convert_to_mode (mode, y, 0);
   4945     }
   4946 
   4947   /* Attach a REG_EQUAL note describing the semantics of the libcall to
   4948      the RTL.  The allows the RTL optimizers to delete the libcall if the
   4949      condition can be determined at compile-time.  */
   4950   if (comparison == UNORDERED
   4951       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
   4952     {
   4953       true_rtx = const_true_rtx;
   4954       false_rtx = const0_rtx;
   4955     }
   4956   else
   4957     {
   4958       switch (comparison)
   4959         {
   4960         case EQ:
   4961           true_rtx = const0_rtx;
   4962           false_rtx = const_true_rtx;
   4963           break;
   4964 
   4965         case NE:
   4966           true_rtx = const_true_rtx;
   4967           false_rtx = const0_rtx;
   4968           break;
   4969 
   4970         case GT:
   4971           true_rtx = const1_rtx;
   4972           false_rtx = const0_rtx;
   4973           break;
   4974 
   4975         case GE:
   4976           true_rtx = const0_rtx;
   4977           false_rtx = constm1_rtx;
   4978           break;
   4979 
   4980         case LT:
   4981           true_rtx = constm1_rtx;
   4982           false_rtx = const0_rtx;
   4983           break;
   4984 
   4985         case LE:
   4986           true_rtx = const0_rtx;
   4987           false_rtx = const1_rtx;
   4988           break;
   4989 
   4990         default:
   4991           gcc_unreachable ();
   4992         }
   4993     }
   4994 
   4995   if (comparison == UNORDERED)
   4996     {
   4997       rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
   4998       equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
   4999       equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
   5000 				    temp, const_true_rtx, equiv);
   5001     }
   5002   else
   5003     {
   5004       equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
   5005       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
   5006         equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
   5007                                       equiv, true_rtx, false_rtx);
   5008     }
   5009 
   5010   start_sequence ();
   5011   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
   5012 				   cmp_mode, x, mode, y, mode);
   5013   insns = get_insns ();
   5014   end_sequence ();
   5015 
   5016   target = gen_reg_rtx (cmp_mode);
   5017   emit_libcall_block (insns, target, value, equiv);
   5018 
   5019   if (comparison == UNORDERED
   5020       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
   5021       || reversed_p)
   5022     *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
   5023   else
   5024     *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
   5025 
   5026   *pmode = cmp_mode;
   5027 }
   5028 
   5029 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
   5031 
   5032 void
   5033 emit_indirect_jump (rtx loc)
   5034 {
   5035   if (!targetm.have_indirect_jump ())
   5036     sorry ("indirect jumps are not available on this target");
   5037   else
   5038     {
   5039       class expand_operand ops[1];
   5040       create_address_operand (&ops[0], loc);
   5041       expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
   5042       emit_barrier ();
   5043     }
   5044 }
   5045 
   5046 
   5048 /* Emit a conditional move instruction if the machine supports one for that
   5049    condition and machine mode.
   5050 
   5051    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
   5052    the mode to use should they be constants.  If it is VOIDmode, they cannot
   5053    both be constants.
   5054 
   5055    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
   5056    should be stored there.  MODE is the mode to use should they be constants.
   5057    If it is VOIDmode, they cannot both be constants.
   5058 
   5059    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
   5060    is not supported.  */
   5061 
   5062 rtx
   5063 emit_conditional_move (rtx target, struct rtx_comparison comp,
   5064 		       rtx op2, rtx op3,
   5065 		       machine_mode mode, int unsignedp)
   5066 {
   5067   rtx comparison;
   5068   rtx_insn *last;
   5069   enum insn_code icode;
   5070   enum rtx_code reversed;
   5071 
   5072   /* If the two source operands are identical, that's just a move.  */
   5073 
   5074   if (rtx_equal_p (op2, op3))
   5075     {
   5076       if (!target)
   5077 	target = gen_reg_rtx (mode);
   5078 
   5079       emit_move_insn (target, op3);
   5080       return target;
   5081     }
   5082 
   5083   /* If one operand is constant, make it the second one.  Only do this
   5084      if the other operand is not constant as well.  */
   5085 
   5086   if (swap_commutative_operands_p (comp.op0, comp.op1))
   5087     {
   5088       std::swap (comp.op0, comp.op1);
   5089       comp.code = swap_condition (comp.code);
   5090     }
   5091 
   5092   /* get_condition will prefer to generate LT and GT even if the old
   5093      comparison was against zero, so undo that canonicalization here since
   5094      comparisons against zero are cheaper.  */
   5095 
   5096   if (comp.code == LT && comp.op1 == const1_rtx)
   5097     comp.code = LE, comp.op1 = const0_rtx;
   5098   else if (comp.code == GT && comp.op1 == constm1_rtx)
   5099     comp.code = GE, comp.op1 = const0_rtx;
   5100 
   5101   if (comp.mode == VOIDmode)
   5102     comp.mode = GET_MODE (comp.op0);
   5103 
   5104   enum rtx_code orig_code = comp.code;
   5105   bool swapped = false;
   5106   if (swap_commutative_operands_p (op2, op3)
   5107       && ((reversed =
   5108 	   reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL))
   5109 	  != UNKNOWN))
   5110     {
   5111       std::swap (op2, op3);
   5112       comp.code = reversed;
   5113       swapped = true;
   5114     }
   5115 
   5116   if (mode == VOIDmode)
   5117     mode = GET_MODE (op2);
   5118 
   5119   icode = direct_optab_handler (movcc_optab, mode);
   5120 
   5121   if (icode == CODE_FOR_nothing)
   5122     return NULL_RTX;
   5123 
   5124   if (!target)
   5125     target = gen_reg_rtx (mode);
   5126 
   5127   for (int pass = 0; ; pass++)
   5128     {
   5129       comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code;
   5130       comparison =
   5131 	simplify_gen_relational (comp.code, VOIDmode,
   5132 				 comp.mode, comp.op0, comp.op1);
   5133 
   5134       /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
   5135 	 punt and let the caller figure out how best to deal with this
   5136 	 situation.  */
   5137       if (COMPARISON_P (comparison))
   5138 	{
   5139 	  saved_pending_stack_adjust save;
   5140 	  save_pending_stack_adjust (&save);
   5141 	  last = get_last_insn ();
   5142 	  do_pending_stack_adjust ();
   5143 	  machine_mode cmpmode = comp.mode;
   5144 	  rtx orig_op0 = XEXP (comparison, 0);
   5145 	  rtx orig_op1 = XEXP (comparison, 1);
   5146 	  rtx op2p = op2;
   5147 	  rtx op3p = op3;
   5148 	  /* If we are optimizing, force expensive constants into a register
   5149 	     but preserve an eventual equality with op2/op3.  */
   5150 	  if (CONSTANT_P (orig_op0) && optimize
   5151 	      && cmpmode == mode
   5152 	      && (rtx_cost (orig_op0, mode, COMPARE, 0,
   5153 			    optimize_insn_for_speed_p ())
   5154 		  > COSTS_N_INSNS (1))
   5155 	      && can_create_pseudo_p ())
   5156 	    {
   5157 	      if (rtx_equal_p (orig_op0, op2))
   5158 		op2p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0);
   5159 	      else if (rtx_equal_p (orig_op0, op3))
   5160 		op3p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0);
   5161 	    }
   5162 	  if (CONSTANT_P (orig_op1) && optimize
   5163 	      && cmpmode == mode
   5164 	      && (rtx_cost (orig_op1, mode, COMPARE, 0,
   5165 			    optimize_insn_for_speed_p ())
   5166 		  > COSTS_N_INSNS (1))
   5167 	      && can_create_pseudo_p ())
   5168 	    {
   5169 	      if (rtx_equal_p (orig_op1, op2))
   5170 		op2p = XEXP (comparison, 1) = force_reg (cmpmode, orig_op1);
   5171 	      else if (rtx_equal_p (orig_op1, op3))
   5172 		op3p = XEXP (comparison, 1) = force_reg (cmpmode, orig_op1);
   5173 	    }
   5174 	  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
   5175 			    GET_CODE (comparison), NULL_RTX, unsignedp,
   5176 			    OPTAB_WIDEN, &comparison, &cmpmode);
   5177 	  if (comparison)
   5178 	    {
   5179 	       rtx res = emit_conditional_move_1 (target, comparison,
   5180 						  op2p, op3p, mode);
   5181 	       if (res != NULL_RTX)
   5182 		 return res;
   5183 	    }
   5184 	  delete_insns_since (last);
   5185 	  restore_pending_stack_adjust (&save);
   5186 	}
   5187 
   5188       if (pass == 1)
   5189 	return NULL_RTX;
   5190 
   5191       /* If the preferred op2/op3 order is not usable, retry with other
   5192 	 operand order, perhaps it will expand successfully.  */
   5193       if (swapped)
   5194 	comp.code = orig_code;
   5195       else if ((reversed =
   5196 		reversed_comparison_code_parts (orig_code, comp.op0, comp.op1,
   5197 							   NULL))
   5198 	       != UNKNOWN)
   5199 	comp.code = reversed;
   5200       else
   5201 	return NULL_RTX;
   5202       std::swap (op2, op3);
   5203     }
   5204 }
   5205 
   5206 /* Helper function that, in addition to COMPARISON, also tries
   5207    the reversed REV_COMPARISON with swapped OP2 and OP3.  As opposed
   5208    to when we pass the specific constituents of a comparison, no
   5209    additional insns are emitted for it.  It might still be necessary
   5210    to emit more than one insn for the final conditional move, though.  */
   5211 
   5212 rtx
   5213 emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison,
   5214 		       rtx op2, rtx op3, machine_mode mode)
   5215 {
   5216   rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode);
   5217 
   5218   if (res != NULL_RTX)
   5219     return res;
   5220 
   5221   return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode);
   5222 }
   5223 
   5224 /* Helper for emitting a conditional move.  */
   5225 
   5226 static rtx
   5227 emit_conditional_move_1 (rtx target, rtx comparison,
   5228 			 rtx op2, rtx op3, machine_mode mode)
   5229 {
   5230   enum insn_code icode;
   5231 
   5232   if (comparison == NULL_RTX || !COMPARISON_P (comparison))
   5233     return NULL_RTX;
   5234 
   5235   /* If the two source operands are identical, that's just a move.
   5236      As the comparison comes in non-canonicalized, we must make
   5237      sure not to discard any possible side effects.  If there are
   5238      side effects, just let the target handle it.  */
   5239   if (!side_effects_p (comparison) && rtx_equal_p (op2, op3))
   5240     {
   5241       if (!target)
   5242 	target = gen_reg_rtx (mode);
   5243 
   5244       emit_move_insn (target, op3);
   5245       return target;
   5246     }
   5247 
   5248   if (mode == VOIDmode)
   5249     mode = GET_MODE (op2);
   5250 
   5251   icode = direct_optab_handler (movcc_optab, mode);
   5252 
   5253   if (icode == CODE_FOR_nothing)
   5254     return NULL_RTX;
   5255 
   5256   if (!target)
   5257     target = gen_reg_rtx (mode);
   5258 
   5259   class expand_operand ops[4];
   5260 
   5261   create_output_operand (&ops[0], target, mode);
   5262   create_fixed_operand (&ops[1], comparison);
   5263   create_input_operand (&ops[2], op2, mode);
   5264   create_input_operand (&ops[3], op3, mode);
   5265 
   5266   if (maybe_expand_insn (icode, 4, ops))
   5267     {
   5268       if (ops[0].value != target)
   5269 	convert_move (target, ops[0].value, false);
   5270       return target;
   5271     }
   5272 
   5273   return NULL_RTX;
   5274 }
   5275 
   5276 
   5277 /* Emit a conditional negate or bitwise complement using the
   5278    negcc or notcc optabs if available.  Return NULL_RTX if such operations
   5279    are not available.  Otherwise return the RTX holding the result.
   5280    TARGET is the desired destination of the result.  COMP is the comparison
   5281    on which to negate.  If COND is true move into TARGET the negation
   5282    or bitwise complement of OP1.  Otherwise move OP2 into TARGET.
   5283    CODE is either NEG or NOT.  MODE is the machine mode in which the
   5284    operation is performed.  */
   5285 
   5286 rtx
   5287 emit_conditional_neg_or_complement (rtx target, rtx_code code,
   5288 				     machine_mode mode, rtx cond, rtx op1,
   5289 				     rtx op2)
   5290 {
   5291   optab op = unknown_optab;
   5292   if (code == NEG)
   5293     op = negcc_optab;
   5294   else if (code == NOT)
   5295     op = notcc_optab;
   5296   else
   5297     gcc_unreachable ();
   5298 
   5299   insn_code icode = direct_optab_handler (op, mode);
   5300 
   5301   if (icode == CODE_FOR_nothing)
   5302     return NULL_RTX;
   5303 
   5304   if (!target)
   5305     target = gen_reg_rtx (mode);
   5306 
   5307   rtx_insn *last = get_last_insn ();
   5308   class expand_operand ops[4];
   5309 
   5310   create_output_operand (&ops[0], target, mode);
   5311   create_fixed_operand (&ops[1], cond);
   5312   create_input_operand (&ops[2], op1, mode);
   5313   create_input_operand (&ops[3], op2, mode);
   5314 
   5315   if (maybe_expand_insn (icode, 4, ops))
   5316     {
   5317       if (ops[0].value != target)
   5318 	convert_move (target, ops[0].value, false);
   5319 
   5320       return target;
   5321     }
   5322   delete_insns_since (last);
   5323   return NULL_RTX;
   5324 }
   5325 
   5326 /* Emit a conditional addition instruction if the machine supports one for that
   5327    condition and machine mode.
   5328 
   5329    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
   5330    the mode to use should they be constants.  If it is VOIDmode, they cannot
   5331    both be constants.
   5332 
   5333    OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
   5334    should be stored there.  MODE is the mode to use should they be constants.
   5335    If it is VOIDmode, they cannot both be constants.
   5336 
   5337    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
   5338    is not supported.  */
   5339 
   5340 rtx
   5341 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
   5342 		      machine_mode cmode, rtx op2, rtx op3,
   5343 		      machine_mode mode, int unsignedp)
   5344 {
   5345   rtx comparison;
   5346   rtx_insn *last;
   5347   enum insn_code icode;
   5348 
   5349   /* If one operand is constant, make it the second one.  Only do this
   5350      if the other operand is not constant as well.  */
   5351 
   5352   if (swap_commutative_operands_p (op0, op1))
   5353     {
   5354       std::swap (op0, op1);
   5355       code = swap_condition (code);
   5356     }
   5357 
   5358   /* get_condition will prefer to generate LT and GT even if the old
   5359      comparison was against zero, so undo that canonicalization here since
   5360      comparisons against zero are cheaper.  */
   5361   if (code == LT && op1 == const1_rtx)
   5362     code = LE, op1 = const0_rtx;
   5363   else if (code == GT && op1 == constm1_rtx)
   5364     code = GE, op1 = const0_rtx;
   5365 
   5366   if (cmode == VOIDmode)
   5367     cmode = GET_MODE (op0);
   5368 
   5369   if (mode == VOIDmode)
   5370     mode = GET_MODE (op2);
   5371 
   5372   icode = optab_handler (addcc_optab, mode);
   5373 
   5374   if (icode == CODE_FOR_nothing)
   5375     return 0;
   5376 
   5377   if (!target)
   5378     target = gen_reg_rtx (mode);
   5379 
   5380   code = unsignedp ? unsigned_condition (code) : code;
   5381   comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
   5382 
   5383   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
   5384      return NULL and let the caller figure out how best to deal with this
   5385      situation.  */
   5386   if (!COMPARISON_P (comparison))
   5387     return NULL_RTX;
   5388 
   5389   do_pending_stack_adjust ();
   5390   last = get_last_insn ();
   5391   prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
   5392                     GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
   5393                     &comparison, &cmode);
   5394   if (comparison)
   5395     {
   5396       class expand_operand ops[4];
   5397 
   5398       create_output_operand (&ops[0], target, mode);
   5399       create_fixed_operand (&ops[1], comparison);
   5400       create_input_operand (&ops[2], op2, mode);
   5401       create_input_operand (&ops[3], op3, mode);
   5402       if (maybe_expand_insn (icode, 4, ops))
   5403 	{
   5404 	  if (ops[0].value != target)
   5405 	    convert_move (target, ops[0].value, false);
   5406 	  return target;
   5407 	}
   5408     }
   5409   delete_insns_since (last);
   5410   return NULL_RTX;
   5411 }
   5412 
   5413 /* These functions attempt to generate an insn body, rather than
   5415    emitting the insn, but if the gen function already emits them, we
   5416    make no attempt to turn them back into naked patterns.  */
   5417 
   5418 /* Generate and return an insn body to add Y to X.  */
   5419 
   5420 rtx_insn *
   5421 gen_add2_insn (rtx x, rtx y)
   5422 {
   5423   enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
   5424 
   5425   gcc_assert (insn_operand_matches (icode, 0, x));
   5426   gcc_assert (insn_operand_matches (icode, 1, x));
   5427   gcc_assert (insn_operand_matches (icode, 2, y));
   5428 
   5429   return GEN_FCN (icode) (x, x, y);
   5430 }
   5431 
   5432 /* Generate and return an insn body to add r1 and c,
   5433    storing the result in r0.  */
   5434 
   5435 rtx_insn *
   5436 gen_add3_insn (rtx r0, rtx r1, rtx c)
   5437 {
   5438   enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
   5439 
   5440   if (icode == CODE_FOR_nothing
   5441       || !insn_operand_matches (icode, 0, r0)
   5442       || !insn_operand_matches (icode, 1, r1)
   5443       || !insn_operand_matches (icode, 2, c))
   5444     return NULL;
   5445 
   5446   return GEN_FCN (icode) (r0, r1, c);
   5447 }
   5448 
   5449 bool
   5450 have_add2_insn (rtx x, rtx y)
   5451 {
   5452   enum insn_code icode;
   5453 
   5454   gcc_assert (GET_MODE (x) != VOIDmode);
   5455 
   5456   icode = optab_handler (add_optab, GET_MODE (x));
   5457 
   5458   if (icode == CODE_FOR_nothing)
   5459     return false;
   5460 
   5461   if (!insn_operand_matches (icode, 0, x)
   5462       || !insn_operand_matches (icode, 1, x)
   5463       || !insn_operand_matches (icode, 2, y))
   5464     return false;
   5465 
   5466   return true;
   5467 }
   5468 
   5469 /* Generate and return an insn body to add Y to X.  */
   5470 
   5471 rtx_insn *
   5472 gen_addptr3_insn (rtx x, rtx y, rtx z)
   5473 {
   5474   enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
   5475 
   5476   gcc_assert (insn_operand_matches (icode, 0, x));
   5477   gcc_assert (insn_operand_matches (icode, 1, y));
   5478   gcc_assert (insn_operand_matches (icode, 2, z));
   5479 
   5480   return GEN_FCN (icode) (x, y, z);
   5481 }
   5482 
   5483 /* Return true if the target implements an addptr pattern and X, Y,
   5484    and Z are valid for the pattern predicates.  */
   5485 
   5486 bool
   5487 have_addptr3_insn (rtx x, rtx y, rtx z)
   5488 {
   5489   enum insn_code icode;
   5490 
   5491   gcc_assert (GET_MODE (x) != VOIDmode);
   5492 
   5493   icode = optab_handler (addptr3_optab, GET_MODE (x));
   5494 
   5495   if (icode == CODE_FOR_nothing)
   5496     return false;
   5497 
   5498   if (!insn_operand_matches (icode, 0, x)
   5499       || !insn_operand_matches (icode, 1, y)
   5500       || !insn_operand_matches (icode, 2, z))
   5501     return false;
   5502 
   5503   return true;
   5504 }
   5505 
   5506 /* Generate and return an insn body to subtract Y from X.  */
   5507 
   5508 rtx_insn *
   5509 gen_sub2_insn (rtx x, rtx y)
   5510 {
   5511   enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
   5512 
   5513   gcc_assert (insn_operand_matches (icode, 0, x));
   5514   gcc_assert (insn_operand_matches (icode, 1, x));
   5515   gcc_assert (insn_operand_matches (icode, 2, y));
   5516 
   5517   return GEN_FCN (icode) (x, x, y);
   5518 }
   5519 
   5520 /* Generate and return an insn body to subtract r1 and c,
   5521    storing the result in r0.  */
   5522 
   5523 rtx_insn *
   5524 gen_sub3_insn (rtx r0, rtx r1, rtx c)
   5525 {
   5526   enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
   5527 
   5528   if (icode == CODE_FOR_nothing
   5529       || !insn_operand_matches (icode, 0, r0)
   5530       || !insn_operand_matches (icode, 1, r1)
   5531       || !insn_operand_matches (icode, 2, c))
   5532     return NULL;
   5533 
   5534   return GEN_FCN (icode) (r0, r1, c);
   5535 }
   5536 
   5537 bool
   5538 have_sub2_insn (rtx x, rtx y)
   5539 {
   5540   enum insn_code icode;
   5541 
   5542   gcc_assert (GET_MODE (x) != VOIDmode);
   5543 
   5544   icode = optab_handler (sub_optab, GET_MODE (x));
   5545 
   5546   if (icode == CODE_FOR_nothing)
   5547     return false;
   5548 
   5549   if (!insn_operand_matches (icode, 0, x)
   5550       || !insn_operand_matches (icode, 1, x)
   5551       || !insn_operand_matches (icode, 2, y))
   5552     return false;
   5553 
   5554   return true;
   5555 }
   5556 
   5557 /* Generate the body of an insn to extend Y (with mode MFROM)
   5559    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
   5560 
   5561 rtx_insn *
   5562 gen_extend_insn (rtx x, rtx y, machine_mode mto,
   5563 		 machine_mode mfrom, int unsignedp)
   5564 {
   5565   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
   5566   return GEN_FCN (icode) (x, y);
   5567 }
   5568 
   5569 /* Generate code to convert FROM to floating point
   5571    and store in TO.  FROM must be fixed point and not VOIDmode.
   5572    UNSIGNEDP nonzero means regard FROM as unsigned.
   5573    Normally this is done by correcting the final value
   5574    if it is negative.  */
   5575 
   5576 void
   5577 expand_float (rtx to, rtx from, int unsignedp)
   5578 {
   5579   enum insn_code icode;
   5580   rtx target = to;
   5581   scalar_mode from_mode, to_mode;
   5582   machine_mode fmode, imode;
   5583   bool can_do_signed = false;
   5584 
   5585   /* Crash now, because we won't be able to decide which mode to use.  */
   5586   gcc_assert (GET_MODE (from) != VOIDmode);
   5587 
   5588   /* Look for an insn to do the conversion.  Do it in the specified
   5589      modes if possible; otherwise convert either input, output or both to
   5590      wider mode.  If the integer mode is wider than the mode of FROM,
   5591      we can do the conversion signed even if the input is unsigned.  */
   5592 
   5593   FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
   5594     FOR_EACH_MODE_FROM (imode, GET_MODE (from))
   5595       {
   5596 	int doing_unsigned = unsignedp;
   5597 
   5598 	if (fmode != GET_MODE (to)
   5599 	    && (significand_size (fmode)
   5600 		< GET_MODE_UNIT_PRECISION (GET_MODE (from))))
   5601 	  continue;
   5602 
   5603 	icode = can_float_p (fmode, imode, unsignedp);
   5604 	if (icode == CODE_FOR_nothing && unsignedp)
   5605 	  {
   5606 	    enum insn_code scode = can_float_p (fmode, imode, 0);
   5607 	    if (scode != CODE_FOR_nothing)
   5608 	      can_do_signed = true;
   5609 	    if (imode != GET_MODE (from))
   5610 	      icode = scode, doing_unsigned = 0;
   5611 	  }
   5612 
   5613 	if (icode != CODE_FOR_nothing)
   5614 	  {
   5615 	    if (imode != GET_MODE (from))
   5616 	      from = convert_to_mode (imode, from, unsignedp);
   5617 
   5618 	    if (fmode != GET_MODE (to))
   5619 	      target = gen_reg_rtx (fmode);
   5620 
   5621 	    emit_unop_insn (icode, target, from,
   5622 			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
   5623 
   5624 	    if (target != to)
   5625 	      convert_move (to, target, 0);
   5626 	    return;
   5627 	  }
   5628       }
   5629 
   5630   /* Unsigned integer, and no way to convert directly.  Convert as signed,
   5631      then unconditionally adjust the result.  */
   5632   if (unsignedp
   5633       && can_do_signed
   5634       && is_a <scalar_mode> (GET_MODE (to), &to_mode)
   5635       && is_a <scalar_mode> (GET_MODE (from), &from_mode))
   5636     {
   5637       opt_scalar_mode fmode_iter;
   5638       rtx_code_label *label = gen_label_rtx ();
   5639       rtx temp;
   5640       REAL_VALUE_TYPE offset;
   5641 
   5642       /* Look for a usable floating mode FMODE wider than the source and at
   5643 	 least as wide as the target.  Using FMODE will avoid rounding woes
   5644 	 with unsigned values greater than the signed maximum value.  */
   5645 
   5646       FOR_EACH_MODE_FROM (fmode_iter, to_mode)
   5647 	{
   5648 	  scalar_mode fmode = fmode_iter.require ();
   5649 	  if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
   5650 	      && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
   5651 	    break;
   5652 	}
   5653 
   5654       if (!fmode_iter.exists (&fmode))
   5655 	{
   5656 	  /* There is no such mode.  Pretend the target is wide enough.  */
   5657 	  fmode = to_mode;
   5658 
   5659 	  /* Avoid double-rounding when TO is narrower than FROM.  */
   5660 	  if ((significand_size (fmode) + 1)
   5661 	      < GET_MODE_PRECISION (from_mode))
   5662 	    {
   5663 	      rtx temp1;
   5664 	      rtx_code_label *neglabel = gen_label_rtx ();
   5665 
   5666 	      /* Don't use TARGET if it isn't a register, is a hard register,
   5667 		 or is the wrong mode.  */
   5668 	      if (!REG_P (target)
   5669 		  || REGNO (target) < FIRST_PSEUDO_REGISTER
   5670 		  || GET_MODE (target) != fmode)
   5671 		target = gen_reg_rtx (fmode);
   5672 
   5673 	      imode = from_mode;
   5674 	      do_pending_stack_adjust ();
   5675 
   5676 	      /* Test whether the sign bit is set.  */
   5677 	      emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
   5678 				       0, neglabel);
   5679 
   5680 	      /* The sign bit is not set.  Convert as signed.  */
   5681 	      expand_float (target, from, 0);
   5682 	      emit_jump_insn (targetm.gen_jump (label));
   5683 	      emit_barrier ();
   5684 
   5685 	      /* The sign bit is set.
   5686 		 Convert to a usable (positive signed) value by shifting right
   5687 		 one bit, while remembering if a nonzero bit was shifted
   5688 		 out; i.e., compute  (from & 1) | (from >> 1).  */
   5689 
   5690 	      emit_label (neglabel);
   5691 	      temp = expand_binop (imode, and_optab, from, const1_rtx,
   5692 				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
   5693 	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
   5694 	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
   5695 				   OPTAB_LIB_WIDEN);
   5696 	      expand_float (target, temp, 0);
   5697 
   5698 	      /* Multiply by 2 to undo the shift above.  */
   5699 	      temp = expand_binop (fmode, add_optab, target, target,
   5700 				   target, 0, OPTAB_LIB_WIDEN);
   5701 	      if (temp != target)
   5702 		emit_move_insn (target, temp);
   5703 
   5704 	      do_pending_stack_adjust ();
   5705 	      emit_label (label);
   5706 	      goto done;
   5707 	    }
   5708 	}
   5709 
   5710       /* If we are about to do some arithmetic to correct for an
   5711 	 unsigned operand, do it in a pseudo-register.  */
   5712 
   5713       if (to_mode != fmode
   5714 	  || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
   5715 	target = gen_reg_rtx (fmode);
   5716 
   5717       /* Convert as signed integer to floating.  */
   5718       expand_float (target, from, 0);
   5719 
   5720       /* If FROM is negative (and therefore TO is negative),
   5721 	 correct its value by 2**bitwidth.  */
   5722 
   5723       do_pending_stack_adjust ();
   5724       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
   5725 			       0, label);
   5726 
   5727 
   5728       real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
   5729       temp = expand_binop (fmode, add_optab, target,
   5730 			   const_double_from_real_value (offset, fmode),
   5731 			   target, 0, OPTAB_LIB_WIDEN);
   5732       if (temp != target)
   5733 	emit_move_insn (target, temp);
   5734 
   5735       do_pending_stack_adjust ();
   5736       emit_label (label);
   5737       goto done;
   5738     }
   5739 
   5740   /* No hardware instruction available; call a library routine.  */
   5741     {
   5742       rtx libfunc;
   5743       rtx_insn *insns;
   5744       rtx value;
   5745       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
   5746 
   5747       if (is_narrower_int_mode (GET_MODE (from), SImode))
   5748 	from = convert_to_mode (SImode, from, unsignedp);
   5749 
   5750       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
   5751       gcc_assert (libfunc);
   5752 
   5753       start_sequence ();
   5754 
   5755       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
   5756 				       GET_MODE (to), from, GET_MODE (from));
   5757       insns = get_insns ();
   5758       end_sequence ();
   5759 
   5760       emit_libcall_block (insns, target, value,
   5761 			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
   5762 					 GET_MODE (to), from));
   5763     }
   5764 
   5765  done:
   5766 
   5767   /* Copy result to requested destination
   5768      if we have been computing in a temp location.  */
   5769 
   5770   if (target != to)
   5771     {
   5772       if (GET_MODE (target) == GET_MODE (to))
   5773 	emit_move_insn (to, target);
   5774       else
   5775 	convert_move (to, target, 0);
   5776     }
   5777 }
   5778 
   5779 /* Generate code to convert FROM to fixed point and store in TO.  FROM
   5781    must be floating point.  */
   5782 
   5783 void
   5784 expand_fix (rtx to, rtx from, int unsignedp)
   5785 {
   5786   enum insn_code icode;
   5787   rtx target = to;
   5788   machine_mode fmode, imode;
   5789   opt_scalar_mode fmode_iter;
   5790   bool must_trunc = false;
   5791 
   5792   /* We first try to find a pair of modes, one real and one integer, at
   5793      least as wide as FROM and TO, respectively, in which we can open-code
   5794      this conversion.  If the integer mode is wider than the mode of TO,
   5795      we can do the conversion either signed or unsigned.  */
   5796 
   5797   FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
   5798     FOR_EACH_MODE_FROM (imode, GET_MODE (to))
   5799       {
   5800 	int doing_unsigned = unsignedp;
   5801 
   5802 	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
   5803 	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
   5804 	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
   5805 
   5806 	if (icode != CODE_FOR_nothing)
   5807 	  {
   5808 	    rtx_insn *last = get_last_insn ();
   5809 	    rtx from1 = from;
   5810 	    if (fmode != GET_MODE (from))
   5811 	      {
   5812 		if (REAL_MODE_FORMAT (GET_MODE (from))
   5813 		    == &arm_bfloat_half_format
   5814 		    && REAL_MODE_FORMAT (fmode) == &ieee_single_format)
   5815 		  /* The BF -> SF conversions can be just a shift, doesn't
   5816 		     need to handle sNANs.  */
   5817 		  {
   5818 		    int save_flag_finite_math_only = flag_finite_math_only;
   5819 		    flag_finite_math_only = true;
   5820 		    from1 = convert_to_mode (fmode, from, 0);
   5821 		    flag_finite_math_only = save_flag_finite_math_only;
   5822 		  }
   5823 		else
   5824 		  from1 = convert_to_mode (fmode, from, 0);
   5825 	      }
   5826 
   5827 	    if (must_trunc)
   5828 	      {
   5829 		rtx temp = gen_reg_rtx (GET_MODE (from1));
   5830 		from1 = expand_unop (GET_MODE (from1), ftrunc_optab, from1,
   5831 				     temp, 0);
   5832 	      }
   5833 
   5834 	    if (imode != GET_MODE (to))
   5835 	      target = gen_reg_rtx (imode);
   5836 
   5837 	    if (maybe_emit_unop_insn (icode, target, from1,
   5838 				      doing_unsigned ? UNSIGNED_FIX : FIX))
   5839 	      {
   5840 		if (target != to)
   5841 		  convert_move (to, target, unsignedp);
   5842 		return;
   5843 	      }
   5844 	    delete_insns_since (last);
   5845 	  }
   5846       }
   5847 
   5848   /* For an unsigned conversion, there is one more way to do it.
   5849      If we have a signed conversion, we generate code that compares
   5850      the real value to the largest representable positive number.  If if
   5851      is smaller, the conversion is done normally.  Otherwise, subtract
   5852      one plus the highest signed number, convert, and add it back.
   5853 
   5854      We only need to check all real modes, since we know we didn't find
   5855      anything with a wider integer mode.
   5856 
   5857      This code used to extend FP value into mode wider than the destination.
   5858      This is needed for decimal float modes which cannot accurately
   5859      represent one plus the highest signed number of the same size, but
   5860      not for binary modes.  Consider, for instance conversion from SFmode
   5861      into DImode.
   5862 
   5863      The hot path through the code is dealing with inputs smaller than 2^63
   5864      and doing just the conversion, so there is no bits to lose.
   5865 
   5866      In the other path we know the value is positive in the range 2^63..2^64-1
   5867      inclusive.  (as for other input overflow happens and result is undefined)
   5868      So we know that the most important bit set in mantissa corresponds to
   5869      2^63.  The subtraction of 2^63 should not generate any rounding as it
   5870      simply clears out that bit.  The rest is trivial.  */
   5871 
   5872   scalar_int_mode to_mode;
   5873   if (unsignedp
   5874       && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
   5875       && HWI_COMPUTABLE_MODE_P (to_mode))
   5876     FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
   5877       {
   5878 	scalar_mode fmode = fmode_iter.require ();
   5879 	if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
   5880 					   0, &must_trunc)
   5881 	    && (!DECIMAL_FLOAT_MODE_P (fmode)
   5882 		|| (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
   5883 	  {
   5884 	    int bitsize;
   5885 	    REAL_VALUE_TYPE offset;
   5886 	    rtx limit;
   5887 	    rtx_code_label *lab1, *lab2;
   5888 	    rtx_insn *insn;
   5889 
   5890 	    bitsize = GET_MODE_PRECISION (to_mode);
   5891 	    real_2expN (&offset, bitsize - 1, fmode);
   5892 	    limit = const_double_from_real_value (offset, fmode);
   5893 	    lab1 = gen_label_rtx ();
   5894 	    lab2 = gen_label_rtx ();
   5895 
   5896 	    if (fmode != GET_MODE (from))
   5897 	      {
   5898 		if (REAL_MODE_FORMAT (GET_MODE (from))
   5899 		    == &arm_bfloat_half_format
   5900 		    && REAL_MODE_FORMAT (fmode) == &ieee_single_format)
   5901 		  /* The BF -> SF conversions can be just a shift, doesn't
   5902 		     need to handle sNANs.  */
   5903 		  {
   5904 		    int save_flag_finite_math_only = flag_finite_math_only;
   5905 		    flag_finite_math_only = true;
   5906 		    from = convert_to_mode (fmode, from, 0);
   5907 		    flag_finite_math_only = save_flag_finite_math_only;
   5908 		  }
   5909 		else
   5910 		  from = convert_to_mode (fmode, from, 0);
   5911 	      }
   5912 
   5913 	    /* See if we need to do the subtraction.  */
   5914 	    do_pending_stack_adjust ();
   5915 	    emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
   5916 				     GET_MODE (from), 0, lab1);
   5917 
   5918 	    /* If not, do the signed "fix" and branch around fixup code.  */
   5919 	    expand_fix (to, from, 0);
   5920 	    emit_jump_insn (targetm.gen_jump (lab2));
   5921 	    emit_barrier ();
   5922 
   5923 	    /* Otherwise, subtract 2**(N-1), convert to signed number,
   5924 	       then add 2**(N-1).  Do the addition using XOR since this
   5925 	       will often generate better code.  */
   5926 	    emit_label (lab1);
   5927 	    target = expand_binop (GET_MODE (from), sub_optab, from, limit,
   5928 				   NULL_RTX, 0, OPTAB_LIB_WIDEN);
   5929 	    expand_fix (to, target, 0);
   5930 	    target = expand_binop (to_mode, xor_optab, to,
   5931 				   gen_int_mode
   5932 				   (HOST_WIDE_INT_1 << (bitsize - 1),
   5933 				    to_mode),
   5934 				   to, 1, OPTAB_LIB_WIDEN);
   5935 
   5936 	    if (target != to)
   5937 	      emit_move_insn (to, target);
   5938 
   5939 	    emit_label (lab2);
   5940 
   5941 	    if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
   5942 	      {
   5943 		/* Make a place for a REG_NOTE and add it.  */
   5944 		insn = emit_move_insn (to, to);
   5945 		set_dst_reg_note (insn, REG_EQUAL,
   5946 				  gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
   5947 						 copy_rtx (from)),
   5948 				  to);
   5949 	      }
   5950 
   5951 	    return;
   5952 	  }
   5953       }
   5954 
   5955 #ifdef HAVE_SFmode
   5956   if (REAL_MODE_FORMAT (GET_MODE (from)) == &arm_bfloat_half_format
   5957       && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
   5958     /* We don't have BF -> TI library functions, use BF -> SF -> TI
   5959        instead but the BF -> SF conversion can be just a shift, doesn't
   5960        need to handle sNANs.  */
   5961     {
   5962       int save_flag_finite_math_only = flag_finite_math_only;
   5963       flag_finite_math_only = true;
   5964       from = convert_to_mode (SFmode, from, 0);
   5965       flag_finite_math_only = save_flag_finite_math_only;
   5966       expand_fix (to, from, unsignedp);
   5967       return;
   5968     }
   5969 #endif
   5970 
   5971   /* We can't do it with an insn, so use a library call.  But first ensure
   5972      that the mode of TO is at least as wide as SImode, since those are the
   5973      only library calls we know about.  */
   5974 
   5975   if (is_narrower_int_mode (GET_MODE (to), SImode))
   5976     {
   5977       target = gen_reg_rtx (SImode);
   5978 
   5979       expand_fix (target, from, unsignedp);
   5980     }
   5981   else
   5982     {
   5983       rtx_insn *insns;
   5984       rtx value;
   5985       rtx libfunc;
   5986 
   5987       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
   5988       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
   5989       gcc_assert (libfunc);
   5990 
   5991       start_sequence ();
   5992 
   5993       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
   5994 				       GET_MODE (to), from, GET_MODE (from));
   5995       insns = get_insns ();
   5996       end_sequence ();
   5997 
   5998       emit_libcall_block (insns, target, value,
   5999 			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
   6000 					 GET_MODE (to), from));
   6001     }
   6002 
   6003   if (target != to)
   6004     {
   6005       if (GET_MODE (to) == GET_MODE (target))
   6006         emit_move_insn (to, target);
   6007       else
   6008         convert_move (to, target, 0);
   6009     }
   6010 }
   6011 
   6012 
   6013 /* Promote integer arguments for a libcall if necessary.
   6014    emit_library_call_value cannot do the promotion because it does not
   6015    know if it should do a signed or unsigned promotion.  This is because
   6016    there are no tree types defined for libcalls.  */
   6017 
   6018 static rtx
   6019 prepare_libcall_arg (rtx arg, int uintp)
   6020 {
   6021   scalar_int_mode mode;
   6022   machine_mode arg_mode;
   6023   if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
   6024     {
   6025       /*  If we need to promote the integer function argument we need to do
   6026 	  it here instead of inside emit_library_call_value because in
   6027 	  emit_library_call_value we don't know if we should do a signed or
   6028 	  unsigned promotion.  */
   6029 
   6030       int unsigned_p = 0;
   6031       arg_mode = promote_function_mode (NULL_TREE, mode,
   6032 					&unsigned_p, NULL_TREE, 0);
   6033       if (arg_mode != mode)
   6034 	return convert_to_mode (arg_mode, arg, uintp);
   6035     }
   6036     return arg;
   6037 }
   6038 
   6039 /* Generate code to convert FROM or TO a fixed-point.
   6040    If UINTP is true, either TO or FROM is an unsigned integer.
   6041    If SATP is true, we need to saturate the result.  */
   6042 
   6043 void
   6044 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
   6045 {
   6046   machine_mode to_mode = GET_MODE (to);
   6047   machine_mode from_mode = GET_MODE (from);
   6048   convert_optab tab;
   6049   enum rtx_code this_code;
   6050   enum insn_code code;
   6051   rtx_insn *insns;
   6052   rtx value;
   6053   rtx libfunc;
   6054 
   6055   if (to_mode == from_mode)
   6056     {
   6057       emit_move_insn (to, from);
   6058       return;
   6059     }
   6060 
   6061   if (uintp)
   6062     {
   6063       tab = satp ? satfractuns_optab : fractuns_optab;
   6064       this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
   6065     }
   6066   else
   6067     {
   6068       tab = satp ? satfract_optab : fract_optab;
   6069       this_code = satp ? SAT_FRACT : FRACT_CONVERT;
   6070     }
   6071   code = convert_optab_handler (tab, to_mode, from_mode);
   6072   if (code != CODE_FOR_nothing)
   6073     {
   6074       emit_unop_insn (code, to, from, this_code);
   6075       return;
   6076     }
   6077 
   6078   libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
   6079   gcc_assert (libfunc);
   6080 
   6081   from = prepare_libcall_arg (from, uintp);
   6082   from_mode = GET_MODE (from);
   6083 
   6084   start_sequence ();
   6085   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
   6086 				   from, from_mode);
   6087   insns = get_insns ();
   6088   end_sequence ();
   6089 
   6090   emit_libcall_block (insns, to, value,
   6091 		      gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
   6092 }
   6093 
   6094 /* Generate code to convert FROM to fixed point and store in TO.  FROM
   6095    must be floating point, TO must be signed.  Use the conversion optab
   6096    TAB to do the conversion.  */
   6097 
   6098 bool
   6099 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
   6100 {
   6101   enum insn_code icode;
   6102   rtx target = to;
   6103   machine_mode fmode, imode;
   6104 
   6105   /* We first try to find a pair of modes, one real and one integer, at
   6106      least as wide as FROM and TO, respectively, in which we can open-code
   6107      this conversion.  If the integer mode is wider than the mode of TO,
   6108      we can do the conversion either signed or unsigned.  */
   6109 
   6110   FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
   6111     FOR_EACH_MODE_FROM (imode, GET_MODE (to))
   6112       {
   6113 	icode = convert_optab_handler (tab, imode, fmode,
   6114 				       insn_optimization_type ());
   6115 	if (icode != CODE_FOR_nothing)
   6116 	  {
   6117 	    rtx_insn *last = get_last_insn ();
   6118 	    if (fmode != GET_MODE (from))
   6119 	      from = convert_to_mode (fmode, from, 0);
   6120 
   6121 	    if (imode != GET_MODE (to))
   6122 	      target = gen_reg_rtx (imode);
   6123 
   6124 	    if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
   6125 	      {
   6126 	        delete_insns_since (last);
   6127 		continue;
   6128 	      }
   6129 	    if (target != to)
   6130 	      convert_move (to, target, 0);
   6131 	    return true;
   6132 	  }
   6133       }
   6134 
   6135   return false;
   6136 }
   6137 
   6138 /* Report whether we have an instruction to perform the operation
   6140    specified by CODE on operands of mode MODE.  */
   6141 bool
   6142 have_insn_for (enum rtx_code code, machine_mode mode)
   6143 {
   6144   return (code_to_optab (code)
   6145 	  && (optab_handler (code_to_optab (code), mode)
   6146 	      != CODE_FOR_nothing));
   6147 }
   6148 
   6149 /* Print information about the current contents of the optabs on
   6150    STDERR.  */
   6151 
   6152 DEBUG_FUNCTION void
   6153 debug_optab_libfuncs (void)
   6154 {
   6155   int i, j, k;
   6156 
   6157   /* Dump the arithmetic optabs.  */
   6158   for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
   6159     for (j = 0; j < NUM_MACHINE_MODES; ++j)
   6160       {
   6161 	rtx l = optab_libfunc ((optab) i, (machine_mode) j);
   6162 	if (l)
   6163 	  {
   6164 	    gcc_assert (GET_CODE (l) == SYMBOL_REF);
   6165 	    fprintf (stderr, "%s\t%s:\t%s\n",
   6166 		     GET_RTX_NAME (optab_to_code ((optab) i)),
   6167 		     GET_MODE_NAME (j),
   6168 		     XSTR (l, 0));
   6169 	  }
   6170       }
   6171 
   6172   /* Dump the conversion optabs.  */
   6173   for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
   6174     for (j = 0; j < NUM_MACHINE_MODES; ++j)
   6175       for (k = 0; k < NUM_MACHINE_MODES; ++k)
   6176 	{
   6177 	  rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
   6178 					 (machine_mode) k);
   6179 	  if (l)
   6180 	    {
   6181 	      gcc_assert (GET_CODE (l) == SYMBOL_REF);
   6182 	      fprintf (stderr, "%s\t%s\t%s:\t%s\n",
   6183 		       GET_RTX_NAME (optab_to_code ((optab) i)),
   6184 		       GET_MODE_NAME (j),
   6185 		       GET_MODE_NAME (k),
   6186 		       XSTR (l, 0));
   6187 	    }
   6188 	}
   6189 }
   6190 
   6191 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
   6192    CODE.  Return 0 on failure.  */
   6193 
   6194 rtx_insn *
   6195 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
   6196 {
   6197   machine_mode mode = GET_MODE (op1);
   6198   enum insn_code icode;
   6199   rtx_insn *insn;
   6200   rtx trap_rtx;
   6201 
   6202   if (mode == VOIDmode)
   6203     return 0;
   6204 
   6205   icode = optab_handler (ctrap_optab, mode);
   6206   if (icode == CODE_FOR_nothing)
   6207     return 0;
   6208 
   6209   /* Some targets only accept a zero trap code.  */
   6210   if (!insn_operand_matches (icode, 3, tcode))
   6211     return 0;
   6212 
   6213   do_pending_stack_adjust ();
   6214   start_sequence ();
   6215   prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
   6216 		    &trap_rtx, &mode);
   6217   if (!trap_rtx)
   6218     insn = NULL;
   6219   else
   6220     insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
   6221 			    tcode);
   6222 
   6223   /* If that failed, then give up.  */
   6224   if (insn == 0)
   6225     {
   6226       end_sequence ();
   6227       return 0;
   6228     }
   6229 
   6230   emit_insn (insn);
   6231   insn = get_insns ();
   6232   end_sequence ();
   6233   return insn;
   6234 }
   6235 
   6236 /* Return rtx code for TCODE or UNKNOWN.  Use UNSIGNEDP to select signed
   6237    or unsigned operation code.  */
   6238 
   6239 enum rtx_code
   6240 get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
   6241 {
   6242   enum rtx_code code;
   6243   switch (tcode)
   6244     {
   6245     case EQ_EXPR:
   6246       code = EQ;
   6247       break;
   6248     case NE_EXPR:
   6249       code = NE;
   6250       break;
   6251     case LT_EXPR:
   6252       code = unsignedp ? LTU : LT;
   6253       break;
   6254     case LE_EXPR:
   6255       code = unsignedp ? LEU : LE;
   6256       break;
   6257     case GT_EXPR:
   6258       code = unsignedp ? GTU : GT;
   6259       break;
   6260     case GE_EXPR:
   6261       code = unsignedp ? GEU : GE;
   6262       break;
   6263 
   6264     case UNORDERED_EXPR:
   6265       code = UNORDERED;
   6266       break;
   6267     case ORDERED_EXPR:
   6268       code = ORDERED;
   6269       break;
   6270     case UNLT_EXPR:
   6271       code = UNLT;
   6272       break;
   6273     case UNLE_EXPR:
   6274       code = UNLE;
   6275       break;
   6276     case UNGT_EXPR:
   6277       code = UNGT;
   6278       break;
   6279     case UNGE_EXPR:
   6280       code = UNGE;
   6281       break;
   6282     case UNEQ_EXPR:
   6283       code = UNEQ;
   6284       break;
   6285     case LTGT_EXPR:
   6286       code = LTGT;
   6287       break;
   6288 
   6289     case BIT_AND_EXPR:
   6290       code = AND;
   6291       break;
   6292 
   6293     case BIT_IOR_EXPR:
   6294       code = IOR;
   6295       break;
   6296 
   6297     default:
   6298       code = UNKNOWN;
   6299       break;
   6300     }
   6301   return code;
   6302 }
   6303 
   6304 /* Return rtx code for TCODE.  Use UNSIGNEDP to select signed
   6305    or unsigned operation code.  */
   6306 
   6307 enum rtx_code
   6308 get_rtx_code (enum tree_code tcode, bool unsignedp)
   6309 {
   6310   enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
   6311   gcc_assert (code != UNKNOWN);
   6312   return code;
   6313 }
   6314 
   6315 /* Return a comparison rtx of mode CMP_MODE for COND.  Use UNSIGNEDP to
   6316    select signed or unsigned operators.  OPNO holds the index of the
   6317    first comparison operand for insn ICODE.  Do not generate the
   6318    compare instruction itself.  */
   6319 
   6320 rtx
   6321 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
   6322 		    tree t_op0, tree t_op1, bool unsignedp,
   6323 		    enum insn_code icode, unsigned int opno)
   6324 {
   6325   class expand_operand ops[2];
   6326   rtx rtx_op0, rtx_op1;
   6327   machine_mode m0, m1;
   6328   enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
   6329 
   6330   gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
   6331 
   6332   /* Expand operands.  For vector types with scalar modes, e.g. where int64x1_t
   6333      has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
   6334      cases, use the original mode.  */
   6335   rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
   6336 			 EXPAND_STACK_PARM);
   6337   m0 = GET_MODE (rtx_op0);
   6338   if (m0 == VOIDmode)
   6339     m0 = TYPE_MODE (TREE_TYPE (t_op0));
   6340 
   6341   rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
   6342 			 EXPAND_STACK_PARM);
   6343   m1 = GET_MODE (rtx_op1);
   6344   if (m1 == VOIDmode)
   6345     m1 = TYPE_MODE (TREE_TYPE (t_op1));
   6346 
   6347   create_input_operand (&ops[0], rtx_op0, m0);
   6348   create_input_operand (&ops[1], rtx_op1, m1);
   6349   if (!maybe_legitimize_operands (icode, opno, 2, ops))
   6350     gcc_unreachable ();
   6351   return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
   6352 }
   6353 
   6354 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
   6355    the first vec_perm operand, assuming the second operand (for left shift
   6356    first operand) is a constant vector of zeros.  Return the shift distance
   6357    in bits if so, or NULL_RTX if the vec_perm is not a shift.  MODE is the
   6358    mode of the value being shifted.  SHIFT_OPTAB is vec_shr_optab for right
   6359    shift or vec_shl_optab for left shift.  */
   6360 static rtx
   6361 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel,
   6362 			     optab shift_optab)
   6363 {
   6364   unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
   6365   poly_int64 first = sel[0];
   6366   if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
   6367     return NULL_RTX;
   6368 
   6369   if (shift_optab == vec_shl_optab)
   6370     {
   6371       unsigned int nelt;
   6372       if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
   6373 	return NULL_RTX;
   6374       unsigned firstidx = 0;
   6375       for (unsigned int i = 0; i < nelt; i++)
   6376 	{
   6377 	  if (known_eq (sel[i], nelt))
   6378 	    {
   6379 	      if (i == 0 || firstidx)
   6380 		return NULL_RTX;
   6381 	      firstidx = i;
   6382 	    }
   6383 	  else if (firstidx
   6384 		   ? maybe_ne (sel[i], nelt + i - firstidx)
   6385 		   : maybe_ge (sel[i], nelt))
   6386 	    return NULL_RTX;
   6387 	}
   6388 
   6389       if (firstidx == 0)
   6390 	return NULL_RTX;
   6391       first = firstidx;
   6392     }
   6393   else if (!sel.series_p (0, 1, first, 1))
   6394     {
   6395       unsigned int nelt;
   6396       if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
   6397 	return NULL_RTX;
   6398       for (unsigned int i = 1; i < nelt; i++)
   6399 	{
   6400 	  poly_int64 expected = i + first;
   6401 	  /* Indices into the second vector are all equivalent.  */
   6402 	  if (maybe_lt (sel[i], nelt)
   6403 	      ? maybe_ne (sel[i], expected)
   6404 	      : maybe_lt (expected, nelt))
   6405 	    return NULL_RTX;
   6406 	}
   6407     }
   6408 
   6409   return gen_int_shift_amount (mode, first * bitsize);
   6410 }
   6411 
   6412 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn.  */
   6413 
   6414 static rtx
   6415 expand_vec_perm_1 (enum insn_code icode, rtx target,
   6416 		   rtx v0, rtx v1, rtx sel)
   6417 {
   6418   machine_mode tmode = GET_MODE (target);
   6419   machine_mode smode = GET_MODE (sel);
   6420   class expand_operand ops[4];
   6421 
   6422   gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
   6423 	      || related_int_vector_mode (tmode).require () == smode);
   6424   create_output_operand (&ops[0], target, tmode);
   6425   create_input_operand (&ops[3], sel, smode);
   6426 
   6427   /* Make an effort to preserve v0 == v1.  The target expander is able to
   6428      rely on this to determine if we're permuting a single input operand.  */
   6429   if (rtx_equal_p (v0, v1))
   6430     {
   6431       if (!insn_operand_matches (icode, 1, v0))
   6432         v0 = force_reg (tmode, v0);
   6433       gcc_checking_assert (insn_operand_matches (icode, 1, v0));
   6434       gcc_checking_assert (insn_operand_matches (icode, 2, v0));
   6435 
   6436       create_fixed_operand (&ops[1], v0);
   6437       create_fixed_operand (&ops[2], v0);
   6438     }
   6439   else
   6440     {
   6441       create_input_operand (&ops[1], v0, tmode);
   6442       create_input_operand (&ops[2], v1, tmode);
   6443     }
   6444 
   6445   if (maybe_expand_insn (icode, 4, ops))
   6446     return ops[0].value;
   6447   return NULL_RTX;
   6448 }
   6449 
   6450 /* Implement a permutation of vectors v0 and v1 using the permutation
   6451    vector in SEL and return the result.  Use TARGET to hold the result
   6452    if nonnull and convenient.
   6453 
   6454    MODE is the mode of the vectors being permuted (V0 and V1).  SEL_MODE
   6455    is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
   6456    to have a particular mode.  */
   6457 
   6458 rtx
   6459 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
   6460 		       const vec_perm_builder &sel, machine_mode sel_mode,
   6461 		       rtx target)
   6462 {
   6463   if (!target || !register_operand (target, mode))
   6464     target = gen_reg_rtx (mode);
   6465 
   6466   /* Set QIMODE to a different vector mode with byte elements.
   6467      If no such mode, or if MODE already has byte elements, use VOIDmode.  */
   6468   machine_mode qimode;
   6469   if (!qimode_for_vec_perm (mode).exists (&qimode))
   6470     qimode = VOIDmode;
   6471 
   6472   rtx_insn *last = get_last_insn ();
   6473 
   6474   bool single_arg_p = rtx_equal_p (v0, v1);
   6475   /* Always specify two input vectors here and leave the target to handle
   6476      cases in which the inputs are equal.  Not all backends can cope with
   6477      the single-input representation when testing for a double-input
   6478      target instruction.  */
   6479   vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
   6480 
   6481   /* See if this can be handled with a vec_shr or vec_shl.  We only do this
   6482      if the second (for vec_shr) or first (for vec_shl) vector is all
   6483      zeroes.  */
   6484   insn_code shift_code = CODE_FOR_nothing;
   6485   insn_code shift_code_qi = CODE_FOR_nothing;
   6486   optab shift_optab = unknown_optab;
   6487   rtx v2 = v0;
   6488   if (v1 == CONST0_RTX (GET_MODE (v1)))
   6489     shift_optab = vec_shr_optab;
   6490   else if (v0 == CONST0_RTX (GET_MODE (v0)))
   6491     {
   6492       shift_optab = vec_shl_optab;
   6493       v2 = v1;
   6494     }
   6495   if (shift_optab != unknown_optab)
   6496     {
   6497       shift_code = optab_handler (shift_optab, mode);
   6498       shift_code_qi = ((qimode != VOIDmode && qimode != mode)
   6499 		       ? optab_handler (shift_optab, qimode)
   6500 		       : CODE_FOR_nothing);
   6501     }
   6502   if (shift_code != CODE_FOR_nothing || shift_code_qi != CODE_FOR_nothing)
   6503     {
   6504       rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices, shift_optab);
   6505       if (shift_amt)
   6506 	{
   6507 	  class expand_operand ops[3];
   6508 	  if (shift_amt == const0_rtx)
   6509 	    return v2;
   6510 	  if (shift_code != CODE_FOR_nothing)
   6511 	    {
   6512 	      create_output_operand (&ops[0], target, mode);
   6513 	      create_input_operand (&ops[1], v2, mode);
   6514 	      create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
   6515 	      if (maybe_expand_insn (shift_code, 3, ops))
   6516 		return ops[0].value;
   6517 	    }
   6518 	  if (shift_code_qi != CODE_FOR_nothing)
   6519 	    {
   6520 	      rtx tmp = gen_reg_rtx (qimode);
   6521 	      create_output_operand (&ops[0], tmp, qimode);
   6522 	      create_input_operand (&ops[1], gen_lowpart (qimode, v2), qimode);
   6523 	      create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
   6524 	      if (maybe_expand_insn (shift_code_qi, 3, ops))
   6525 		return gen_lowpart (mode, ops[0].value);
   6526 	    }
   6527 	}
   6528     }
   6529 
   6530   if (targetm.vectorize.vec_perm_const != NULL)
   6531     {
   6532       if (single_arg_p)
   6533 	v1 = v0;
   6534 
   6535       gcc_checking_assert (GET_MODE (v0) == GET_MODE (v1));
   6536       machine_mode op_mode = GET_MODE (v0);
   6537       if (targetm.vectorize.vec_perm_const (mode, op_mode, target, v0, v1,
   6538 					    indices))
   6539 	return target;
   6540     }
   6541 
   6542   /* Fall back to a constant byte-based permutation.  */
   6543   vec_perm_indices qimode_indices;
   6544   rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
   6545   if (qimode != VOIDmode)
   6546     {
   6547       qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
   6548       target_qi = gen_reg_rtx (qimode);
   6549       v0_qi = gen_lowpart (qimode, v0);
   6550       v1_qi = gen_lowpart (qimode, v1);
   6551       if (targetm.vectorize.vec_perm_const != NULL
   6552 	  && targetm.vectorize.vec_perm_const (qimode, qimode, target_qi, v0_qi,
   6553 					       v1_qi, qimode_indices))
   6554 	return gen_lowpart (mode, target_qi);
   6555     }
   6556 
   6557   v0 = force_reg (mode, v0);
   6558   if (single_arg_p)
   6559     v1 = v0;
   6560   v1 = force_reg (mode, v1);
   6561 
   6562   /* Otherwise expand as a fully variable permuation.  */
   6563 
   6564   /* The optabs are only defined for selectors with the same width
   6565      as the values being permuted.  */
   6566   machine_mode required_sel_mode;
   6567   if (!related_int_vector_mode (mode).exists (&required_sel_mode))
   6568     {
   6569       delete_insns_since (last);
   6570       return NULL_RTX;
   6571     }
   6572 
   6573   /* We know that it is semantically valid to treat SEL as having SEL_MODE.
   6574      If that isn't the mode we want then we need to prove that using
   6575      REQUIRED_SEL_MODE is OK.  */
   6576   if (sel_mode != required_sel_mode)
   6577     {
   6578       if (!selector_fits_mode_p (required_sel_mode, indices))
   6579 	{
   6580 	  delete_insns_since (last);
   6581 	  return NULL_RTX;
   6582 	}
   6583       sel_mode = required_sel_mode;
   6584     }
   6585 
   6586   insn_code icode = direct_optab_handler (vec_perm_optab, mode);
   6587   if (icode != CODE_FOR_nothing)
   6588     {
   6589       rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
   6590       rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
   6591       if (tmp)
   6592 	return tmp;
   6593     }
   6594 
   6595   if (qimode != VOIDmode
   6596       && selector_fits_mode_p (qimode, qimode_indices))
   6597     {
   6598       icode = direct_optab_handler (vec_perm_optab, qimode);
   6599       if (icode != CODE_FOR_nothing)
   6600 	{
   6601 	  rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
   6602 	  rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
   6603 	  if (tmp)
   6604 	    return gen_lowpart (mode, tmp);
   6605 	}
   6606     }
   6607 
   6608   delete_insns_since (last);
   6609   return NULL_RTX;
   6610 }
   6611 
   6612 /* Implement a permutation of vectors v0 and v1 using the permutation
   6613    vector in SEL and return the result.  Use TARGET to hold the result
   6614    if nonnull and convenient.
   6615 
   6616    MODE is the mode of the vectors being permuted (V0 and V1).
   6617    SEL must have the integer equivalent of MODE and is known to be
   6618    unsuitable for permutes with a constant permutation vector.  */
   6619 
   6620 rtx
   6621 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
   6622 {
   6623   enum insn_code icode;
   6624   unsigned int i, u;
   6625   rtx tmp, sel_qi;
   6626 
   6627   u = GET_MODE_UNIT_SIZE (mode);
   6628 
   6629   if (!target || GET_MODE (target) != mode)
   6630     target = gen_reg_rtx (mode);
   6631 
   6632   icode = direct_optab_handler (vec_perm_optab, mode);
   6633   if (icode != CODE_FOR_nothing)
   6634     {
   6635       tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
   6636       if (tmp)
   6637 	return tmp;
   6638     }
   6639 
   6640   /* As a special case to aid several targets, lower the element-based
   6641      permutation to a byte-based permutation and try again.  */
   6642   machine_mode qimode;
   6643   if (!qimode_for_vec_perm (mode).exists (&qimode)
   6644       || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
   6645     return NULL_RTX;
   6646   icode = direct_optab_handler (vec_perm_optab, qimode);
   6647   if (icode == CODE_FOR_nothing)
   6648     return NULL_RTX;
   6649 
   6650   /* Multiply each element by its byte size.  */
   6651   machine_mode selmode = GET_MODE (sel);
   6652   if (u == 2)
   6653     sel = expand_simple_binop (selmode, PLUS, sel, sel,
   6654 			       NULL, 0, OPTAB_DIRECT);
   6655   else
   6656     sel = expand_simple_binop (selmode, ASHIFT, sel,
   6657 			       gen_int_shift_amount (selmode, exact_log2 (u)),
   6658 			       NULL, 0, OPTAB_DIRECT);
   6659   gcc_assert (sel != NULL);
   6660 
   6661   /* Broadcast the low byte each element into each of its bytes.
   6662      The encoding has U interleaved stepped patterns, one for each
   6663      byte of an element.  */
   6664   vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
   6665   unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
   6666   for (i = 0; i < 3; ++i)
   6667     for (unsigned int j = 0; j < u; ++j)
   6668       const_sel.quick_push (i * u + low_byte_in_u);
   6669   sel = gen_lowpart (qimode, sel);
   6670   sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
   6671   gcc_assert (sel != NULL);
   6672 
   6673   /* Add the byte offset to each byte element.  */
   6674   /* Note that the definition of the indicies here is memory ordering,
   6675      so there should be no difference between big and little endian.  */
   6676   rtx_vector_builder byte_indices (qimode, u, 1);
   6677   for (i = 0; i < u; ++i)
   6678     byte_indices.quick_push (GEN_INT (i));
   6679   tmp = byte_indices.build ();
   6680   sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
   6681 				sel, 0, OPTAB_DIRECT);
   6682   gcc_assert (sel_qi != NULL);
   6683 
   6684   tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
   6685   tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
   6686 			   gen_lowpart (qimode, v1), sel_qi);
   6687   if (tmp)
   6688     tmp = gen_lowpart (mode, tmp);
   6689   return tmp;
   6690 }
   6691 
   6692 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
   6693    Use TARGET for the result if nonnull and convenient.  */
   6694 
   6695 rtx
   6696 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
   6697 {
   6698   class expand_operand ops[3];
   6699   enum insn_code icode;
   6700   machine_mode emode = GET_MODE_INNER (vmode);
   6701 
   6702   icode = direct_optab_handler (vec_series_optab, vmode);
   6703   gcc_assert (icode != CODE_FOR_nothing);
   6704 
   6705   create_output_operand (&ops[0], target, vmode);
   6706   create_input_operand (&ops[1], op0, emode);
   6707   create_input_operand (&ops[2], op1, emode);
   6708 
   6709   expand_insn (icode, 3, ops);
   6710   return ops[0].value;
   6711 }
   6712 
   6713 /* Generate insns for a vector comparison into a mask.  */
   6714 
   6715 rtx
   6716 expand_vec_cmp_expr (tree type, tree exp, rtx target)
   6717 {
   6718   class expand_operand ops[4];
   6719   enum insn_code icode;
   6720   rtx comparison;
   6721   machine_mode mask_mode = TYPE_MODE (type);
   6722   machine_mode vmode;
   6723   bool unsignedp;
   6724   tree op0a, op0b;
   6725   enum tree_code tcode;
   6726 
   6727   op0a = TREE_OPERAND (exp, 0);
   6728   op0b = TREE_OPERAND (exp, 1);
   6729   tcode = TREE_CODE (exp);
   6730 
   6731   unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
   6732   vmode = TYPE_MODE (TREE_TYPE (op0a));
   6733 
   6734   icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
   6735   if (icode == CODE_FOR_nothing)
   6736     {
   6737       if (tcode == EQ_EXPR || tcode == NE_EXPR)
   6738 	icode = get_vec_cmp_eq_icode (vmode, mask_mode);
   6739       if (icode == CODE_FOR_nothing)
   6740 	return 0;
   6741     }
   6742 
   6743   comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
   6744 				   unsignedp, icode, 2);
   6745   create_output_operand (&ops[0], target, mask_mode);
   6746   create_fixed_operand (&ops[1], comparison);
   6747   create_fixed_operand (&ops[2], XEXP (comparison, 0));
   6748   create_fixed_operand (&ops[3], XEXP (comparison, 1));
   6749   expand_insn (icode, 4, ops);
   6750   return ops[0].value;
   6751 }
   6752 
   6753 /* Expand a highpart multiply.  */
   6754 
   6755 rtx
   6756 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
   6757 		      rtx target, bool uns_p)
   6758 {
   6759   class expand_operand eops[3];
   6760   enum insn_code icode;
   6761   int method, i;
   6762   machine_mode wmode;
   6763   rtx m1, m2;
   6764   optab tab1, tab2;
   6765 
   6766   method = can_mult_highpart_p (mode, uns_p);
   6767   switch (method)
   6768     {
   6769     case 0:
   6770       return NULL_RTX;
   6771     case 1:
   6772       tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
   6773       return expand_binop (mode, tab1, op0, op1, target, uns_p,
   6774 			   OPTAB_LIB_WIDEN);
   6775     case 2:
   6776       tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
   6777       tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
   6778       break;
   6779     case 3:
   6780       tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
   6781       tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
   6782       if (BYTES_BIG_ENDIAN)
   6783 	std::swap (tab1, tab2);
   6784       break;
   6785     default:
   6786       gcc_unreachable ();
   6787     }
   6788 
   6789   icode = optab_handler (tab1, mode);
   6790   wmode = insn_data[icode].operand[0].mode;
   6791   gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
   6792 				 GET_MODE_NUNITS (mode)));
   6793   gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
   6794 
   6795   create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
   6796   create_input_operand (&eops[1], op0, mode);
   6797   create_input_operand (&eops[2], op1, mode);
   6798   expand_insn (icode, 3, eops);
   6799   m1 = gen_lowpart (mode, eops[0].value);
   6800 
   6801   create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
   6802   create_input_operand (&eops[1], op0, mode);
   6803   create_input_operand (&eops[2], op1, mode);
   6804   expand_insn (optab_handler (tab2, mode), 3, eops);
   6805   m2 = gen_lowpart (mode, eops[0].value);
   6806 
   6807   vec_perm_builder sel;
   6808   if (method == 2)
   6809     {
   6810       /* The encoding has 2 interleaved stepped patterns.  */
   6811       sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
   6812       for (i = 0; i < 6; ++i)
   6813 	sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
   6814 			+ ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
   6815     }
   6816   else
   6817     {
   6818       /* The encoding has a single interleaved stepped pattern.  */
   6819       sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
   6820       for (i = 0; i < 3; ++i)
   6821 	sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
   6822     }
   6823 
   6824   return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
   6825 }
   6826 
   6827 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
   6829    pattern.  */
   6830 
   6831 static void
   6832 find_cc_set (rtx x, const_rtx pat, void *data)
   6833 {
   6834   if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
   6835       && GET_CODE (pat) == SET)
   6836     {
   6837       rtx *p_cc_reg = (rtx *) data;
   6838       gcc_assert (!*p_cc_reg);
   6839       *p_cc_reg = x;
   6840     }
   6841 }
   6842 
   6843 /* This is a helper function for the other atomic operations.  This function
   6844    emits a loop that contains SEQ that iterates until a compare-and-swap
   6845    operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
   6846    a set of instructions that takes a value from OLD_REG as an input and
   6847    produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
   6848    set to the current contents of MEM.  After SEQ, a compare-and-swap will
   6849    attempt to update MEM with NEW_REG.  The function returns true when the
   6850    loop was generated successfully.  */
   6851 
   6852 static bool
   6853 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
   6854 {
   6855   machine_mode mode = GET_MODE (mem);
   6856   rtx_code_label *label;
   6857   rtx cmp_reg, success, oldval;
   6858 
   6859   /* The loop we want to generate looks like
   6860 
   6861 	cmp_reg = mem;
   6862       label:
   6863         old_reg = cmp_reg;
   6864 	seq;
   6865 	(success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
   6866 	if (success)
   6867 	  goto label;
   6868 
   6869      Note that we only do the plain load from memory once.  Subsequent
   6870      iterations use the value loaded by the compare-and-swap pattern.  */
   6871 
   6872   label = gen_label_rtx ();
   6873   cmp_reg = gen_reg_rtx (mode);
   6874 
   6875   emit_move_insn (cmp_reg, mem);
   6876   emit_label (label);
   6877   emit_move_insn (old_reg, cmp_reg);
   6878   if (seq)
   6879     emit_insn (seq);
   6880 
   6881   success = NULL_RTX;
   6882   oldval = cmp_reg;
   6883   if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
   6884 				       new_reg, false, MEMMODEL_SYNC_SEQ_CST,
   6885 				       MEMMODEL_RELAXED))
   6886     return false;
   6887 
   6888   if (oldval != cmp_reg)
   6889     emit_move_insn (cmp_reg, oldval);
   6890 
   6891   /* Mark this jump predicted not taken.  */
   6892   emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
   6893 			   GET_MODE (success), 1, label,
   6894 			   profile_probability::guessed_never ());
   6895   return true;
   6896 }
   6897 
   6898 
   6899 /* This function tries to emit an atomic_exchange intruction.  VAL is written
   6900    to *MEM using memory model MODEL. The previous contents of *MEM are returned,
   6901    using TARGET if possible.  */
   6902 
   6903 static rtx
   6904 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
   6905 {
   6906   machine_mode mode = GET_MODE (mem);
   6907   enum insn_code icode;
   6908 
   6909   /* If the target supports the exchange directly, great.  */
   6910   icode = direct_optab_handler (atomic_exchange_optab, mode);
   6911   if (icode != CODE_FOR_nothing)
   6912     {
   6913       class expand_operand ops[4];
   6914 
   6915       create_output_operand (&ops[0], target, mode);
   6916       create_fixed_operand (&ops[1], mem);
   6917       create_input_operand (&ops[2], val, mode);
   6918       create_integer_operand (&ops[3], model);
   6919       if (maybe_expand_insn (icode, 4, ops))
   6920 	return ops[0].value;
   6921     }
   6922 
   6923   return NULL_RTX;
   6924 }
   6925 
   6926 /* This function tries to implement an atomic exchange operation using
   6927    __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
   6928    The previous contents of *MEM are returned, using TARGET if possible.
   6929    Since this instructionn is an acquire barrier only, stronger memory
   6930    models may require additional barriers to be emitted.  */
   6931 
   6932 static rtx
   6933 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
   6934 				   enum memmodel model)
   6935 {
   6936   machine_mode mode = GET_MODE (mem);
   6937   enum insn_code icode;
   6938   rtx_insn *last_insn = get_last_insn ();
   6939 
   6940   icode = optab_handler (sync_lock_test_and_set_optab, mode);
   6941 
   6942   /* Legacy sync_lock_test_and_set is an acquire barrier.  If the pattern
   6943      exists, and the memory model is stronger than acquire, add a release
   6944      barrier before the instruction.  */
   6945 
   6946   if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
   6947     expand_mem_thread_fence (model);
   6948 
   6949   if (icode != CODE_FOR_nothing)
   6950     {
   6951       class expand_operand ops[3];
   6952       create_output_operand (&ops[0], target, mode);
   6953       create_fixed_operand (&ops[1], mem);
   6954       create_input_operand (&ops[2], val, mode);
   6955       if (maybe_expand_insn (icode, 3, ops))
   6956 	return ops[0].value;
   6957     }
   6958 
   6959   /* If an external test-and-set libcall is provided, use that instead of
   6960      any external compare-and-swap that we might get from the compare-and-
   6961      swap-loop expansion later.  */
   6962   if (!can_compare_and_swap_p (mode, false))
   6963     {
   6964       rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
   6965       if (libfunc != NULL)
   6966 	{
   6967 	  rtx addr;
   6968 
   6969 	  addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
   6970 	  return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
   6971 					  mode, addr, ptr_mode,
   6972 					  val, mode);
   6973 	}
   6974     }
   6975 
   6976   /* If the test_and_set can't be emitted, eliminate any barrier that might
   6977      have been emitted.  */
   6978   delete_insns_since (last_insn);
   6979   return NULL_RTX;
   6980 }
   6981 
   6982 /* This function tries to implement an atomic exchange operation using a
   6983    compare_and_swap loop. VAL is written to *MEM.  The previous contents of
   6984    *MEM are returned, using TARGET if possible.  No memory model is required
   6985    since a compare_and_swap loop is seq-cst.  */
   6986 
   6987 static rtx
   6988 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
   6989 {
   6990   machine_mode mode = GET_MODE (mem);
   6991 
   6992   if (can_compare_and_swap_p (mode, true))
   6993     {
   6994       if (!target || !register_operand (target, mode))
   6995 	target = gen_reg_rtx (mode);
   6996       if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
   6997 	return target;
   6998     }
   6999 
   7000   return NULL_RTX;
   7001 }
   7002 
   7003 /* This function tries to implement an atomic test-and-set operation
   7004    using the atomic_test_and_set instruction pattern.  A boolean value
   7005    is returned from the operation, using TARGET if possible.  */
   7006 
   7007 static rtx
   7008 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
   7009 {
   7010   machine_mode pat_bool_mode;
   7011   class expand_operand ops[3];
   7012 
   7013   if (!targetm.have_atomic_test_and_set ())
   7014     return NULL_RTX;
   7015 
   7016   /* While we always get QImode from __atomic_test_and_set, we get
   7017      other memory modes from __sync_lock_test_and_set.  Note that we
   7018      use no endian adjustment here.  This matches the 4.6 behavior
   7019      in the Sparc backend.  */
   7020   enum insn_code icode = targetm.code_for_atomic_test_and_set;
   7021   gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
   7022   if (GET_MODE (mem) != QImode)
   7023     mem = adjust_address_nv (mem, QImode, 0);
   7024 
   7025   pat_bool_mode = insn_data[icode].operand[0].mode;
   7026   create_output_operand (&ops[0], target, pat_bool_mode);
   7027   create_fixed_operand (&ops[1], mem);
   7028   create_integer_operand (&ops[2], model);
   7029 
   7030   if (maybe_expand_insn (icode, 3, ops))
   7031     return ops[0].value;
   7032   return NULL_RTX;
   7033 }
   7034 
   7035 /* This function expands the legacy _sync_lock test_and_set operation which is
   7036    generally an atomic exchange.  Some limited targets only allow the
   7037    constant 1 to be stored.  This is an ACQUIRE operation.
   7038 
   7039    TARGET is an optional place to stick the return value.
   7040    MEM is where VAL is stored.  */
   7041 
   7042 rtx
   7043 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
   7044 {
   7045   rtx ret;
   7046 
   7047   /* Try an atomic_exchange first.  */
   7048   ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
   7049   if (ret)
   7050     return ret;
   7051 
   7052   ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
   7053 					   MEMMODEL_SYNC_ACQUIRE);
   7054   if (ret)
   7055     return ret;
   7056 
   7057   ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
   7058   if (ret)
   7059     return ret;
   7060 
   7061   /* If there are no other options, try atomic_test_and_set if the value
   7062      being stored is 1.  */
   7063   if (val == const1_rtx)
   7064     ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
   7065 
   7066   return ret;
   7067 }
   7068 
   7069 /* This function expands the atomic test_and_set operation:
   7070    atomically store a boolean TRUE into MEM and return the previous value.
   7071 
   7072    MEMMODEL is the memory model variant to use.
   7073    TARGET is an optional place to stick the return value.  */
   7074 
   7075 rtx
   7076 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
   7077 {
   7078   machine_mode mode = GET_MODE (mem);
   7079   rtx ret, trueval, subtarget;
   7080 
   7081   ret = maybe_emit_atomic_test_and_set (target, mem, model);
   7082   if (ret)
   7083     return ret;
   7084 
   7085   /* Be binary compatible with non-default settings of trueval, and different
   7086      cpu revisions.  E.g. one revision may have atomic-test-and-set, but
   7087      another only has atomic-exchange.  */
   7088   if (targetm.atomic_test_and_set_trueval == 1)
   7089     {
   7090       trueval = const1_rtx;
   7091       subtarget = target ? target : gen_reg_rtx (mode);
   7092     }
   7093   else
   7094     {
   7095       trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
   7096       subtarget = gen_reg_rtx (mode);
   7097     }
   7098 
   7099   /* Try the atomic-exchange optab...  */
   7100   ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
   7101 
   7102   /* ... then an atomic-compare-and-swap loop ... */
   7103   if (!ret)
   7104     ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
   7105 
   7106   /* ... before trying the vaguely defined legacy lock_test_and_set. */
   7107   if (!ret)
   7108     ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
   7109 
   7110   /* Recall that the legacy lock_test_and_set optab was allowed to do magic
   7111      things with the value 1.  Thus we try again without trueval.  */
   7112   if (!ret && targetm.atomic_test_and_set_trueval != 1)
   7113     {
   7114       ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
   7115 
   7116       if (ret)
   7117 	{
   7118 	  /* Rectify the not-one trueval.  */
   7119 	  ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
   7120 	  gcc_assert (ret);
   7121 	}
   7122     }
   7123 
   7124   return ret;
   7125 }
   7126 
   7127 /* This function expands the atomic exchange operation:
   7128    atomically store VAL in MEM and return the previous value in MEM.
   7129 
   7130    MEMMODEL is the memory model variant to use.
   7131    TARGET is an optional place to stick the return value.  */
   7132 
   7133 rtx
   7134 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
   7135 {
   7136   machine_mode mode = GET_MODE (mem);
   7137   rtx ret;
   7138 
   7139   /* If loads are not atomic for the required size and we are not called to
   7140      provide a __sync builtin, do not do anything so that we stay consistent
   7141      with atomic loads of the same size.  */
   7142   if (!can_atomic_load_p (mode) && !is_mm_sync (model))
   7143     return NULL_RTX;
   7144 
   7145   ret = maybe_emit_atomic_exchange (target, mem, val, model);
   7146 
   7147   /* Next try a compare-and-swap loop for the exchange.  */
   7148   if (!ret)
   7149     ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
   7150 
   7151   return ret;
   7152 }
   7153 
   7154 /* This function expands the atomic compare exchange operation:
   7155 
   7156    *PTARGET_BOOL is an optional place to store the boolean success/failure.
   7157    *PTARGET_OVAL is an optional place to store the old value from memory.
   7158    Both target parameters may be NULL or const0_rtx to indicate that we do
   7159    not care about that return value.  Both target parameters are updated on
   7160    success to the actual location of the corresponding result.
   7161 
   7162    MEMMODEL is the memory model variant to use.
   7163 
   7164    The return value of the function is true for success.  */
   7165 
   7166 bool
   7167 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
   7168 				rtx mem, rtx expected, rtx desired,
   7169 				bool is_weak, enum memmodel succ_model,
   7170 				enum memmodel fail_model)
   7171 {
   7172   machine_mode mode = GET_MODE (mem);
   7173   class expand_operand ops[8];
   7174   enum insn_code icode;
   7175   rtx target_oval, target_bool = NULL_RTX;
   7176   rtx libfunc;
   7177 
   7178   /* If loads are not atomic for the required size and we are not called to
   7179      provide a __sync builtin, do not do anything so that we stay consistent
   7180      with atomic loads of the same size.  */
   7181   if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
   7182     return false;
   7183 
   7184   /* Load expected into a register for the compare and swap.  */
   7185   if (MEM_P (expected))
   7186     expected = copy_to_reg (expected);
   7187 
   7188   /* Make sure we always have some place to put the return oldval.
   7189      Further, make sure that place is distinct from the input expected,
   7190      just in case we need that path down below.  */
   7191   if (ptarget_oval && *ptarget_oval == const0_rtx)
   7192     ptarget_oval = NULL;
   7193 
   7194   if (ptarget_oval == NULL
   7195       || (target_oval = *ptarget_oval) == NULL
   7196       || reg_overlap_mentioned_p (expected, target_oval))
   7197     target_oval = gen_reg_rtx (mode);
   7198 
   7199   icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
   7200   if (icode != CODE_FOR_nothing)
   7201     {
   7202       machine_mode bool_mode = insn_data[icode].operand[0].mode;
   7203 
   7204       if (ptarget_bool && *ptarget_bool == const0_rtx)
   7205 	ptarget_bool = NULL;
   7206 
   7207       /* Make sure we always have a place for the bool operand.  */
   7208       if (ptarget_bool == NULL
   7209 	  || (target_bool = *ptarget_bool) == NULL
   7210 	  || GET_MODE (target_bool) != bool_mode)
   7211 	target_bool = gen_reg_rtx (bool_mode);
   7212 
   7213       /* Emit the compare_and_swap.  */
   7214       create_output_operand (&ops[0], target_bool, bool_mode);
   7215       create_output_operand (&ops[1], target_oval, mode);
   7216       create_fixed_operand (&ops[2], mem);
   7217       create_input_operand (&ops[3], expected, mode);
   7218       create_input_operand (&ops[4], desired, mode);
   7219       create_integer_operand (&ops[5], is_weak);
   7220       create_integer_operand (&ops[6], succ_model);
   7221       create_integer_operand (&ops[7], fail_model);
   7222       if (maybe_expand_insn (icode, 8, ops))
   7223 	{
   7224 	  /* Return success/failure.  */
   7225 	  target_bool = ops[0].value;
   7226 	  target_oval = ops[1].value;
   7227 	  goto success;
   7228 	}
   7229     }
   7230 
   7231   /* Otherwise fall back to the original __sync_val_compare_and_swap
   7232      which is always seq-cst.  */
   7233   icode = optab_handler (sync_compare_and_swap_optab, mode);
   7234   if (icode != CODE_FOR_nothing)
   7235     {
   7236       rtx cc_reg;
   7237 
   7238       create_output_operand (&ops[0], target_oval, mode);
   7239       create_fixed_operand (&ops[1], mem);
   7240       create_input_operand (&ops[2], expected, mode);
   7241       create_input_operand (&ops[3], desired, mode);
   7242       if (!maybe_expand_insn (icode, 4, ops))
   7243 	return false;
   7244 
   7245       target_oval = ops[0].value;
   7246 
   7247       /* If the caller isn't interested in the boolean return value,
   7248 	 skip the computation of it.  */
   7249       if (ptarget_bool == NULL)
   7250 	goto success;
   7251 
   7252       /* Otherwise, work out if the compare-and-swap succeeded.  */
   7253       cc_reg = NULL_RTX;
   7254       if (have_insn_for (COMPARE, CCmode))
   7255 	note_stores (get_last_insn (), find_cc_set, &cc_reg);
   7256       if (cc_reg)
   7257 	{
   7258 	  target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
   7259 					       const0_rtx, VOIDmode, 0, 1);
   7260 	  goto success;
   7261 	}
   7262       goto success_bool_from_val;
   7263     }
   7264 
   7265   /* Also check for library support for __sync_val_compare_and_swap.  */
   7266   libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
   7267   if (libfunc != NULL)
   7268     {
   7269       rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
   7270       rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
   7271 					    mode, addr, ptr_mode,
   7272 					    expected, mode, desired, mode);
   7273       emit_move_insn (target_oval, target);
   7274 
   7275       /* Compute the boolean return value only if requested.  */
   7276       if (ptarget_bool)
   7277 	goto success_bool_from_val;
   7278       else
   7279 	goto success;
   7280     }
   7281 
   7282   /* Failure.  */
   7283   return false;
   7284 
   7285  success_bool_from_val:
   7286    target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
   7287 					expected, VOIDmode, 1, 1);
   7288  success:
   7289   /* Make sure that the oval output winds up where the caller asked.  */
   7290   if (ptarget_oval)
   7291     *ptarget_oval = target_oval;
   7292   if (ptarget_bool)
   7293     *ptarget_bool = target_bool;
   7294   return true;
   7295 }
   7296 
   7297 /* Generate asm volatile("" : : : "memory") as the memory blockage.  */
   7298 
   7299 static void
   7300 expand_asm_memory_blockage (void)
   7301 {
   7302   rtx asm_op, clob;
   7303 
   7304   asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
   7305 				 rtvec_alloc (0), rtvec_alloc (0),
   7306 				 rtvec_alloc (0), UNKNOWN_LOCATION);
   7307   MEM_VOLATILE_P (asm_op) = 1;
   7308 
   7309   clob = gen_rtx_SCRATCH (VOIDmode);
   7310   clob = gen_rtx_MEM (BLKmode, clob);
   7311   clob = gen_rtx_CLOBBER (VOIDmode, clob);
   7312 
   7313   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
   7314 }
   7315 
   7316 /* Do not propagate memory accesses across this point.  */
   7317 
   7318 static void
   7319 expand_memory_blockage (void)
   7320 {
   7321   if (targetm.have_memory_blockage ())
   7322     emit_insn (targetm.gen_memory_blockage ());
   7323   else
   7324     expand_asm_memory_blockage ();
   7325 }
   7326 
   7327 /* Generate asm volatile("" : : : "memory") as a memory blockage, at the
   7328    same time clobbering the register set specified by REGS.  */
   7329 
   7330 void
   7331 expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
   7332 {
   7333   rtx asm_op, clob_mem;
   7334 
   7335   unsigned int num_of_regs = 0;
   7336   for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   7337     if (TEST_HARD_REG_BIT (regs, i))
   7338       num_of_regs++;
   7339 
   7340   asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
   7341 				 rtvec_alloc (0), rtvec_alloc (0),
   7342 				 rtvec_alloc (0), UNKNOWN_LOCATION);
   7343   MEM_VOLATILE_P (asm_op) = 1;
   7344 
   7345   rtvec v = rtvec_alloc (num_of_regs + 2);
   7346 
   7347   clob_mem = gen_rtx_SCRATCH (VOIDmode);
   7348   clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
   7349   clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);
   7350 
   7351   RTVEC_ELT (v, 0) = asm_op;
   7352   RTVEC_ELT (v, 1) = clob_mem;
   7353 
   7354   if (num_of_regs > 0)
   7355     {
   7356       unsigned int j = 2;
   7357       for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   7358 	if (TEST_HARD_REG_BIT (regs, i))
   7359 	  {
   7360 	    RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
   7361  	    j++;
   7362 	  }
   7363       gcc_assert (j == (num_of_regs + 2));
   7364     }
   7365 
   7366   emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
   7367 }
   7368 
   7369 /* This routine will either emit the mem_thread_fence pattern or issue a
   7370    sync_synchronize to generate a fence for memory model MEMMODEL.  */
   7371 
   7372 void
   7373 expand_mem_thread_fence (enum memmodel model)
   7374 {
   7375   if (is_mm_relaxed (model))
   7376     return;
   7377   if (targetm.have_mem_thread_fence ())
   7378     {
   7379       emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
   7380       expand_memory_blockage ();
   7381     }
   7382   else if (targetm.have_memory_barrier ())
   7383     emit_insn (targetm.gen_memory_barrier ());
   7384   else if (synchronize_libfunc != NULL_RTX)
   7385     emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
   7386   else
   7387     expand_memory_blockage ();
   7388 }
   7389 
   7390 /* Emit a signal fence with given memory model.  */
   7391 
   7392 void
   7393 expand_mem_signal_fence (enum memmodel model)
   7394 {
   7395   /* No machine barrier is required to implement a signal fence, but
   7396      a compiler memory barrier must be issued, except for relaxed MM.  */
   7397   if (!is_mm_relaxed (model))
   7398     expand_memory_blockage ();
   7399 }
   7400 
   7401 /* This function expands the atomic load operation:
   7402    return the atomically loaded value in MEM.
   7403 
   7404    MEMMODEL is the memory model variant to use.
   7405    TARGET is an option place to stick the return value.  */
   7406 
   7407 rtx
   7408 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
   7409 {
   7410   machine_mode mode = GET_MODE (mem);
   7411   enum insn_code icode;
   7412 
   7413   /* If the target supports the load directly, great.  */
   7414   icode = direct_optab_handler (atomic_load_optab, mode);
   7415   if (icode != CODE_FOR_nothing)
   7416     {
   7417       class expand_operand ops[3];
   7418       rtx_insn *last = get_last_insn ();
   7419       if (is_mm_seq_cst (model))
   7420 	expand_memory_blockage ();
   7421 
   7422       create_output_operand (&ops[0], target, mode);
   7423       create_fixed_operand (&ops[1], mem);
   7424       create_integer_operand (&ops[2], model);
   7425       if (maybe_expand_insn (icode, 3, ops))
   7426 	{
   7427 	  if (!is_mm_relaxed (model))
   7428 	    expand_memory_blockage ();
   7429 	  return ops[0].value;
   7430 	}
   7431       delete_insns_since (last);
   7432     }
   7433 
   7434   /* If the size of the object is greater than word size on this target,
   7435      then we assume that a load will not be atomic.  We could try to
   7436      emulate a load with a compare-and-swap operation, but the store that
   7437      doing this could result in would be incorrect if this is a volatile
   7438      atomic load or targetting read-only-mapped memory.  */
   7439   if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
   7440     /* If there is no atomic load, leave the library call.  */
   7441     return NULL_RTX;
   7442 
   7443   /* Otherwise assume loads are atomic, and emit the proper barriers.  */
   7444   if (!target || target == const0_rtx)
   7445     target = gen_reg_rtx (mode);
   7446 
   7447   /* For SEQ_CST, emit a barrier before the load.  */
   7448   if (is_mm_seq_cst (model))
   7449     expand_mem_thread_fence (model);
   7450 
   7451   emit_move_insn (target, mem);
   7452 
   7453   /* Emit the appropriate barrier after the load.  */
   7454   expand_mem_thread_fence (model);
   7455 
   7456   return target;
   7457 }
   7458 
   7459 /* This function expands the atomic store operation:
   7460    Atomically store VAL in MEM.
   7461    MEMMODEL is the memory model variant to use.
   7462    USE_RELEASE is true if __sync_lock_release can be used as a fall back.
   7463    function returns const0_rtx if a pattern was emitted.  */
   7464 
   7465 rtx
   7466 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
   7467 {
   7468   machine_mode mode = GET_MODE (mem);
   7469   enum insn_code icode;
   7470   class expand_operand ops[3];
   7471 
   7472   /* If the target supports the store directly, great.  */
   7473   icode = direct_optab_handler (atomic_store_optab, mode);
   7474   if (icode != CODE_FOR_nothing)
   7475     {
   7476       rtx_insn *last = get_last_insn ();
   7477       if (!is_mm_relaxed (model))
   7478 	expand_memory_blockage ();
   7479       create_fixed_operand (&ops[0], mem);
   7480       create_input_operand (&ops[1], val, mode);
   7481       create_integer_operand (&ops[2], model);
   7482       if (maybe_expand_insn (icode, 3, ops))
   7483 	{
   7484 	  if (is_mm_seq_cst (model))
   7485 	    expand_memory_blockage ();
   7486 	  return const0_rtx;
   7487 	}
   7488       delete_insns_since (last);
   7489     }
   7490 
   7491   /* If using __sync_lock_release is a viable alternative, try it.
   7492      Note that this will not be set to true if we are expanding a generic
   7493      __atomic_store_n.  */
   7494   if (use_release)
   7495     {
   7496       icode = direct_optab_handler (sync_lock_release_optab, mode);
   7497       if (icode != CODE_FOR_nothing)
   7498 	{
   7499 	  create_fixed_operand (&ops[0], mem);
   7500 	  create_input_operand (&ops[1], const0_rtx, mode);
   7501 	  if (maybe_expand_insn (icode, 2, ops))
   7502 	    {
   7503 	      /* lock_release is only a release barrier.  */
   7504 	      if (is_mm_seq_cst (model))
   7505 		expand_mem_thread_fence (model);
   7506 	      return const0_rtx;
   7507 	    }
   7508 	}
   7509     }
   7510 
   7511   /* If the size of the object is greater than word size on this target,
   7512      a default store will not be atomic.  */
   7513   if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
   7514     {
   7515       /* If loads are atomic or we are called to provide a __sync builtin,
   7516 	 we can try a atomic_exchange and throw away the result.  Otherwise,
   7517 	 don't do anything so that we do not create an inconsistency between
   7518 	 loads and stores.  */
   7519       if (can_atomic_load_p (mode) || is_mm_sync (model))
   7520 	{
   7521 	  rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
   7522 	  if (!target)
   7523 	    target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
   7524 								val);
   7525 	  if (target)
   7526 	    return const0_rtx;
   7527 	}
   7528         return NULL_RTX;
   7529     }
   7530 
   7531   /* Otherwise assume stores are atomic, and emit the proper barriers.  */
   7532   expand_mem_thread_fence (model);
   7533 
   7534   emit_move_insn (mem, val);
   7535 
   7536   /* For SEQ_CST, also emit a barrier after the store.  */
   7537   if (is_mm_seq_cst (model))
   7538     expand_mem_thread_fence (model);
   7539 
   7540   return const0_rtx;
   7541 }
   7542 
   7543 
   7544 /* Structure containing the pointers and values required to process the
   7545    various forms of the atomic_fetch_op and atomic_op_fetch builtins.  */
   7546 
   7547 struct atomic_op_functions
   7548 {
   7549   direct_optab mem_fetch_before;
   7550   direct_optab mem_fetch_after;
   7551   direct_optab mem_no_result;
   7552   optab fetch_before;
   7553   optab fetch_after;
   7554   direct_optab no_result;
   7555   enum rtx_code reverse_code;
   7556 };
   7557 
   7558 
   7559 /* Fill in structure pointed to by OP with the various optab entries for an
   7560    operation of type CODE.  */
   7561 
   7562 static void
   7563 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
   7564 {
   7565   gcc_assert (op!= NULL);
   7566 
   7567   /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
   7568      in the source code during compilation, and the optab entries are not
   7569      computable until runtime.  Fill in the values at runtime.  */
   7570   switch (code)
   7571     {
   7572     case PLUS:
   7573       op->mem_fetch_before = atomic_fetch_add_optab;
   7574       op->mem_fetch_after = atomic_add_fetch_optab;
   7575       op->mem_no_result = atomic_add_optab;
   7576       op->fetch_before = sync_old_add_optab;
   7577       op->fetch_after = sync_new_add_optab;
   7578       op->no_result = sync_add_optab;
   7579       op->reverse_code = MINUS;
   7580       break;
   7581     case MINUS:
   7582       op->mem_fetch_before = atomic_fetch_sub_optab;
   7583       op->mem_fetch_after = atomic_sub_fetch_optab;
   7584       op->mem_no_result = atomic_sub_optab;
   7585       op->fetch_before = sync_old_sub_optab;
   7586       op->fetch_after = sync_new_sub_optab;
   7587       op->no_result = sync_sub_optab;
   7588       op->reverse_code = PLUS;
   7589       break;
   7590     case XOR:
   7591       op->mem_fetch_before = atomic_fetch_xor_optab;
   7592       op->mem_fetch_after = atomic_xor_fetch_optab;
   7593       op->mem_no_result = atomic_xor_optab;
   7594       op->fetch_before = sync_old_xor_optab;
   7595       op->fetch_after = sync_new_xor_optab;
   7596       op->no_result = sync_xor_optab;
   7597       op->reverse_code = XOR;
   7598       break;
   7599     case AND:
   7600       op->mem_fetch_before = atomic_fetch_and_optab;
   7601       op->mem_fetch_after = atomic_and_fetch_optab;
   7602       op->mem_no_result = atomic_and_optab;
   7603       op->fetch_before = sync_old_and_optab;
   7604       op->fetch_after = sync_new_and_optab;
   7605       op->no_result = sync_and_optab;
   7606       op->reverse_code = UNKNOWN;
   7607       break;
   7608     case IOR:
   7609       op->mem_fetch_before = atomic_fetch_or_optab;
   7610       op->mem_fetch_after = atomic_or_fetch_optab;
   7611       op->mem_no_result = atomic_or_optab;
   7612       op->fetch_before = sync_old_ior_optab;
   7613       op->fetch_after = sync_new_ior_optab;
   7614       op->no_result = sync_ior_optab;
   7615       op->reverse_code = UNKNOWN;
   7616       break;
   7617     case NOT:
   7618       op->mem_fetch_before = atomic_fetch_nand_optab;
   7619       op->mem_fetch_after = atomic_nand_fetch_optab;
   7620       op->mem_no_result = atomic_nand_optab;
   7621       op->fetch_before = sync_old_nand_optab;
   7622       op->fetch_after = sync_new_nand_optab;
   7623       op->no_result = sync_nand_optab;
   7624       op->reverse_code = UNKNOWN;
   7625       break;
   7626     default:
   7627       gcc_unreachable ();
   7628     }
   7629 }
   7630 
   7631 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
   7632    using memory order MODEL.  If AFTER is true the operation needs to return
   7633    the value of *MEM after the operation, otherwise the previous value.
   7634    TARGET is an optional place to place the result.  The result is unused if
   7635    it is const0_rtx.
   7636    Return the result if there is a better sequence, otherwise NULL_RTX.  */
   7637 
   7638 static rtx
   7639 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
   7640 			 enum memmodel model, bool after)
   7641 {
   7642   /* If the value is prefetched, or not used, it may be possible to replace
   7643      the sequence with a native exchange operation.  */
   7644   if (!after || target == const0_rtx)
   7645     {
   7646       /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m).  */
   7647       if (code == AND && val == const0_rtx)
   7648         {
   7649 	  if (target == const0_rtx)
   7650 	    target = gen_reg_rtx (GET_MODE (mem));
   7651 	  return maybe_emit_atomic_exchange (target, mem, val, model);
   7652 	}
   7653 
   7654       /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m).  */
   7655       if (code == IOR && val == constm1_rtx)
   7656         {
   7657 	  if (target == const0_rtx)
   7658 	    target = gen_reg_rtx (GET_MODE (mem));
   7659 	  return maybe_emit_atomic_exchange (target, mem, val, model);
   7660 	}
   7661     }
   7662 
   7663   return NULL_RTX;
   7664 }
   7665 
   7666 /* Try to emit an instruction for a specific operation varaition.
   7667    OPTAB contains the OP functions.
   7668    TARGET is an optional place to return the result. const0_rtx means unused.
   7669    MEM is the memory location to operate on.
   7670    VAL is the value to use in the operation.
   7671    USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
   7672    MODEL is the memory model, if used.
   7673    AFTER is true if the returned result is the value after the operation.  */
   7674 
   7675 static rtx
   7676 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
   7677 	       rtx val, bool use_memmodel, enum memmodel model, bool after)
   7678 {
   7679   machine_mode mode = GET_MODE (mem);
   7680   class expand_operand ops[4];
   7681   enum insn_code icode;
   7682   int op_counter = 0;
   7683   int num_ops;
   7684 
   7685   /* Check to see if there is a result returned.  */
   7686   if (target == const0_rtx)
   7687     {
   7688       if (use_memmodel)
   7689         {
   7690 	  icode = direct_optab_handler (optab->mem_no_result, mode);
   7691 	  create_integer_operand (&ops[2], model);
   7692 	  num_ops = 3;
   7693 	}
   7694       else
   7695         {
   7696 	  icode = direct_optab_handler (optab->no_result, mode);
   7697 	  num_ops = 2;
   7698 	}
   7699     }
   7700   /* Otherwise, we need to generate a result.  */
   7701   else
   7702     {
   7703       if (use_memmodel)
   7704         {
   7705 	  icode = direct_optab_handler (after ? optab->mem_fetch_after
   7706 					: optab->mem_fetch_before, mode);
   7707 	  create_integer_operand (&ops[3], model);
   7708 	  num_ops = 4;
   7709 	}
   7710       else
   7711 	{
   7712 	  icode = optab_handler (after ? optab->fetch_after
   7713 				 : optab->fetch_before, mode);
   7714 	  num_ops = 3;
   7715 	}
   7716       create_output_operand (&ops[op_counter++], target, mode);
   7717     }
   7718   if (icode == CODE_FOR_nothing)
   7719     return NULL_RTX;
   7720 
   7721   create_fixed_operand (&ops[op_counter++], mem);
   7722   /* VAL may have been promoted to a wider mode.  Shrink it if so.  */
   7723   create_convert_operand_to (&ops[op_counter++], val, mode, true);
   7724 
   7725   if (maybe_expand_insn (icode, num_ops, ops))
   7726     return (target == const0_rtx ? const0_rtx : ops[0].value);
   7727 
   7728   return NULL_RTX;
   7729 }
   7730 
   7731 
   7732 /* This function expands an atomic fetch_OP or OP_fetch operation:
   7733    TARGET is an option place to stick the return value.  const0_rtx indicates
   7734    the result is unused.
   7735    atomically fetch MEM, perform the operation with VAL and return it to MEM.
   7736    CODE is the operation being performed (OP)
   7737    MEMMODEL is the memory model variant to use.
   7738    AFTER is true to return the result of the operation (OP_fetch).
   7739    AFTER is false to return the value before the operation (fetch_OP).
   7740 
   7741    This function will *only* generate instructions if there is a direct
   7742    optab. No compare and swap loops or libcalls will be generated. */
   7743 
   7744 static rtx
   7745 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
   7746 				    enum rtx_code code, enum memmodel model,
   7747 				    bool after)
   7748 {
   7749   machine_mode mode = GET_MODE (mem);
   7750   struct atomic_op_functions optab;
   7751   rtx result;
   7752   bool unused_result = (target == const0_rtx);
   7753 
   7754   get_atomic_op_for_code (&optab, code);
   7755 
   7756   /* Check to see if there are any better instructions.  */
   7757   result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
   7758   if (result)
   7759     return result;
   7760 
   7761   /* Check for the case where the result isn't used and try those patterns.  */
   7762   if (unused_result)
   7763     {
   7764       /* Try the memory model variant first.  */
   7765       result = maybe_emit_op (&optab, target, mem, val, true, model, true);
   7766       if (result)
   7767         return result;
   7768 
   7769       /* Next try the old style withuot a memory model.  */
   7770       result = maybe_emit_op (&optab, target, mem, val, false, model, true);
   7771       if (result)
   7772         return result;
   7773 
   7774       /* There is no no-result pattern, so try patterns with a result.  */
   7775       target = NULL_RTX;
   7776     }
   7777 
   7778   /* Try the __atomic version.  */
   7779   result = maybe_emit_op (&optab, target, mem, val, true, model, after);
   7780   if (result)
   7781     return result;
   7782 
   7783   /* Try the older __sync version.  */
   7784   result = maybe_emit_op (&optab, target, mem, val, false, model, after);
   7785   if (result)
   7786     return result;
   7787 
   7788   /* If the fetch value can be calculated from the other variation of fetch,
   7789      try that operation.  */
   7790   if (after || unused_result || optab.reverse_code != UNKNOWN)
   7791     {
   7792       /* Try the __atomic version, then the older __sync version.  */
   7793       result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
   7794       if (!result)
   7795 	result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
   7796 
   7797       if (result)
   7798 	{
   7799 	  /* If the result isn't used, no need to do compensation code.  */
   7800 	  if (unused_result)
   7801 	    return result;
   7802 
   7803 	  /* Issue compensation code.  Fetch_after  == fetch_before OP val.
   7804 	     Fetch_before == after REVERSE_OP val.  */
   7805 	  if (!after)
   7806 	    code = optab.reverse_code;
   7807 	  if (code == NOT)
   7808 	    {
   7809 	      result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
   7810 					    true, OPTAB_LIB_WIDEN);
   7811 	      result = expand_simple_unop (mode, NOT, result, target, true);
   7812 	    }
   7813 	  else
   7814 	    result = expand_simple_binop (mode, code, result, val, target,
   7815 					  true, OPTAB_LIB_WIDEN);
   7816 	  return result;
   7817 	}
   7818     }
   7819 
   7820   /* No direct opcode can be generated.  */
   7821   return NULL_RTX;
   7822 }
   7823 
   7824 
   7825 
   7826 /* This function expands an atomic fetch_OP or OP_fetch operation:
   7827    TARGET is an option place to stick the return value.  const0_rtx indicates
   7828    the result is unused.
   7829    atomically fetch MEM, perform the operation with VAL and return it to MEM.
   7830    CODE is the operation being performed (OP)
   7831    MEMMODEL is the memory model variant to use.
   7832    AFTER is true to return the result of the operation (OP_fetch).
   7833    AFTER is false to return the value before the operation (fetch_OP).  */
   7834 rtx
   7835 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
   7836 			enum memmodel model, bool after)
   7837 {
   7838   machine_mode mode = GET_MODE (mem);
   7839   rtx result;
   7840   bool unused_result = (target == const0_rtx);
   7841 
   7842   /* If loads are not atomic for the required size and we are not called to
   7843      provide a __sync builtin, do not do anything so that we stay consistent
   7844      with atomic loads of the same size.  */
   7845   if (!can_atomic_load_p (mode) && !is_mm_sync (model))
   7846     return NULL_RTX;
   7847 
   7848   result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
   7849 					       after);
   7850 
   7851   if (result)
   7852     return result;
   7853 
   7854   /* Add/sub can be implemented by doing the reverse operation with -(val).  */
   7855   if (code == PLUS || code == MINUS)
   7856     {
   7857       rtx tmp;
   7858       enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
   7859 
   7860       start_sequence ();
   7861       tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
   7862       result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
   7863 						   model, after);
   7864       if (result)
   7865 	{
   7866 	  /* PLUS worked so emit the insns and return.  */
   7867 	  tmp = get_insns ();
   7868 	  end_sequence ();
   7869 	  emit_insn (tmp);
   7870           return result;
   7871 	}
   7872 
   7873       /* PLUS did not work, so throw away the negation code and continue.  */
   7874       end_sequence ();
   7875     }
   7876 
   7877   /* Try the __sync libcalls only if we can't do compare-and-swap inline.  */
   7878   if (!can_compare_and_swap_p (mode, false))
   7879     {
   7880       rtx libfunc;
   7881       bool fixup = false;
   7882       enum rtx_code orig_code = code;
   7883       struct atomic_op_functions optab;
   7884 
   7885       get_atomic_op_for_code (&optab, code);
   7886       libfunc = optab_libfunc (after ? optab.fetch_after
   7887 			       : optab.fetch_before, mode);
   7888       if (libfunc == NULL
   7889 	  && (after || unused_result || optab.reverse_code != UNKNOWN))
   7890 	{
   7891 	  fixup = true;
   7892 	  if (!after)
   7893 	    code = optab.reverse_code;
   7894 	  libfunc = optab_libfunc (after ? optab.fetch_before
   7895 				   : optab.fetch_after, mode);
   7896 	}
   7897       if (libfunc != NULL)
   7898 	{
   7899 	  rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
   7900 	  result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
   7901 					    addr, ptr_mode, val, mode);
   7902 
   7903 	  if (!unused_result && fixup)
   7904 	    result = expand_simple_binop (mode, code, result, val, target,
   7905 					  true, OPTAB_LIB_WIDEN);
   7906 	  return result;
   7907 	}
   7908 
   7909       /* We need the original code for any further attempts.  */
   7910       code = orig_code;
   7911     }
   7912 
   7913   /* If nothing else has succeeded, default to a compare and swap loop.  */
   7914   if (can_compare_and_swap_p (mode, true))
   7915     {
   7916       rtx_insn *insn;
   7917       rtx t0 = gen_reg_rtx (mode), t1;
   7918 
   7919       start_sequence ();
   7920 
   7921       /* If the result is used, get a register for it.  */
   7922       if (!unused_result)
   7923         {
   7924 	  if (!target || !register_operand (target, mode))
   7925 	    target = gen_reg_rtx (mode);
   7926 	  /* If fetch_before, copy the value now.  */
   7927 	  if (!after)
   7928 	    emit_move_insn (target, t0);
   7929 	}
   7930       else
   7931         target = const0_rtx;
   7932 
   7933       t1 = t0;
   7934       if (code == NOT)
   7935         {
   7936 	  t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
   7937 				    true, OPTAB_LIB_WIDEN);
   7938 	  t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
   7939 	}
   7940       else
   7941 	t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
   7942 				  OPTAB_LIB_WIDEN);
   7943 
   7944       /* For after, copy the value now.  */
   7945       if (!unused_result && after)
   7946         emit_move_insn (target, t1);
   7947       insn = get_insns ();
   7948       end_sequence ();
   7949 
   7950       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
   7951         return target;
   7952     }
   7953 
   7954   return NULL_RTX;
   7955 }
   7956 
   7957 /* Return true if OPERAND is suitable for operand number OPNO of
   7959    instruction ICODE.  */
   7960 
   7961 bool
   7962 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
   7963 {
   7964   return (!insn_data[(int) icode].operand[opno].predicate
   7965 	  || (insn_data[(int) icode].operand[opno].predicate
   7966 	      (operand, insn_data[(int) icode].operand[opno].mode)));
   7967 }
   7968 
   7969 /* TARGET is a target of a multiword operation that we are going to
   7971    implement as a series of word-mode operations.  Return true if
   7972    TARGET is suitable for this purpose.  */
   7973 
   7974 bool
   7975 valid_multiword_target_p (rtx target)
   7976 {
   7977   machine_mode mode;
   7978   int i, size;
   7979 
   7980   mode = GET_MODE (target);
   7981   if (!GET_MODE_SIZE (mode).is_constant (&size))
   7982     return false;
   7983   for (i = 0; i < size; i += UNITS_PER_WORD)
   7984     if (!validate_subreg (word_mode, mode, target, i))
   7985       return false;
   7986   return true;
   7987 }
   7988 
   7989 /* Make OP describe an input operand that has value INTVAL and that has
   7990    no inherent mode.  This function should only be used for operands that
   7991    are always expand-time constants.  The backend may request that INTVAL
   7992    be copied into a different kind of rtx, but it must specify the mode
   7993    of that rtx if so.  */
   7994 
   7995 void
   7996 create_integer_operand (class expand_operand *op, poly_int64 intval)
   7997 {
   7998   create_expand_operand (op, EXPAND_INTEGER,
   7999 			 gen_int_mode (intval, MAX_MODE_INT),
   8000 			 VOIDmode, false, intval);
   8001 }
   8002 
   8003 /* Like maybe_legitimize_operand, but do not change the code of the
   8004    current rtx value.  */
   8005 
   8006 static bool
   8007 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
   8008 				    class expand_operand *op)
   8009 {
   8010   /* See if the operand matches in its current form.  */
   8011   if (insn_operand_matches (icode, opno, op->value))
   8012     return true;
   8013 
   8014   /* If the operand is a memory whose address has no side effects,
   8015      try forcing the address into a non-virtual pseudo register.
   8016      The check for side effects is important because copy_to_mode_reg
   8017      cannot handle things like auto-modified addresses.  */
   8018   if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
   8019     {
   8020       rtx addr, mem;
   8021 
   8022       mem = op->value;
   8023       addr = XEXP (mem, 0);
   8024       if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
   8025 	  && !side_effects_p (addr))
   8026 	{
   8027 	  rtx_insn *last;
   8028 	  machine_mode mode;
   8029 
   8030 	  last = get_last_insn ();
   8031 	  mode = get_address_mode (mem);
   8032 	  mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
   8033 	  if (insn_operand_matches (icode, opno, mem))
   8034 	    {
   8035 	      op->value = mem;
   8036 	      return true;
   8037 	    }
   8038 	  delete_insns_since (last);
   8039 	}
   8040     }
   8041 
   8042   return false;
   8043 }
   8044 
   8045 /* Try to make OP match operand OPNO of instruction ICODE.  Return true
   8046    on success, storing the new operand value back in OP.  */
   8047 
   8048 static bool
   8049 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
   8050 			  class expand_operand *op)
   8051 {
   8052   machine_mode mode, imode, tmode;
   8053 
   8054   mode = op->mode;
   8055   switch (op->type)
   8056     {
   8057     case EXPAND_FIXED:
   8058       {
   8059 	temporary_volatile_ok v (true);
   8060 	return maybe_legitimize_operand_same_code (icode, opno, op);
   8061       }
   8062 
   8063     case EXPAND_OUTPUT:
   8064       gcc_assert (mode != VOIDmode);
   8065       if (op->value
   8066 	  && op->value != const0_rtx
   8067 	  && GET_MODE (op->value) == mode
   8068 	  && maybe_legitimize_operand_same_code (icode, opno, op))
   8069 	return true;
   8070 
   8071       op->value = gen_reg_rtx (mode);
   8072       op->target = 0;
   8073       break;
   8074 
   8075     case EXPAND_INPUT:
   8076     input:
   8077       gcc_assert (mode != VOIDmode);
   8078       gcc_assert (GET_MODE (op->value) == VOIDmode
   8079 		  || GET_MODE (op->value) == mode);
   8080       if (maybe_legitimize_operand_same_code (icode, opno, op))
   8081 	return true;
   8082 
   8083       op->value = copy_to_mode_reg (mode, op->value);
   8084       break;
   8085 
   8086     case EXPAND_CONVERT_TO:
   8087       gcc_assert (mode != VOIDmode);
   8088       op->value = convert_to_mode (mode, op->value, op->unsigned_p);
   8089       goto input;
   8090 
   8091     case EXPAND_CONVERT_FROM:
   8092       if (GET_MODE (op->value) != VOIDmode)
   8093 	mode = GET_MODE (op->value);
   8094       else
   8095 	/* The caller must tell us what mode this value has.  */
   8096 	gcc_assert (mode != VOIDmode);
   8097 
   8098       imode = insn_data[(int) icode].operand[opno].mode;
   8099       tmode = (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode)
   8100 	       ? GET_MODE_INNER (imode) : imode);
   8101       if (tmode != VOIDmode && tmode != mode)
   8102 	{
   8103 	  op->value = convert_modes (tmode, mode, op->value, op->unsigned_p);
   8104 	  mode = tmode;
   8105 	}
   8106       if (imode != VOIDmode && imode != mode)
   8107 	{
   8108 	  gcc_assert (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode));
   8109 	  op->value = expand_vector_broadcast (imode, op->value);
   8110 	  mode = imode;
   8111 	}
   8112       goto input;
   8113 
   8114     case EXPAND_ADDRESS:
   8115       op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
   8116 					  op->value);
   8117       goto input;
   8118 
   8119     case EXPAND_INTEGER:
   8120       mode = insn_data[(int) icode].operand[opno].mode;
   8121       if (mode != VOIDmode
   8122 	  && known_eq (trunc_int_for_mode (op->int_value, mode),
   8123 		       op->int_value))
   8124 	{
   8125 	  op->value = gen_int_mode (op->int_value, mode);
   8126 	  goto input;
   8127 	}
   8128       break;
   8129 
   8130     case EXPAND_UNDEFINED_INPUT:
   8131       /* See if the predicate accepts a SCRATCH rtx, which in this context
   8132 	 indicates an undefined value.  Use an uninitialized register if not. */
   8133       if (!insn_operand_matches (icode, opno, op->value))
   8134 	{
   8135 	  op->value = gen_reg_rtx (op->mode);
   8136 	  goto input;
   8137 	}
   8138       return true;
   8139     }
   8140   return insn_operand_matches (icode, opno, op->value);
   8141 }
   8142 
   8143 /* Make OP describe an input operand that should have the same value
   8144    as VALUE, after any mode conversion that the target might request.
   8145    TYPE is the type of VALUE.  */
   8146 
   8147 void
   8148 create_convert_operand_from_type (class expand_operand *op,
   8149 				  rtx value, tree type)
   8150 {
   8151   create_convert_operand_from (op, value, TYPE_MODE (type),
   8152 			       TYPE_UNSIGNED (type));
   8153 }
   8154 
   8155 /* Return true if the requirements on operands OP1 and OP2 of instruction
   8156    ICODE are similar enough for the result of legitimizing OP1 to be
   8157    reusable for OP2.  OPNO1 and OPNO2 are the operand numbers associated
   8158    with OP1 and OP2 respectively.  */
   8159 
   8160 static inline bool
   8161 can_reuse_operands_p (enum insn_code icode,
   8162 		      unsigned int opno1, unsigned int opno2,
   8163 		      const class expand_operand *op1,
   8164 		      const class expand_operand *op2)
   8165 {
   8166   /* Check requirements that are common to all types.  */
   8167   if (op1->type != op2->type
   8168       || op1->mode != op2->mode
   8169       || (insn_data[(int) icode].operand[opno1].mode
   8170 	  != insn_data[(int) icode].operand[opno2].mode))
   8171     return false;
   8172 
   8173   /* Check the requirements for specific types.  */
   8174   switch (op1->type)
   8175     {
   8176     case EXPAND_OUTPUT:
   8177     case EXPAND_UNDEFINED_INPUT:
   8178       /* Outputs and undefined intputs must remain distinct.  */
   8179       return false;
   8180 
   8181     case EXPAND_FIXED:
   8182     case EXPAND_INPUT:
   8183     case EXPAND_ADDRESS:
   8184     case EXPAND_INTEGER:
   8185       return true;
   8186 
   8187     case EXPAND_CONVERT_TO:
   8188     case EXPAND_CONVERT_FROM:
   8189       return op1->unsigned_p == op2->unsigned_p;
   8190     }
   8191   gcc_unreachable ();
   8192 }
   8193 
   8194 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
   8195    of instruction ICODE.  Return true on success, leaving the new operand
   8196    values in the OPS themselves.  Emit no code on failure.  */
   8197 
   8198 bool
   8199 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
   8200 			   unsigned int nops, class expand_operand *ops)
   8201 {
   8202   rtx_insn *last = get_last_insn ();
   8203   rtx *orig_values = XALLOCAVEC (rtx, nops);
   8204   for (unsigned int i = 0; i < nops; i++)
   8205     {
   8206       orig_values[i] = ops[i].value;
   8207 
   8208       /* First try reusing the result of an earlier legitimization.
   8209 	 This avoids duplicate rtl and ensures that tied operands
   8210 	 remain tied.
   8211 
   8212 	 This search is linear, but NOPS is bounded at compile time
   8213 	 to a small number (current a single digit).  */
   8214       unsigned int j = 0;
   8215       for (; j < i; ++j)
   8216 	if (can_reuse_operands_p (icode, opno + j, opno + i, &ops[j], &ops[i])
   8217 	    && rtx_equal_p (orig_values[j], orig_values[i])
   8218 	    && ops[j].value
   8219 	    && insn_operand_matches (icode, opno + i, ops[j].value))
   8220 	  {
   8221 	    ops[i].value = copy_rtx (ops[j].value);
   8222 	    break;
   8223 	  }
   8224 
   8225       /* Otherwise try legitimizing the operand on its own.  */
   8226       if (j == i && !maybe_legitimize_operand (icode, opno + i, &ops[i]))
   8227 	{
   8228 	  delete_insns_since (last);
   8229 	  return false;
   8230 	}
   8231     }
   8232   return true;
   8233 }
   8234 
   8235 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
   8236    as its operands.  Return the instruction pattern on success,
   8237    and emit any necessary set-up code.  Return null and emit no
   8238    code on failure.  */
   8239 
   8240 rtx_insn *
   8241 maybe_gen_insn (enum insn_code icode, unsigned int nops,
   8242 		class expand_operand *ops)
   8243 {
   8244   gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
   8245   if (!maybe_legitimize_operands (icode, 0, nops, ops))
   8246     return NULL;
   8247 
   8248   switch (nops)
   8249     {
   8250     case 0:
   8251       return GEN_FCN (icode) ();
   8252     case 1:
   8253       return GEN_FCN (icode) (ops[0].value);
   8254     case 2:
   8255       return GEN_FCN (icode) (ops[0].value, ops[1].value);
   8256     case 3:
   8257       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
   8258     case 4:
   8259       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8260 			      ops[3].value);
   8261     case 5:
   8262       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8263 			      ops[3].value, ops[4].value);
   8264     case 6:
   8265       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8266 			      ops[3].value, ops[4].value, ops[5].value);
   8267     case 7:
   8268       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8269 			      ops[3].value, ops[4].value, ops[5].value,
   8270 			      ops[6].value);
   8271     case 8:
   8272       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8273 			      ops[3].value, ops[4].value, ops[5].value,
   8274 			      ops[6].value, ops[7].value);
   8275     case 9:
   8276       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8277 			      ops[3].value, ops[4].value, ops[5].value,
   8278 			      ops[6].value, ops[7].value, ops[8].value);
   8279     case 10:
   8280       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8281 			      ops[3].value, ops[4].value, ops[5].value,
   8282 			      ops[6].value, ops[7].value, ops[8].value,
   8283 			      ops[9].value);
   8284     case 11:
   8285       return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
   8286 			      ops[3].value, ops[4].value, ops[5].value,
   8287 			      ops[6].value, ops[7].value, ops[8].value,
   8288 			      ops[9].value, ops[10].value);
   8289     }
   8290   gcc_unreachable ();
   8291 }
   8292 
   8293 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
   8294    as its operands.  Return true on success and emit no code on failure.  */
   8295 
   8296 bool
   8297 maybe_expand_insn (enum insn_code icode, unsigned int nops,
   8298 		   class expand_operand *ops)
   8299 {
   8300   rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
   8301   if (pat)
   8302     {
   8303       emit_insn (pat);
   8304       return true;
   8305     }
   8306   return false;
   8307 }
   8308 
   8309 /* Like maybe_expand_insn, but for jumps.  */
   8310 
   8311 bool
   8312 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
   8313 			class expand_operand *ops)
   8314 {
   8315   rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
   8316   if (pat)
   8317     {
   8318       emit_jump_insn (pat);
   8319       return true;
   8320     }
   8321   return false;
   8322 }
   8323 
   8324 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
   8325    as its operands.  */
   8326 
   8327 void
   8328 expand_insn (enum insn_code icode, unsigned int nops,
   8329 	     class expand_operand *ops)
   8330 {
   8331   if (!maybe_expand_insn (icode, nops, ops))
   8332     gcc_unreachable ();
   8333 }
   8334 
   8335 /* Like expand_insn, but for jumps.  */
   8336 
   8337 void
   8338 expand_jump_insn (enum insn_code icode, unsigned int nops,
   8339 		  class expand_operand *ops)
   8340 {
   8341   if (!maybe_expand_jump_insn (icode, nops, ops))
   8342     gcc_unreachable ();
   8343 }
   8344