OSDN Git Service

97319714fa5c8d57daedd1f835e83f0969b39648
[pf3gnuchains/gcc-fork.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "toplev.h"
28
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30    is properly defined.  */
31 #include "insn-config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tm_p.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "except.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "libfuncs.h"
41 #include "recog.h"
42 #include "reload.h"
43 #include "ggc.h"
44 #include "real.h"
45 #include "basic-block.h"
46 #include "target.h"
47
48 /* Each optab contains info on how this target machine
49    can perform a particular operation
50    for all sizes and kinds of operands.
51
52    The operation to be performed is often specified
53    by passing one of these optabs as an argument.
54
55    See expr.h for documentation of these optabs.  */
56
57 optab optab_table[OTI_MAX];
58
59 rtx libfunc_table[LTI_MAX];
60
61 /* Tables of patterns for converting one mode to another.  */
62 convert_optab convert_optab_table[COI_MAX];
63
64 /* Contains the optab used for each rtx code.  */
65 optab code_to_optab[NUM_RTX_CODE + 1];
66
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68    gives the gen_function to make a branch to test that condition.  */
69
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
71
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73    gives the insn code to make a store-condition insn
74    to test that condition.  */
75
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
77
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80    move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
81    setcc_gen_code to cut down on the number of named patterns.  Consider a day
82    when a lot more rtx codes are conditional (eg: for the ARM).  */
83
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
85 #endif
86
87 /* Indexed by the machine mode, gives the insn code for vector conditional
88    operation.  */
89
90 enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
91 enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
92
93 /* The insn generating function can not take an rtx_code argument.
94    TRAP_RTX is used as an rtx argument.  Its code is replaced with
95    the code to be used in the trap insn and all other fields are ignored.  */
96 static GTY(()) rtx trap_rtx;
97
98 static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
99 static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
100                           int);
101 static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
102                               enum machine_mode *, int *,
103                               enum can_compare_purpose);
104 static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
105                                  int *);
106 static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
107 static optab new_optab (void);
108 static convert_optab new_convert_optab (void);
109 static inline optab init_optab (enum rtx_code);
110 static inline optab init_optabv (enum rtx_code);
111 static inline convert_optab init_convert_optab (enum rtx_code);
112 static void init_libfuncs (optab, int, int, const char *, int);
113 static void init_integral_libfuncs (optab, const char *, int);
114 static void init_floating_libfuncs (optab, const char *, int);
115 static void init_interclass_conv_libfuncs (convert_optab, const char *,
116                                            enum mode_class, enum mode_class);
117 static void init_intraclass_conv_libfuncs (convert_optab, const char *,
118                                            enum mode_class, bool);
119 static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
120                                       enum rtx_code, int, rtx);
121 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
122                                    enum machine_mode *, int *);
123 static rtx widen_clz (enum machine_mode, rtx, rtx);
124 static rtx expand_parity (enum machine_mode, rtx, rtx);
125 static rtx expand_ffs (enum machine_mode, rtx, rtx);
126 static rtx expand_ctz (enum machine_mode, rtx, rtx);
127 static enum rtx_code get_rtx_code (enum tree_code, bool);
128 static rtx vector_compare_rtx (tree, bool, enum insn_code);
129
130 /* Current libcall id.  It doesn't matter what these are, as long
131    as they are unique to each libcall that is emitted.  */
132 static HOST_WIDE_INT libcall_id = 0;
133
134 #ifndef HAVE_conditional_trap
135 #define HAVE_conditional_trap 0
136 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
137 #endif
138
139 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
140 #if ENABLE_DECIMAL_BID_FORMAT
141 #define DECIMAL_PREFIX "bid_"
142 #else
143 #define DECIMAL_PREFIX "dpd_"
144 #endif
145
146 \f
147 /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
148    the result of operation CODE applied to OP0 (and OP1 if it is a binary
149    operation).
150
151    If the last insn does not set TARGET, don't do anything, but return 1.
152
153    If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
154    don't add the REG_EQUAL note but return 0.  Our caller can then try
155    again, ensuring that TARGET is not one of the operands.  */
156
157 static int
158 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
159 {
160   rtx last_insn, insn, set;
161   rtx note;
162
163   gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
164
165   if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
166       && GET_RTX_CLASS (code) != RTX_BIN_ARITH
167       && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
168       && GET_RTX_CLASS (code) != RTX_COMPARE
169       && GET_RTX_CLASS (code) != RTX_UNARY)
170     return 1;
171
172   if (GET_CODE (target) == ZERO_EXTRACT)
173     return 1;
174
175   for (last_insn = insns;
176        NEXT_INSN (last_insn) != NULL_RTX;
177        last_insn = NEXT_INSN (last_insn))
178     ;
179
180   set = single_set (last_insn);
181   if (set == NULL_RTX)
182     return 1;
183
184   if (! rtx_equal_p (SET_DEST (set), target)
185       /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
186       && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
187           || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
188     return 1;
189
190   /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
191      besides the last insn.  */
192   if (reg_overlap_mentioned_p (target, op0)
193       || (op1 && reg_overlap_mentioned_p (target, op1)))
194     {
195       insn = PREV_INSN (last_insn);
196       while (insn != NULL_RTX)
197         {
198           if (reg_set_p (target, insn))
199             return 0;
200
201           insn = PREV_INSN (insn);
202         }
203     }
204
205   if (GET_RTX_CLASS (code) == RTX_UNARY)
206     note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
207   else
208     note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
209
210   set_unique_reg_note (last_insn, REG_EQUAL, note);
211
212   return 1;
213 }
214 \f
215 /* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
216    says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
217    not actually do a sign-extend or zero-extend, but can leave the
218    higher-order bits of the result rtx undefined, for example, in the case
219    of logical operations, but not right shifts.  */
220
221 static rtx
222 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
223                int unsignedp, int no_extend)
224 {
225   rtx result;
226
227   /* If we don't have to extend and this is a constant, return it.  */
228   if (no_extend && GET_MODE (op) == VOIDmode)
229     return op;
230
231   /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
232      extend since it will be more efficient to do so unless the signedness of
233      a promoted object differs from our extension.  */
234   if (! no_extend
235       || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
236           && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
237     return convert_modes (mode, oldmode, op, unsignedp);
238
239   /* If MODE is no wider than a single word, we return a paradoxical
240      SUBREG.  */
241   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
242     return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
243
244   /* Otherwise, get an object of MODE, clobber it, and set the low-order
245      part to OP.  */
246
247   result = gen_reg_rtx (mode);
248   emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
249   emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
250   return result;
251 }
252 \f
253 /* Return the optab used for computing the operation given by
254    the tree code, CODE.  This function is not always usable (for
255    example, it cannot give complete results for multiplication
256    or division) but probably ought to be relied on more widely
257    throughout the expander.  */
258 optab
259 optab_for_tree_code (enum tree_code code, const_tree type)
260 {
261   bool trapv;
262   switch (code)
263     {
264     case BIT_AND_EXPR:
265       return and_optab;
266
267     case BIT_IOR_EXPR:
268       return ior_optab;
269
270     case BIT_NOT_EXPR:
271       return one_cmpl_optab;
272
273     case BIT_XOR_EXPR:
274       return xor_optab;
275
276     case TRUNC_MOD_EXPR:
277     case CEIL_MOD_EXPR:
278     case FLOOR_MOD_EXPR:
279     case ROUND_MOD_EXPR:
280       return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
281
282     case RDIV_EXPR:
283     case TRUNC_DIV_EXPR:
284     case CEIL_DIV_EXPR:
285     case FLOOR_DIV_EXPR:
286     case ROUND_DIV_EXPR:
287     case EXACT_DIV_EXPR:
288       return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
289
290     case LSHIFT_EXPR:
291       return ashl_optab;
292
293     case RSHIFT_EXPR:
294       return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
295
296     case LROTATE_EXPR:
297       return rotl_optab;
298
299     case RROTATE_EXPR:
300       return rotr_optab;
301
302     case MAX_EXPR:
303       return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
304
305     case MIN_EXPR:
306       return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
307
308     case REALIGN_LOAD_EXPR:
309       return vec_realign_load_optab;
310
311     case WIDEN_SUM_EXPR:
312       return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
313
314     case DOT_PROD_EXPR:
315       return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
316
317     case REDUC_MAX_EXPR:
318       return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
319
320     case REDUC_MIN_EXPR:
321       return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
322
323     case REDUC_PLUS_EXPR:
324       return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
325
326     case VEC_LSHIFT_EXPR:
327       return vec_shl_optab;
328
329     case VEC_RSHIFT_EXPR:
330       return vec_shr_optab;
331
332     case VEC_WIDEN_MULT_HI_EXPR:
333       return TYPE_UNSIGNED (type) ? 
334         vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
335
336     case VEC_WIDEN_MULT_LO_EXPR:
337       return TYPE_UNSIGNED (type) ? 
338         vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
339
340     case VEC_UNPACK_HI_EXPR:
341       return TYPE_UNSIGNED (type) ?
342         vec_unpacku_hi_optab : vec_unpacks_hi_optab;
343
344     case VEC_UNPACK_LO_EXPR:
345       return TYPE_UNSIGNED (type) ? 
346         vec_unpacku_lo_optab : vec_unpacks_lo_optab;
347
348     case VEC_UNPACK_FLOAT_HI_EXPR:
349       /* The signedness is determined from input operand.  */
350       return TYPE_UNSIGNED (type) ?
351         vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
352
353     case VEC_UNPACK_FLOAT_LO_EXPR:
354       /* The signedness is determined from input operand.  */
355       return TYPE_UNSIGNED (type) ? 
356         vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
357
358     case VEC_PACK_TRUNC_EXPR:
359       return vec_pack_trunc_optab;
360
361     case VEC_PACK_SAT_EXPR:
362       return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
363
364     case VEC_PACK_FIX_TRUNC_EXPR:
365       /* The signedness is determined from output operand.  */
366       return TYPE_UNSIGNED (type) ?
367         vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
368
369     default:
370       break;
371     }
372
373   trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
374   switch (code)
375     {
376     case POINTER_PLUS_EXPR:
377     case PLUS_EXPR:
378       return trapv ? addv_optab : add_optab;
379
380     case MINUS_EXPR:
381       return trapv ? subv_optab : sub_optab;
382
383     case MULT_EXPR:
384       return trapv ? smulv_optab : smul_optab;
385
386     case NEGATE_EXPR:
387       return trapv ? negv_optab : neg_optab;
388
389     case ABS_EXPR:
390       return trapv ? absv_optab : abs_optab;
391
392     case VEC_EXTRACT_EVEN_EXPR:
393       return vec_extract_even_optab;
394
395     case VEC_EXTRACT_ODD_EXPR:
396       return vec_extract_odd_optab;
397
398     case VEC_INTERLEAVE_HIGH_EXPR:
399       return vec_interleave_high_optab;
400
401     case VEC_INTERLEAVE_LOW_EXPR:
402       return vec_interleave_low_optab;
403
404     default:
405       return NULL;
406     }
407 }
408 \f
409
410 /* Expand vector widening operations.
411
412    There are two different classes of operations handled here:
413    1) Operations whose result is wider than all the arguments to the operation.
414       Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
415       In this case OP0 and optionally OP1 would be initialized,
416       but WIDE_OP wouldn't (not relevant for this case).
417    2) Operations whose result is of the same size as the last argument to the
418       operation, but wider than all the other arguments to the operation.
419       Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
420       In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
421
422    E.g, when called to expand the following operations, this is how
423    the arguments will be initialized:
424                                 nops    OP0     OP1     WIDE_OP
425    widening-sum                 2       oprnd0  -       oprnd1          
426    widening-dot-product         3       oprnd0  oprnd1  oprnd2
427    widening-mult                2       oprnd0  oprnd1  -
428    type-promotion (vec-unpack)  1       oprnd0  -       -  */
429
430 rtx
431 expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
432                            int unsignedp)
433 {   
434   tree oprnd0, oprnd1, oprnd2;
435   enum machine_mode wmode = 0, tmode0, tmode1 = 0;
436   optab widen_pattern_optab;
437   int icode; 
438   enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
439   rtx temp;
440   rtx pat;
441   rtx xop0, xop1, wxop;
442   int nops = TREE_OPERAND_LENGTH (exp);
443
444   oprnd0 = TREE_OPERAND (exp, 0);
445   tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
446   widen_pattern_optab =
447         optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
448   icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code;
449   gcc_assert (icode != CODE_FOR_nothing);
450   xmode0 = insn_data[icode].operand[1].mode;
451
452   if (nops >= 2)
453     {
454       oprnd1 = TREE_OPERAND (exp, 1);
455       tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
456       xmode1 = insn_data[icode].operand[2].mode;
457     }
458
459   /* The last operand is of a wider mode than the rest of the operands.  */
460   if (nops == 2)
461     {
462       wmode = tmode1;
463       wxmode = xmode1;
464     }
465   else if (nops == 3)
466     {
467       gcc_assert (tmode1 == tmode0);
468       gcc_assert (op1);
469       oprnd2 = TREE_OPERAND (exp, 2);
470       wmode = TYPE_MODE (TREE_TYPE (oprnd2));
471       wxmode = insn_data[icode].operand[3].mode;
472     }
473
474   if (!wide_op)
475     wmode = wxmode = insn_data[icode].operand[0].mode;
476
477   if (!target
478       || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
479     temp = gen_reg_rtx (wmode);
480   else
481     temp = target;
482
483   xop0 = op0;
484   xop1 = op1;
485   wxop = wide_op;
486
487   /* In case the insn wants input operands in modes different from
488      those of the actual operands, convert the operands.  It would
489      seem that we don't need to convert CONST_INTs, but we do, so
490      that they're properly zero-extended, sign-extended or truncated
491      for their mode.  */
492
493   if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
494     xop0 = convert_modes (xmode0,
495                           GET_MODE (op0) != VOIDmode
496                           ? GET_MODE (op0)
497                           : tmode0,
498                           xop0, unsignedp);
499
500   if (op1)
501     if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
502       xop1 = convert_modes (xmode1,
503                             GET_MODE (op1) != VOIDmode
504                             ? GET_MODE (op1)
505                             : tmode1,
506                             xop1, unsignedp);
507
508   if (wide_op)
509     if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
510       wxop = convert_modes (wxmode,
511                             GET_MODE (wide_op) != VOIDmode
512                             ? GET_MODE (wide_op)
513                             : wmode,
514                             wxop, unsignedp);
515
516   /* Now, if insn's predicates don't allow our operands, put them into
517      pseudo regs.  */
518
519   if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
520       && xmode0 != VOIDmode)
521     xop0 = copy_to_mode_reg (xmode0, xop0);
522
523   if (op1)
524     {
525       if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
526           && xmode1 != VOIDmode)
527         xop1 = copy_to_mode_reg (xmode1, xop1);
528
529       if (wide_op)
530         {
531           if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
532               && wxmode != VOIDmode)
533             wxop = copy_to_mode_reg (wxmode, wxop);
534
535           pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
536         }
537       else
538         pat = GEN_FCN (icode) (temp, xop0, xop1);
539     }
540   else
541     {
542       if (wide_op)
543         {
544           if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
545               && wxmode != VOIDmode)
546             wxop = copy_to_mode_reg (wxmode, wxop);
547
548           pat = GEN_FCN (icode) (temp, xop0, wxop);
549         }
550       else
551         pat = GEN_FCN (icode) (temp, xop0);
552     }
553
554   emit_insn (pat);
555   return temp;
556 }
557
558 /* Generate code to perform an operation specified by TERNARY_OPTAB
559    on operands OP0, OP1 and OP2, with result having machine-mode MODE.
560
561    UNSIGNEDP is for the case where we have to widen the operands
562    to perform the operation.  It says to use zero-extension.
563
564    If TARGET is nonzero, the value
565    is generated there, if it is convenient to do so.
566    In all cases an rtx is returned for the locus of the value;
567    this may or may not be TARGET.  */
568
569 rtx
570 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
571                    rtx op1, rtx op2, rtx target, int unsignedp)
572 {
573   int icode = (int) optab_handler (ternary_optab, mode)->insn_code;
574   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
575   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
576   enum machine_mode mode2 = insn_data[icode].operand[3].mode;
577   rtx temp;
578   rtx pat;
579   rtx xop0 = op0, xop1 = op1, xop2 = op2;
580
581   gcc_assert (optab_handler (ternary_optab, mode)->insn_code
582               != CODE_FOR_nothing);
583
584   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
585     temp = gen_reg_rtx (mode);
586   else
587     temp = target;
588
589   /* In case the insn wants input operands in modes different from
590      those of the actual operands, convert the operands.  It would
591      seem that we don't need to convert CONST_INTs, but we do, so
592      that they're properly zero-extended, sign-extended or truncated
593      for their mode.  */
594
595   if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
596     xop0 = convert_modes (mode0,
597                           GET_MODE (op0) != VOIDmode
598                           ? GET_MODE (op0)
599                           : mode,
600                           xop0, unsignedp);
601
602   if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
603     xop1 = convert_modes (mode1,
604                           GET_MODE (op1) != VOIDmode
605                           ? GET_MODE (op1)
606                           : mode,
607                           xop1, unsignedp);
608
609   if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
610     xop2 = convert_modes (mode2,
611                           GET_MODE (op2) != VOIDmode
612                           ? GET_MODE (op2)
613                           : mode,
614                           xop2, unsignedp);
615
616   /* Now, if insn's predicates don't allow our operands, put them into
617      pseudo regs.  */
618
619   if (!insn_data[icode].operand[1].predicate (xop0, mode0)
620       && mode0 != VOIDmode)
621     xop0 = copy_to_mode_reg (mode0, xop0);
622
623   if (!insn_data[icode].operand[2].predicate (xop1, mode1)
624       && mode1 != VOIDmode)
625     xop1 = copy_to_mode_reg (mode1, xop1);
626
627   if (!insn_data[icode].operand[3].predicate (xop2, mode2)
628       && mode2 != VOIDmode)
629     xop2 = copy_to_mode_reg (mode2, xop2);
630
631   pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
632
633   emit_insn (pat);
634   return temp;
635 }
636
637
638 /* Like expand_binop, but return a constant rtx if the result can be
639    calculated at compile time.  The arguments and return value are
640    otherwise the same as for expand_binop.  */
641
642 static rtx
643 simplify_expand_binop (enum machine_mode mode, optab binoptab,
644                        rtx op0, rtx op1, rtx target, int unsignedp,
645                        enum optab_methods methods)
646 {
647   if (CONSTANT_P (op0) && CONSTANT_P (op1))
648     {
649       rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
650
651       if (x)
652         return x;
653     }
654
655   return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
656 }
657
658 /* Like simplify_expand_binop, but always put the result in TARGET.
659    Return true if the expansion succeeded.  */
660
661 bool
662 force_expand_binop (enum machine_mode mode, optab binoptab,
663                     rtx op0, rtx op1, rtx target, int unsignedp,
664                     enum optab_methods methods)
665 {
666   rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
667                                  target, unsignedp, methods);
668   if (x == 0)
669     return false;
670   if (x != target)
671     emit_move_insn (target, x);
672   return true;
673 }
674
675 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR.  */
676
677 rtx
678 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
679 {
680   enum insn_code icode;
681   rtx rtx_op1, rtx_op2;
682   enum machine_mode mode1;
683   enum machine_mode mode2;
684   enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
685   tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
686   tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
687   optab shift_optab;
688   rtx pat;
689
690   switch (TREE_CODE (vec_shift_expr))
691     {
692       case VEC_RSHIFT_EXPR:
693         shift_optab = vec_shr_optab;
694         break;
695       case VEC_LSHIFT_EXPR:
696         shift_optab = vec_shl_optab;
697         break;
698       default:
699         gcc_unreachable ();
700     }
701
702   icode = (int) optab_handler (shift_optab, mode)->insn_code;
703   gcc_assert (icode != CODE_FOR_nothing);
704
705   mode1 = insn_data[icode].operand[1].mode;
706   mode2 = insn_data[icode].operand[2].mode;
707
708   rtx_op1 = expand_normal (vec_oprnd);
709   if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
710       && mode1 != VOIDmode)
711     rtx_op1 = force_reg (mode1, rtx_op1);
712
713   rtx_op2 = expand_normal (shift_oprnd);
714   if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
715       && mode2 != VOIDmode)
716     rtx_op2 = force_reg (mode2, rtx_op2);
717
718   if (!target
719       || ! (*insn_data[icode].operand[0].predicate) (target, mode))
720     target = gen_reg_rtx (mode);
721
722   /* Emit instruction */
723   pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
724   gcc_assert (pat);
725   emit_insn (pat);
726
727   return target;
728 }
729
730 /* This subroutine of expand_doubleword_shift handles the cases in which
731    the effective shift value is >= BITS_PER_WORD.  The arguments and return
732    value are the same as for the parent routine, except that SUPERWORD_OP1
733    is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
734    INTO_TARGET may be null if the caller has decided to calculate it.  */
735
736 static bool
737 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
738                         rtx outof_target, rtx into_target,
739                         int unsignedp, enum optab_methods methods)
740 {
741   if (into_target != 0)
742     if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
743                              into_target, unsignedp, methods))
744       return false;
745
746   if (outof_target != 0)
747     {
748       /* For a signed right shift, we must fill OUTOF_TARGET with copies
749          of the sign bit, otherwise we must fill it with zeros.  */
750       if (binoptab != ashr_optab)
751         emit_move_insn (outof_target, CONST0_RTX (word_mode));
752       else
753         if (!force_expand_binop (word_mode, binoptab,
754                                  outof_input, GEN_INT (BITS_PER_WORD - 1),
755                                  outof_target, unsignedp, methods))
756           return false;
757     }
758   return true;
759 }
760
761 /* This subroutine of expand_doubleword_shift handles the cases in which
762    the effective shift value is < BITS_PER_WORD.  The arguments and return
763    value are the same as for the parent routine.  */
764
765 static bool
766 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
767                       rtx outof_input, rtx into_input, rtx op1,
768                       rtx outof_target, rtx into_target,
769                       int unsignedp, enum optab_methods methods,
770                       unsigned HOST_WIDE_INT shift_mask)
771 {
772   optab reverse_unsigned_shift, unsigned_shift;
773   rtx tmp, carries;
774
775   reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
776   unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
777
778   /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
779      We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
780      the opposite direction to BINOPTAB.  */
781   if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
782     {
783       carries = outof_input;
784       tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
785       tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
786                                    0, true, methods);
787     }
788   else
789     {
790       /* We must avoid shifting by BITS_PER_WORD bits since that is either
791          the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
792          has unknown behavior.  Do a single shift first, then shift by the
793          remainder.  It's OK to use ~OP1 as the remainder if shift counts
794          are truncated to the mode size.  */
795       carries = expand_binop (word_mode, reverse_unsigned_shift,
796                               outof_input, const1_rtx, 0, unsignedp, methods);
797       if (shift_mask == BITS_PER_WORD - 1)
798         {
799           tmp = immed_double_const (-1, -1, op1_mode);
800           tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
801                                        0, true, methods);
802         }
803       else
804         {
805           tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
806           tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
807                                        0, true, methods);
808         }
809     }
810   if (tmp == 0 || carries == 0)
811     return false;
812   carries = expand_binop (word_mode, reverse_unsigned_shift,
813                           carries, tmp, 0, unsignedp, methods);
814   if (carries == 0)
815     return false;
816
817   /* Shift INTO_INPUT logically by OP1.  This is the last use of INTO_INPUT
818      so the result can go directly into INTO_TARGET if convenient.  */
819   tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
820                       into_target, unsignedp, methods);
821   if (tmp == 0)
822     return false;
823
824   /* Now OR in the bits carried over from OUTOF_INPUT.  */
825   if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
826                            into_target, unsignedp, methods))
827     return false;
828
829   /* Use a standard word_mode shift for the out-of half.  */
830   if (outof_target != 0)
831     if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
832                              outof_target, unsignedp, methods))
833       return false;
834
835   return true;
836 }
837
838
839 #ifdef HAVE_conditional_move
840 /* Try implementing expand_doubleword_shift using conditional moves.
841    The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
842    otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
843    are the shift counts to use in the former and latter case.  All other
844    arguments are the same as the parent routine.  */
845
846 static bool
847 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
848                                   enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
849                                   rtx outof_input, rtx into_input,
850                                   rtx subword_op1, rtx superword_op1,
851                                   rtx outof_target, rtx into_target,
852                                   int unsignedp, enum optab_methods methods,
853                                   unsigned HOST_WIDE_INT shift_mask)
854 {
855   rtx outof_superword, into_superword;
856
857   /* Put the superword version of the output into OUTOF_SUPERWORD and
858      INTO_SUPERWORD.  */
859   outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
860   if (outof_target != 0 && subword_op1 == superword_op1)
861     {
862       /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
863          OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
864       into_superword = outof_target;
865       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
866                                    outof_superword, 0, unsignedp, methods))
867         return false;
868     }
869   else
870     {
871       into_superword = gen_reg_rtx (word_mode);
872       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
873                                    outof_superword, into_superword,
874                                    unsignedp, methods))
875         return false;
876     }
877
878   /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
879   if (!expand_subword_shift (op1_mode, binoptab,
880                              outof_input, into_input, subword_op1,
881                              outof_target, into_target,
882                              unsignedp, methods, shift_mask))
883     return false;
884
885   /* Select between them.  Do the INTO half first because INTO_SUPERWORD
886      might be the current value of OUTOF_TARGET.  */
887   if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
888                               into_target, into_superword, word_mode, false))
889     return false;
890
891   if (outof_target != 0)
892     if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
893                                 outof_target, outof_superword,
894                                 word_mode, false))
895       return false;
896
897   return true;
898 }
899 #endif
900
901 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
902    OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
903    input operand; the shift moves bits in the direction OUTOF_INPUT->
904    INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
905    of the target.  OP1 is the shift count and OP1_MODE is its mode.
906    If OP1 is constant, it will have been truncated as appropriate
907    and is known to be nonzero.
908
909    If SHIFT_MASK is zero, the result of word shifts is undefined when the
910    shift count is outside the range [0, BITS_PER_WORD).  This routine must
911    avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
912
913    If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
914    masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
915    fill with zeros or sign bits as appropriate.
916
917    If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
918    a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
919    Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
920    In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
921    are undefined.
922
923    BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
924    may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
925    OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
926    function wants to calculate it itself.
927
928    Return true if the shift could be successfully synthesized.  */
929
930 static bool
931 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
932                          rtx outof_input, rtx into_input, rtx op1,
933                          rtx outof_target, rtx into_target,
934                          int unsignedp, enum optab_methods methods,
935                          unsigned HOST_WIDE_INT shift_mask)
936 {
937   rtx superword_op1, tmp, cmp1, cmp2;
938   rtx subword_label, done_label;
939   enum rtx_code cmp_code;
940
941   /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
942      fill the result with sign or zero bits as appropriate.  If so, the value
943      of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
944      this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
945      and INTO_INPUT), then emit code to set up OUTOF_TARGET.
946
947      This isn't worthwhile for constant shifts since the optimizers will
948      cope better with in-range shift counts.  */
949   if (shift_mask >= BITS_PER_WORD
950       && outof_target != 0
951       && !CONSTANT_P (op1))
952     {
953       if (!expand_doubleword_shift (op1_mode, binoptab,
954                                     outof_input, into_input, op1,
955                                     0, into_target,
956                                     unsignedp, methods, shift_mask))
957         return false;
958       if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
959                                outof_target, unsignedp, methods))
960         return false;
961       return true;
962     }
963
964   /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
965      is true when the effective shift value is less than BITS_PER_WORD.
966      Set SUPERWORD_OP1 to the shift count that should be used to shift
967      OUTOF_INPUT into INTO_TARGET when the condition is false.  */
968   tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
969   if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
970     {
971       /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
972          is a subword shift count.  */
973       cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
974                                     0, true, methods);
975       cmp2 = CONST0_RTX (op1_mode);
976       cmp_code = EQ;
977       superword_op1 = op1;
978     }
979   else
980     {
981       /* Set CMP1 to OP1 - BITS_PER_WORD.  */
982       cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
983                                     0, true, methods);
984       cmp2 = CONST0_RTX (op1_mode);
985       cmp_code = LT;
986       superword_op1 = cmp1;
987     }
988   if (cmp1 == 0)
989     return false;
990
991   /* If we can compute the condition at compile time, pick the
992      appropriate subroutine.  */
993   tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
994   if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
995     {
996       if (tmp == const0_rtx)
997         return expand_superword_shift (binoptab, outof_input, superword_op1,
998                                        outof_target, into_target,
999                                        unsignedp, methods);
1000       else
1001         return expand_subword_shift (op1_mode, binoptab,
1002                                      outof_input, into_input, op1,
1003                                      outof_target, into_target,
1004                                      unsignedp, methods, shift_mask);
1005     }
1006
1007 #ifdef HAVE_conditional_move
1008   /* Try using conditional moves to generate straight-line code.  */
1009   {
1010     rtx start = get_last_insn ();
1011     if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1012                                           cmp_code, cmp1, cmp2,
1013                                           outof_input, into_input,
1014                                           op1, superword_op1,
1015                                           outof_target, into_target,
1016                                           unsignedp, methods, shift_mask))
1017       return true;
1018     delete_insns_since (start);
1019   }
1020 #endif
1021
1022   /* As a last resort, use branches to select the correct alternative.  */
1023   subword_label = gen_label_rtx ();
1024   done_label = gen_label_rtx ();
1025
1026   NO_DEFER_POP;
1027   do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1028                            0, 0, subword_label);
1029   OK_DEFER_POP;
1030
1031   if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1032                                outof_target, into_target,
1033                                unsignedp, methods))
1034     return false;
1035
1036   emit_jump_insn (gen_jump (done_label));
1037   emit_barrier ();
1038   emit_label (subword_label);
1039
1040   if (!expand_subword_shift (op1_mode, binoptab,
1041                              outof_input, into_input, op1,
1042                              outof_target, into_target,
1043                              unsignedp, methods, shift_mask))
1044     return false;
1045
1046   emit_label (done_label);
1047   return true;
1048 }
1049 \f
1050 /* Subroutine of expand_binop.  Perform a double word multiplication of
1051    operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1052    as the target's word_mode.  This function return NULL_RTX if anything
1053    goes wrong, in which case it may have already emitted instructions
1054    which need to be deleted.
1055
1056    If we want to multiply two two-word values and have normal and widening
1057    multiplies of single-word values, we can do this with three smaller
1058    multiplications.  Note that we do not make a REG_NO_CONFLICT block here
1059    because we are not operating on one word at a time.
1060
1061    The multiplication proceeds as follows:
1062                                  _______________________
1063                                 [__op0_high_|__op0_low__]
1064                                  _______________________
1065         *                       [__op1_high_|__op1_low__]
1066         _______________________________________________
1067                                  _______________________
1068     (1)                         [__op0_low__*__op1_low__]
1069                      _______________________
1070     (2a)            [__op0_low__*__op1_high_]
1071                      _______________________
1072     (2b)            [__op0_high_*__op1_low__]
1073          _______________________
1074     (3) [__op0_high_*__op1_high_]
1075
1076
1077   This gives a 4-word result.  Since we are only interested in the
1078   lower 2 words, partial result (3) and the upper words of (2a) and
1079   (2b) don't need to be calculated.  Hence (2a) and (2b) can be
1080   calculated using non-widening multiplication.
1081
1082   (1), however, needs to be calculated with an unsigned widening
1083   multiplication.  If this operation is not directly supported we
1084   try using a signed widening multiplication and adjust the result.
1085   This adjustment works as follows:
1086
1087       If both operands are positive then no adjustment is needed.
1088
1089       If the operands have different signs, for example op0_low < 0 and
1090       op1_low >= 0, the instruction treats the most significant bit of
1091       op0_low as a sign bit instead of a bit with significance
1092       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1093       with 2**BITS_PER_WORD - op0_low, and two's complements the
1094       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1095       the result.
1096
1097       Similarly, if both operands are negative, we need to add
1098       (op0_low + op1_low) * 2**BITS_PER_WORD.
1099
1100       We use a trick to adjust quickly.  We logically shift op0_low right
1101       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1102       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
1103       logical shift exists, we do an arithmetic right shift and subtract
1104       the 0 or -1.  */
1105
1106 static rtx
1107 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1108                        bool umulp, enum optab_methods methods)
1109 {
1110   int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1111   int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1112   rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1113   rtx product, adjust, product_high, temp;
1114
1115   rtx op0_high = operand_subword_force (op0, high, mode);
1116   rtx op0_low = operand_subword_force (op0, low, mode);
1117   rtx op1_high = operand_subword_force (op1, high, mode);
1118   rtx op1_low = operand_subword_force (op1, low, mode);
1119
1120   /* If we're using an unsigned multiply to directly compute the product
1121      of the low-order words of the operands and perform any required
1122      adjustments of the operands, we begin by trying two more multiplications
1123      and then computing the appropriate sum.
1124
1125      We have checked above that the required addition is provided.
1126      Full-word addition will normally always succeed, especially if
1127      it is provided at all, so we don't worry about its failure.  The
1128      multiplication may well fail, however, so we do handle that.  */
1129
1130   if (!umulp)
1131     {
1132       /* ??? This could be done with emit_store_flag where available.  */
1133       temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1134                            NULL_RTX, 1, methods);
1135       if (temp)
1136         op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1137                                  NULL_RTX, 0, OPTAB_DIRECT);
1138       else
1139         {
1140           temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1141                                NULL_RTX, 0, methods);
1142           if (!temp)
1143             return NULL_RTX;
1144           op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1145                                    NULL_RTX, 0, OPTAB_DIRECT);
1146         }
1147
1148       if (!op0_high)
1149         return NULL_RTX;
1150     }
1151
1152   adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1153                          NULL_RTX, 0, OPTAB_DIRECT);
1154   if (!adjust)
1155     return NULL_RTX;
1156
1157   /* OP0_HIGH should now be dead.  */
1158
1159   if (!umulp)
1160     {
1161       /* ??? This could be done with emit_store_flag where available.  */
1162       temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1163                            NULL_RTX, 1, methods);
1164       if (temp)
1165         op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1166                                  NULL_RTX, 0, OPTAB_DIRECT);
1167       else
1168         {
1169           temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1170                                NULL_RTX, 0, methods);
1171           if (!temp)
1172             return NULL_RTX;
1173           op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1174                                    NULL_RTX, 0, OPTAB_DIRECT);
1175         }
1176
1177       if (!op1_high)
1178         return NULL_RTX;
1179     }
1180
1181   temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1182                        NULL_RTX, 0, OPTAB_DIRECT);
1183   if (!temp)
1184     return NULL_RTX;
1185
1186   /* OP1_HIGH should now be dead.  */
1187
1188   adjust = expand_binop (word_mode, add_optab, adjust, temp,
1189                          adjust, 0, OPTAB_DIRECT);
1190
1191   if (target && !REG_P (target))
1192     target = NULL_RTX;
1193
1194   if (umulp)
1195     product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1196                             target, 1, OPTAB_DIRECT);
1197   else
1198     product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1199                             target, 1, OPTAB_DIRECT);
1200
1201   if (!product)
1202     return NULL_RTX;
1203
1204   product_high = operand_subword (product, high, 1, mode);
1205   adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1206                          REG_P (product_high) ? product_high : adjust,
1207                          0, OPTAB_DIRECT);
1208   emit_move_insn (product_high, adjust);
1209   return product;
1210 }
1211 \f
1212 /* Wrapper around expand_binop which takes an rtx code to specify
1213    the operation to perform, not an optab pointer.  All other
1214    arguments are the same.  */
1215 rtx
1216 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1217                      rtx op1, rtx target, int unsignedp,
1218                      enum optab_methods methods)
1219 {
1220   optab binop = code_to_optab[(int) code];
1221   gcc_assert (binop);
1222
1223   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1224 }
1225
1226 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1227    binop.  Order them according to commutative_operand_precedence and, if
1228    possible, try to put TARGET or a pseudo first.  */
1229 static bool
1230 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1231 {
1232   int op0_prec = commutative_operand_precedence (op0);
1233   int op1_prec = commutative_operand_precedence (op1);
1234
1235   if (op0_prec < op1_prec)
1236     return true;
1237
1238   if (op0_prec > op1_prec)
1239     return false;
1240
1241   /* With equal precedence, both orders are ok, but it is better if the
1242      first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
1243   if (target == 0 || REG_P (target))
1244     return (REG_P (op1) && !REG_P (op0)) || target == op1;
1245   else
1246     return rtx_equal_p (op1, target);
1247 }
1248
1249 /* Return true if BINOPTAB implements a shift operation.  */
1250
1251 static bool
1252 shift_optab_p (optab binoptab)
1253 {
1254   switch (binoptab->code)
1255     {
1256     case ASHIFT:
1257     case ASHIFTRT:
1258     case LSHIFTRT:
1259     case ROTATE:
1260     case ROTATERT:
1261       return true;
1262
1263     default:
1264       return false;
1265     }
1266 }
1267
1268 /* Return true if BINOPTAB implements a commutatative binary operation.  */
1269
1270 static bool
1271 commutative_optab_p (optab binoptab)
1272 {
1273   return (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1274           || binoptab == smul_widen_optab
1275           || binoptab == umul_widen_optab
1276           || binoptab == smul_highpart_optab
1277           || binoptab == umul_highpart_optab);
1278 }
1279
1280 /* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
1281    optimizing, and if the operand is a constant that costs more than
1282    1 instruction, force the constant into a register and return that
1283    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
1284
1285 static rtx
1286 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1287                           rtx x, bool unsignedp)
1288 {
1289   if (optimize
1290       && CONSTANT_P (x)
1291       && rtx_cost (x, binoptab->code) > COSTS_N_INSNS (1))
1292     {
1293       if (GET_MODE (x) != VOIDmode)
1294         x = convert_modes (mode, VOIDmode, x, unsignedp);
1295       x = force_reg (mode, x);
1296     }
1297   return x;
1298 }
1299
1300 /* Helper function for expand_binop: handle the case where there
1301    is an insn that directly implements the indicated operation.
1302    Returns null if this is not possible.  */
1303 static rtx
1304 expand_binop_directly (enum machine_mode mode, optab binoptab,
1305                        rtx op0, rtx op1,
1306                        rtx target, int unsignedp, enum optab_methods methods,
1307                        rtx last)
1308 {
1309   int icode = (int) optab_handler (binoptab, mode)->insn_code;
1310   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1311   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1312   enum machine_mode tmp_mode;
1313   bool commutative_p;
1314   rtx pat;
1315   rtx xop0 = op0, xop1 = op1;
1316   rtx temp;
1317   rtx swap;
1318   
1319   if (target)
1320     temp = target;
1321   else
1322     temp = gen_reg_rtx (mode);
1323
1324   /* If it is a commutative operator and the modes would match
1325      if we would swap the operands, we can save the conversions.  */
1326   commutative_p = commutative_optab_p (binoptab);
1327   if (commutative_p
1328       && GET_MODE (xop0) != mode0 && GET_MODE (xop1) != mode1
1329       && GET_MODE (xop0) == mode1 && GET_MODE (xop1) == mode1)
1330     {
1331       swap = xop0;
1332       xop0 = xop1;
1333       xop1 = swap;
1334     }
1335   
1336   /* If we are optimizing, force expensive constants into a register.  */
1337   xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
1338   if (!shift_optab_p (binoptab))
1339     xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
1340
1341   /* In case the insn wants input operands in modes different from
1342      those of the actual operands, convert the operands.  It would
1343      seem that we don't need to convert CONST_INTs, but we do, so
1344      that they're properly zero-extended, sign-extended or truncated
1345      for their mode.  */
1346   
1347   if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode)
1348     xop0 = convert_modes (mode0,
1349                           GET_MODE (xop0) != VOIDmode
1350                           ? GET_MODE (xop0)
1351                           : mode,
1352                           xop0, unsignedp);
1353   
1354   if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode)
1355     xop1 = convert_modes (mode1,
1356                           GET_MODE (xop1) != VOIDmode
1357                           ? GET_MODE (xop1)
1358                           : mode,
1359                           xop1, unsignedp);
1360   
1361   /* If operation is commutative,
1362      try to make the first operand a register.
1363      Even better, try to make it the same as the target.
1364      Also try to make the last operand a constant.  */
1365   if (commutative_p
1366       && swap_commutative_operands_with_target (target, xop0, xop1))
1367     {
1368       swap = xop1;
1369       xop1 = xop0;
1370       xop0 = swap;
1371     }
1372
1373   /* Now, if insn's predicates don't allow our operands, put them into
1374      pseudo regs.  */
1375   
1376   if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1377       && mode0 != VOIDmode)
1378     xop0 = copy_to_mode_reg (mode0, xop0);
1379   
1380   if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1381       && mode1 != VOIDmode)
1382     xop1 = copy_to_mode_reg (mode1, xop1);
1383   
1384   if (binoptab == vec_pack_trunc_optab 
1385       || binoptab == vec_pack_usat_optab
1386       || binoptab == vec_pack_ssat_optab
1387       || binoptab == vec_pack_ufix_trunc_optab
1388       || binoptab == vec_pack_sfix_trunc_optab)
1389     {
1390       /* The mode of the result is different then the mode of the
1391          arguments.  */
1392       tmp_mode = insn_data[icode].operand[0].mode;
1393       if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1394         return 0;
1395     }
1396   else
1397     tmp_mode = mode;
1398
1399   if (!insn_data[icode].operand[0].predicate (temp, tmp_mode))
1400     temp = gen_reg_rtx (tmp_mode);
1401   
1402   pat = GEN_FCN (icode) (temp, xop0, xop1);
1403   if (pat)
1404     {
1405       /* If PAT is composed of more than one insn, try to add an appropriate
1406          REG_EQUAL note to it.  If we can't because TEMP conflicts with an
1407          operand, call expand_binop again, this time without a target.  */
1408       if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1409           && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1410         {
1411           delete_insns_since (last);
1412           return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1413                                unsignedp, methods);
1414         }
1415       
1416       emit_insn (pat);
1417       return temp;
1418     }
1419
1420   delete_insns_since (last);
1421   return NULL_RTX;
1422 }
1423
1424 /* Generate code to perform an operation specified by BINOPTAB
1425    on operands OP0 and OP1, with result having machine-mode MODE.
1426
1427    UNSIGNEDP is for the case where we have to widen the operands
1428    to perform the operation.  It says to use zero-extension.
1429
1430    If TARGET is nonzero, the value
1431    is generated there, if it is convenient to do so.
1432    In all cases an rtx is returned for the locus of the value;
1433    this may or may not be TARGET.  */
1434
1435 rtx
1436 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1437               rtx target, int unsignedp, enum optab_methods methods)
1438 {
1439   enum optab_methods next_methods
1440     = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1441        ? OPTAB_WIDEN : methods);
1442   enum mode_class class;
1443   enum machine_mode wider_mode;
1444   rtx temp;
1445   rtx entry_last = get_last_insn ();
1446   rtx last;
1447
1448   class = GET_MODE_CLASS (mode);
1449
1450   /* If subtracting an integer constant, convert this into an addition of
1451      the negated constant.  */
1452
1453   if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1454     {
1455       op1 = negate_rtx (mode, op1);
1456       binoptab = add_optab;
1457     }
1458
1459   /* Record where to delete back to if we backtrack.  */
1460   last = get_last_insn ();
1461
1462   /* If we can do it with a three-operand insn, do so.  */
1463
1464   if (methods != OPTAB_MUST_WIDEN
1465       && optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
1466     {
1467       temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1468                                     unsignedp, methods, last);
1469       if (temp)
1470         return temp;
1471     }
1472
1473   /* If we were trying to rotate, and that didn't work, try rotating
1474      the other direction before falling back to shifts and bitwise-or.  */
1475   if (((binoptab == rotl_optab
1476         && optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing)
1477        || (binoptab == rotr_optab
1478            && optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing))
1479       && class == MODE_INT)
1480     {
1481       optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1482       rtx newop1;
1483       unsigned int bits = GET_MODE_BITSIZE (mode);
1484
1485       if (GET_CODE (op1) == CONST_INT)
1486         newop1 = GEN_INT (bits - INTVAL (op1));
1487       else if (targetm.shift_truncation_mask (mode) == bits - 1)
1488         newop1 = negate_rtx (mode, op1);
1489       else
1490         newop1 = expand_binop (mode, sub_optab,
1491                                GEN_INT (bits), op1,
1492                                NULL_RTX, unsignedp, OPTAB_DIRECT);
1493                                    
1494       temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1495                                     target, unsignedp, methods, last);
1496       if (temp)
1497         return temp;
1498     }
1499
1500   /* If this is a multiply, see if we can do a widening operation that
1501      takes operands of this mode and makes a wider mode.  */
1502
1503   if (binoptab == smul_optab
1504       && GET_MODE_WIDER_MODE (mode) != VOIDmode
1505       && ((optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),
1506                           GET_MODE_WIDER_MODE (mode))->insn_code)
1507           != CODE_FOR_nothing))
1508     {
1509       temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1510                            unsignedp ? umul_widen_optab : smul_widen_optab,
1511                            op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1512
1513       if (temp != 0)
1514         {
1515           if (GET_MODE_CLASS (mode) == MODE_INT
1516               && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1517                                         GET_MODE_BITSIZE (GET_MODE (temp))))
1518             return gen_lowpart (mode, temp);
1519           else
1520             return convert_to_mode (mode, temp, unsignedp);
1521         }
1522     }
1523
1524   /* Look for a wider mode of the same class for which we think we
1525      can open-code the operation.  Check for a widening multiply at the
1526      wider mode as well.  */
1527
1528   if (CLASS_HAS_WIDER_MODES_P (class)
1529       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1530     for (wider_mode = GET_MODE_WIDER_MODE (mode);
1531          wider_mode != VOIDmode;
1532          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1533       {
1534         if (optab_handler (binoptab, wider_mode)->insn_code != CODE_FOR_nothing
1535             || (binoptab == smul_optab
1536                 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1537                 && ((optab_handler ((unsignedp ? umul_widen_optab
1538                                      : smul_widen_optab),
1539                                      GET_MODE_WIDER_MODE (wider_mode))->insn_code)
1540                     != CODE_FOR_nothing)))
1541           {
1542             rtx xop0 = op0, xop1 = op1;
1543             int no_extend = 0;
1544
1545             /* For certain integer operations, we need not actually extend
1546                the narrow operands, as long as we will truncate
1547                the results to the same narrowness.  */
1548
1549             if ((binoptab == ior_optab || binoptab == and_optab
1550                  || binoptab == xor_optab
1551                  || binoptab == add_optab || binoptab == sub_optab
1552                  || binoptab == smul_optab || binoptab == ashl_optab)
1553                 && class == MODE_INT)
1554               {
1555                 no_extend = 1;
1556                 xop0 = avoid_expensive_constant (mode, binoptab,
1557                                                  xop0, unsignedp);
1558                 if (binoptab != ashl_optab)
1559                   xop1 = avoid_expensive_constant (mode, binoptab,
1560                                                    xop1, unsignedp);
1561               }
1562
1563             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1564
1565             /* The second operand of a shift must always be extended.  */
1566             xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1567                                   no_extend && binoptab != ashl_optab);
1568
1569             temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1570                                  unsignedp, OPTAB_DIRECT);
1571             if (temp)
1572               {
1573                 if (class != MODE_INT
1574                     || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1575                                                GET_MODE_BITSIZE (wider_mode)))
1576                   {
1577                     if (target == 0)
1578                       target = gen_reg_rtx (mode);
1579                     convert_move (target, temp, 0);
1580                     return target;
1581                   }
1582                 else
1583                   return gen_lowpart (mode, temp);
1584               }
1585             else
1586               delete_insns_since (last);
1587           }
1588       }
1589
1590   /* If operation is commutative,
1591      try to make the first operand a register.
1592      Even better, try to make it the same as the target.
1593      Also try to make the last operand a constant.  */
1594   if (commutative_optab_p (binoptab)
1595       && swap_commutative_operands_with_target (target, op0, op1))
1596     {
1597       temp = op1;
1598       op1 = op0;
1599       op0 = temp;
1600     }
1601
1602   /* These can be done a word at a time.  */
1603   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1604       && class == MODE_INT
1605       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1606       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1607     {
1608       int i;
1609       rtx insns;
1610       rtx equiv_value;
1611
1612       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1613          won't be accurate, so use a new target.  */
1614       if (target == 0 || target == op0 || target == op1)
1615         target = gen_reg_rtx (mode);
1616
1617       start_sequence ();
1618
1619       /* Do the actual arithmetic.  */
1620       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1621         {
1622           rtx target_piece = operand_subword (target, i, 1, mode);
1623           rtx x = expand_binop (word_mode, binoptab,
1624                                 operand_subword_force (op0, i, mode),
1625                                 operand_subword_force (op1, i, mode),
1626                                 target_piece, unsignedp, next_methods);
1627
1628           if (x == 0)
1629             break;
1630
1631           if (target_piece != x)
1632             emit_move_insn (target_piece, x);
1633         }
1634
1635       insns = get_insns ();
1636       end_sequence ();
1637
1638       if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1639         {
1640           if (binoptab->code != UNKNOWN)
1641             equiv_value
1642               = gen_rtx_fmt_ee (binoptab->code, mode,
1643                                 copy_rtx (op0), copy_rtx (op1));
1644           else
1645             equiv_value = 0;
1646
1647           emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1648           return target;
1649         }
1650     }
1651
1652   /* Synthesize double word shifts from single word shifts.  */
1653   if ((binoptab == lshr_optab || binoptab == ashl_optab
1654        || binoptab == ashr_optab)
1655       && class == MODE_INT
1656       && (GET_CODE (op1) == CONST_INT || !optimize_size)
1657       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1658       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing
1659       && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1660       && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1661     {
1662       unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1663       enum machine_mode op1_mode;
1664
1665       double_shift_mask = targetm.shift_truncation_mask (mode);
1666       shift_mask = targetm.shift_truncation_mask (word_mode);
1667       op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1668
1669       /* Apply the truncation to constant shifts.  */
1670       if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1671         op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1672
1673       if (op1 == CONST0_RTX (op1_mode))
1674         return op0;
1675
1676       /* Make sure that this is a combination that expand_doubleword_shift
1677          can handle.  See the comments there for details.  */
1678       if (double_shift_mask == 0
1679           || (shift_mask == BITS_PER_WORD - 1
1680               && double_shift_mask == BITS_PER_WORD * 2 - 1))
1681         {
1682           rtx insns, equiv_value;
1683           rtx into_target, outof_target;
1684           rtx into_input, outof_input;
1685           int left_shift, outof_word;
1686
1687           /* If TARGET is the same as one of the operands, the REG_EQUAL note
1688              won't be accurate, so use a new target.  */
1689           if (target == 0 || target == op0 || target == op1)
1690             target = gen_reg_rtx (mode);
1691
1692           start_sequence ();
1693
1694           /* OUTOF_* is the word we are shifting bits away from, and
1695              INTO_* is the word that we are shifting bits towards, thus
1696              they differ depending on the direction of the shift and
1697              WORDS_BIG_ENDIAN.  */
1698
1699           left_shift = binoptab == ashl_optab;
1700           outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1701
1702           outof_target = operand_subword (target, outof_word, 1, mode);
1703           into_target = operand_subword (target, 1 - outof_word, 1, mode);
1704
1705           outof_input = operand_subword_force (op0, outof_word, mode);
1706           into_input = operand_subword_force (op0, 1 - outof_word, mode);
1707
1708           if (expand_doubleword_shift (op1_mode, binoptab,
1709                                        outof_input, into_input, op1,
1710                                        outof_target, into_target,
1711                                        unsignedp, next_methods, shift_mask))
1712             {
1713               insns = get_insns ();
1714               end_sequence ();
1715
1716               equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1717               emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1718               return target;
1719             }
1720           end_sequence ();
1721         }
1722     }
1723
1724   /* Synthesize double word rotates from single word shifts.  */
1725   if ((binoptab == rotl_optab || binoptab == rotr_optab)
1726       && class == MODE_INT
1727       && GET_CODE (op1) == CONST_INT
1728       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1729       && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1730       && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1731     {
1732       rtx insns;
1733       rtx into_target, outof_target;
1734       rtx into_input, outof_input;
1735       rtx inter;
1736       int shift_count, left_shift, outof_word;
1737
1738       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1739          won't be accurate, so use a new target. Do this also if target is not
1740          a REG, first because having a register instead may open optimization
1741          opportunities, and second because if target and op0 happen to be MEMs
1742          designating the same location, we would risk clobbering it too early
1743          in the code sequence we generate below.  */
1744       if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1745         target = gen_reg_rtx (mode);
1746
1747       start_sequence ();
1748
1749       shift_count = INTVAL (op1);
1750
1751       /* OUTOF_* is the word we are shifting bits away from, and
1752          INTO_* is the word that we are shifting bits towards, thus
1753          they differ depending on the direction of the shift and
1754          WORDS_BIG_ENDIAN.  */
1755
1756       left_shift = (binoptab == rotl_optab);
1757       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1758
1759       outof_target = operand_subword (target, outof_word, 1, mode);
1760       into_target = operand_subword (target, 1 - outof_word, 1, mode);
1761
1762       outof_input = operand_subword_force (op0, outof_word, mode);
1763       into_input = operand_subword_force (op0, 1 - outof_word, mode);
1764
1765       if (shift_count == BITS_PER_WORD)
1766         {
1767           /* This is just a word swap.  */
1768           emit_move_insn (outof_target, into_input);
1769           emit_move_insn (into_target, outof_input);
1770           inter = const0_rtx;
1771         }
1772       else
1773         {
1774           rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1775           rtx first_shift_count, second_shift_count;
1776           optab reverse_unsigned_shift, unsigned_shift;
1777
1778           reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1779                                     ? lshr_optab : ashl_optab);
1780
1781           unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1782                             ? ashl_optab : lshr_optab);
1783
1784           if (shift_count > BITS_PER_WORD)
1785             {
1786               first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1787               second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1788             }
1789           else
1790             {
1791               first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1792               second_shift_count = GEN_INT (shift_count);
1793             }
1794
1795           into_temp1 = expand_binop (word_mode, unsigned_shift,
1796                                      outof_input, first_shift_count,
1797                                      NULL_RTX, unsignedp, next_methods);
1798           into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1799                                      into_input, second_shift_count,
1800                                      NULL_RTX, unsignedp, next_methods);
1801
1802           if (into_temp1 != 0 && into_temp2 != 0)
1803             inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1804                                   into_target, unsignedp, next_methods);
1805           else
1806             inter = 0;
1807
1808           if (inter != 0 && inter != into_target)
1809             emit_move_insn (into_target, inter);
1810
1811           outof_temp1 = expand_binop (word_mode, unsigned_shift,
1812                                       into_input, first_shift_count,
1813                                       NULL_RTX, unsignedp, next_methods);
1814           outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1815                                       outof_input, second_shift_count,
1816                                       NULL_RTX, unsignedp, next_methods);
1817
1818           if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1819             inter = expand_binop (word_mode, ior_optab,
1820                                   outof_temp1, outof_temp2,
1821                                   outof_target, unsignedp, next_methods);
1822
1823           if (inter != 0 && inter != outof_target)
1824             emit_move_insn (outof_target, inter);
1825         }
1826
1827       insns = get_insns ();
1828       end_sequence ();
1829
1830       if (inter != 0)
1831         {
1832           /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1833              block to help the register allocator a bit.  But a multi-word
1834              rotate will need all the input bits when setting the output
1835              bits, so there clearly is a conflict between the input and
1836              output registers.  So we can't use a no-conflict block here.  */
1837           emit_insn (insns);
1838           return target;
1839         }
1840     }
1841
1842   /* These can be done a word at a time by propagating carries.  */
1843   if ((binoptab == add_optab || binoptab == sub_optab)
1844       && class == MODE_INT
1845       && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1846       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1847     {
1848       unsigned int i;
1849       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1850       const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1851       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1852       rtx xop0, xop1, xtarget;
1853
1854       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1855          value is one of those, use it.  Otherwise, use 1 since it is the
1856          one easiest to get.  */
1857 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1858       int normalizep = STORE_FLAG_VALUE;
1859 #else
1860       int normalizep = 1;
1861 #endif
1862
1863       /* Prepare the operands.  */
1864       xop0 = force_reg (mode, op0);
1865       xop1 = force_reg (mode, op1);
1866
1867       xtarget = gen_reg_rtx (mode);
1868
1869       if (target == 0 || !REG_P (target))
1870         target = xtarget;
1871
1872       /* Indicate for flow that the entire target reg is being set.  */
1873       if (REG_P (target))
1874         emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1875
1876       /* Do the actual arithmetic.  */
1877       for (i = 0; i < nwords; i++)
1878         {
1879           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1880           rtx target_piece = operand_subword (xtarget, index, 1, mode);
1881           rtx op0_piece = operand_subword_force (xop0, index, mode);
1882           rtx op1_piece = operand_subword_force (xop1, index, mode);
1883           rtx x;
1884
1885           /* Main add/subtract of the input operands.  */
1886           x = expand_binop (word_mode, binoptab,
1887                             op0_piece, op1_piece,
1888                             target_piece, unsignedp, next_methods);
1889           if (x == 0)
1890             break;
1891
1892           if (i + 1 < nwords)
1893             {
1894               /* Store carry from main add/subtract.  */
1895               carry_out = gen_reg_rtx (word_mode);
1896               carry_out = emit_store_flag_force (carry_out,
1897                                                  (binoptab == add_optab
1898                                                   ? LT : GT),
1899                                                  x, op0_piece,
1900                                                  word_mode, 1, normalizep);
1901             }
1902
1903           if (i > 0)
1904             {
1905               rtx newx;
1906
1907               /* Add/subtract previous carry to main result.  */
1908               newx = expand_binop (word_mode,
1909                                    normalizep == 1 ? binoptab : otheroptab,
1910                                    x, carry_in,
1911                                    NULL_RTX, 1, next_methods);
1912
1913               if (i + 1 < nwords)
1914                 {
1915                   /* Get out carry from adding/subtracting carry in.  */
1916                   rtx carry_tmp = gen_reg_rtx (word_mode);
1917                   carry_tmp = emit_store_flag_force (carry_tmp,
1918                                                      (binoptab == add_optab
1919                                                       ? LT : GT),
1920                                                      newx, x,
1921                                                      word_mode, 1, normalizep);
1922
1923                   /* Logical-ior the two poss. carry together.  */
1924                   carry_out = expand_binop (word_mode, ior_optab,
1925                                             carry_out, carry_tmp,
1926                                             carry_out, 0, next_methods);
1927                   if (carry_out == 0)
1928                     break;
1929                 }
1930               emit_move_insn (target_piece, newx);
1931             }
1932           else
1933             {
1934               if (x != target_piece)
1935                 emit_move_insn (target_piece, x);
1936             }
1937
1938           carry_in = carry_out;
1939         }
1940
1941       if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1942         {
1943           if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing
1944               || ! rtx_equal_p (target, xtarget))
1945             {
1946               rtx temp = emit_move_insn (target, xtarget);
1947
1948               set_unique_reg_note (temp,
1949                                    REG_EQUAL,
1950                                    gen_rtx_fmt_ee (binoptab->code, mode,
1951                                                    copy_rtx (xop0),
1952                                                    copy_rtx (xop1)));
1953             }
1954           else
1955             target = xtarget;
1956
1957           return target;
1958         }
1959
1960       else
1961         delete_insns_since (last);
1962     }
1963
1964   /* Attempt to synthesize double word multiplies using a sequence of word
1965      mode multiplications.  We first attempt to generate a sequence using a
1966      more efficient unsigned widening multiply, and if that fails we then
1967      try using a signed widening multiply.  */
1968
1969   if (binoptab == smul_optab
1970       && class == MODE_INT
1971       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1972       && optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing
1973       && optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing)
1974     {
1975       rtx product = NULL_RTX;
1976
1977       if (optab_handler (umul_widen_optab, mode)->insn_code
1978           != CODE_FOR_nothing)
1979         {
1980           product = expand_doubleword_mult (mode, op0, op1, target,
1981                                             true, methods);
1982           if (!product)
1983             delete_insns_since (last);
1984         }
1985
1986       if (product == NULL_RTX
1987           && optab_handler (smul_widen_optab, mode)->insn_code
1988              != CODE_FOR_nothing)
1989         {
1990           product = expand_doubleword_mult (mode, op0, op1, target,
1991                                             false, methods);
1992           if (!product)
1993             delete_insns_since (last);
1994         }
1995
1996       if (product != NULL_RTX)
1997         {
1998           if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing)
1999             {
2000               temp = emit_move_insn (target ? target : product, product);
2001               set_unique_reg_note (temp,
2002                                    REG_EQUAL,
2003                                    gen_rtx_fmt_ee (MULT, mode,
2004                                                    copy_rtx (op0),
2005                                                    copy_rtx (op1)));
2006             }
2007           return product;
2008         }
2009     }
2010
2011   /* It can't be open-coded in this mode.
2012      Use a library call if one is available and caller says that's ok.  */
2013
2014   if (optab_handler (binoptab, mode)->libfunc
2015       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2016     {
2017       rtx insns;
2018       rtx op1x = op1;
2019       enum machine_mode op1_mode = mode;
2020       rtx value;
2021
2022       start_sequence ();
2023
2024       if (shift_optab_p (binoptab))
2025         {
2026           op1_mode = targetm.libgcc_shift_count_mode ();
2027           /* Specify unsigned here,
2028              since negative shift counts are meaningless.  */
2029           op1x = convert_to_mode (op1_mode, op1, 1);
2030         }
2031
2032       if (GET_MODE (op0) != VOIDmode
2033           && GET_MODE (op0) != mode)
2034         op0 = convert_to_mode (mode, op0, unsignedp);
2035
2036       /* Pass 1 for NO_QUEUE so we don't lose any increments
2037          if the libcall is cse'd or moved.  */
2038       value = emit_library_call_value (optab_handler (binoptab, mode)->libfunc,
2039                                        NULL_RTX, LCT_CONST, mode, 2,
2040                                        op0, mode, op1x, op1_mode);
2041
2042       insns = get_insns ();
2043       end_sequence ();
2044
2045       target = gen_reg_rtx (mode);
2046       emit_libcall_block (insns, target, value,
2047                           gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
2048
2049       return target;
2050     }
2051
2052   delete_insns_since (last);
2053
2054   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2055
2056   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2057          || methods == OPTAB_MUST_WIDEN))
2058     {
2059       /* Caller says, don't even try.  */
2060       delete_insns_since (entry_last);
2061       return 0;
2062     }
2063
2064   /* Compute the value of METHODS to pass to recursive calls.
2065      Don't allow widening to be tried recursively.  */
2066
2067   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2068
2069   /* Look for a wider mode of the same class for which it appears we can do
2070      the operation.  */
2071
2072   if (CLASS_HAS_WIDER_MODES_P (class))
2073     {
2074       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2075            wider_mode != VOIDmode;
2076            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2077         {
2078           if ((optab_handler (binoptab, wider_mode)->insn_code
2079                != CODE_FOR_nothing)
2080               || (methods == OPTAB_LIB
2081                   && optab_handler (binoptab, wider_mode)->libfunc))
2082             {
2083               rtx xop0 = op0, xop1 = op1;
2084               int no_extend = 0;
2085
2086               /* For certain integer operations, we need not actually extend
2087                  the narrow operands, as long as we will truncate
2088                  the results to the same narrowness.  */
2089
2090               if ((binoptab == ior_optab || binoptab == and_optab
2091                    || binoptab == xor_optab
2092                    || binoptab == add_optab || binoptab == sub_optab
2093                    || binoptab == smul_optab || binoptab == ashl_optab)
2094                   && class == MODE_INT)
2095                 no_extend = 1;
2096
2097               xop0 = widen_operand (xop0, wider_mode, mode,
2098                                     unsignedp, no_extend);
2099
2100               /* The second operand of a shift must always be extended.  */
2101               xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2102                                     no_extend && binoptab != ashl_optab);
2103
2104               temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2105                                    unsignedp, methods);
2106               if (temp)
2107                 {
2108                   if (class != MODE_INT
2109                       || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2110                                                  GET_MODE_BITSIZE (wider_mode)))
2111                     {
2112                       if (target == 0)
2113                         target = gen_reg_rtx (mode);
2114                       convert_move (target, temp, 0);
2115                       return target;
2116                     }
2117                   else
2118                     return gen_lowpart (mode, temp);
2119                 }
2120               else
2121                 delete_insns_since (last);
2122             }
2123         }
2124     }
2125
2126   delete_insns_since (entry_last);
2127   return 0;
2128 }
2129 \f
2130 /* Expand a binary operator which has both signed and unsigned forms.
2131    UOPTAB is the optab for unsigned operations, and SOPTAB is for
2132    signed operations.
2133
2134    If we widen unsigned operands, we may use a signed wider operation instead
2135    of an unsigned wider operation, since the result would be the same.  */
2136
2137 rtx
2138 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2139                    rtx op0, rtx op1, rtx target, int unsignedp,
2140                    enum optab_methods methods)
2141 {
2142   rtx temp;
2143   optab direct_optab = unsignedp ? uoptab : soptab;
2144   struct optab wide_soptab;
2145
2146   /* Do it without widening, if possible.  */
2147   temp = expand_binop (mode, direct_optab, op0, op1, target,
2148                        unsignedp, OPTAB_DIRECT);
2149   if (temp || methods == OPTAB_DIRECT)
2150     return temp;
2151
2152   /* Try widening to a signed int.  Make a fake signed optab that
2153      hides any signed insn for direct use.  */
2154   wide_soptab = *soptab;
2155   optab_handler (&wide_soptab, mode)->insn_code = CODE_FOR_nothing;
2156   optab_handler (&wide_soptab, mode)->libfunc = 0;
2157
2158   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2159                        unsignedp, OPTAB_WIDEN);
2160
2161   /* For unsigned operands, try widening to an unsigned int.  */
2162   if (temp == 0 && unsignedp)
2163     temp = expand_binop (mode, uoptab, op0, op1, target,
2164                          unsignedp, OPTAB_WIDEN);
2165   if (temp || methods == OPTAB_WIDEN)
2166     return temp;
2167
2168   /* Use the right width lib call if that exists.  */
2169   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2170   if (temp || methods == OPTAB_LIB)
2171     return temp;
2172
2173   /* Must widen and use a lib call, use either signed or unsigned.  */
2174   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2175                        unsignedp, methods);
2176   if (temp != 0)
2177     return temp;
2178   if (unsignedp)
2179     return expand_binop (mode, uoptab, op0, op1, target,
2180                          unsignedp, methods);
2181   return 0;
2182 }
2183 \f
2184 /* Generate code to perform an operation specified by UNOPPTAB
2185    on operand OP0, with two results to TARG0 and TARG1.
2186    We assume that the order of the operands for the instruction
2187    is TARG0, TARG1, OP0.
2188
2189    Either TARG0 or TARG1 may be zero, but what that means is that
2190    the result is not actually wanted.  We will generate it into
2191    a dummy pseudo-reg and discard it.  They may not both be zero.
2192
2193    Returns 1 if this operation can be performed; 0 if not.  */
2194
2195 int
2196 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2197                     int unsignedp)
2198 {
2199   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2200   enum mode_class class;
2201   enum machine_mode wider_mode;
2202   rtx entry_last = get_last_insn ();
2203   rtx last;
2204
2205   class = GET_MODE_CLASS (mode);
2206
2207   if (!targ0)
2208     targ0 = gen_reg_rtx (mode);
2209   if (!targ1)
2210     targ1 = gen_reg_rtx (mode);
2211
2212   /* Record where to go back to if we fail.  */
2213   last = get_last_insn ();
2214
2215   if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2216     {
2217       int icode = (int) optab_handler (unoptab, mode)->insn_code;
2218       enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2219       rtx pat;
2220       rtx xop0 = op0;
2221
2222       if (GET_MODE (xop0) != VOIDmode
2223           && GET_MODE (xop0) != mode0)
2224         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2225
2226       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2227       if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2228         xop0 = copy_to_mode_reg (mode0, xop0);
2229
2230       /* We could handle this, but we should always be called with a pseudo
2231          for our targets and all insns should take them as outputs.  */
2232       gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2233       gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2234
2235       pat = GEN_FCN (icode) (targ0, targ1, xop0);
2236       if (pat)
2237         {
2238           emit_insn (pat);
2239           return 1;
2240         }
2241       else
2242         delete_insns_since (last);
2243     }
2244
2245   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2246
2247   if (CLASS_HAS_WIDER_MODES_P (class))
2248     {
2249       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2250            wider_mode != VOIDmode;
2251            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2252         {
2253           if (optab_handler (unoptab, wider_mode)->insn_code
2254               != CODE_FOR_nothing)
2255             {
2256               rtx t0 = gen_reg_rtx (wider_mode);
2257               rtx t1 = gen_reg_rtx (wider_mode);
2258               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2259
2260               if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2261                 {
2262                   convert_move (targ0, t0, unsignedp);
2263                   convert_move (targ1, t1, unsignedp);
2264                   return 1;
2265                 }
2266               else
2267                 delete_insns_since (last);
2268             }
2269         }
2270     }
2271
2272   delete_insns_since (entry_last);
2273   return 0;
2274 }
2275 \f
2276 /* Generate code to perform an operation specified by BINOPTAB
2277    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2278    We assume that the order of the operands for the instruction
2279    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2280    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2281
2282    Either TARG0 or TARG1 may be zero, but what that means is that
2283    the result is not actually wanted.  We will generate it into
2284    a dummy pseudo-reg and discard it.  They may not both be zero.
2285
2286    Returns 1 if this operation can be performed; 0 if not.  */
2287
2288 int
2289 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2290                      int unsignedp)
2291 {
2292   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2293   enum mode_class class;
2294   enum machine_mode wider_mode;
2295   rtx entry_last = get_last_insn ();
2296   rtx last;
2297
2298   class = GET_MODE_CLASS (mode);
2299
2300   if (!targ0)
2301     targ0 = gen_reg_rtx (mode);
2302   if (!targ1)
2303     targ1 = gen_reg_rtx (mode);
2304
2305   /* Record where to go back to if we fail.  */
2306   last = get_last_insn ();
2307
2308   if (optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
2309     {
2310       int icode = (int) optab_handler (binoptab, mode)->insn_code;
2311       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2312       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2313       rtx pat;
2314       rtx xop0 = op0, xop1 = op1;
2315
2316       /* If we are optimizing, force expensive constants into a register.  */
2317       xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
2318       xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
2319
2320       /* In case the insn wants input operands in modes different from
2321          those of the actual operands, convert the operands.  It would
2322          seem that we don't need to convert CONST_INTs, but we do, so
2323          that they're properly zero-extended, sign-extended or truncated
2324          for their mode.  */
2325
2326       if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2327         xop0 = convert_modes (mode0,
2328                               GET_MODE (op0) != VOIDmode
2329                               ? GET_MODE (op0)
2330                               : mode,
2331                               xop0, unsignedp);
2332
2333       if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2334         xop1 = convert_modes (mode1,
2335                               GET_MODE (op1) != VOIDmode
2336                               ? GET_MODE (op1)
2337                               : mode,
2338                               xop1, unsignedp);
2339
2340       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2341       if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2342         xop0 = copy_to_mode_reg (mode0, xop0);
2343
2344       if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2345         xop1 = copy_to_mode_reg (mode1, xop1);
2346
2347       /* We could handle this, but we should always be called with a pseudo
2348          for our targets and all insns should take them as outputs.  */
2349       gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2350       gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2351
2352       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2353       if (pat)
2354         {
2355           emit_insn (pat);
2356           return 1;
2357         }
2358       else
2359         delete_insns_since (last);
2360     }
2361
2362   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2363
2364   if (CLASS_HAS_WIDER_MODES_P (class))
2365     {
2366       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2367            wider_mode != VOIDmode;
2368            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2369         {
2370           if (optab_handler (binoptab, wider_mode)->insn_code
2371               != CODE_FOR_nothing)
2372             {
2373               rtx t0 = gen_reg_rtx (wider_mode);
2374               rtx t1 = gen_reg_rtx (wider_mode);
2375               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2376               rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2377
2378               if (expand_twoval_binop (binoptab, cop0, cop1,
2379                                        t0, t1, unsignedp))
2380                 {
2381                   convert_move (targ0, t0, unsignedp);
2382                   convert_move (targ1, t1, unsignedp);
2383                   return 1;
2384                 }
2385               else
2386                 delete_insns_since (last);
2387             }
2388         }
2389     }
2390
2391   delete_insns_since (entry_last);
2392   return 0;
2393 }
2394
2395 /* Expand the two-valued library call indicated by BINOPTAB, but
2396    preserve only one of the values.  If TARG0 is non-NULL, the first
2397    value is placed into TARG0; otherwise the second value is placed
2398    into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2399    value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2400    This routine assumes that the value returned by the library call is
2401    as if the return value was of an integral mode twice as wide as the
2402    mode of OP0.  Returns 1 if the call was successful.  */
2403
2404 bool
2405 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2406                              rtx targ0, rtx targ1, enum rtx_code code)
2407 {
2408   enum machine_mode mode;
2409   enum machine_mode libval_mode;
2410   rtx libval;
2411   rtx insns;
2412
2413   /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2414   gcc_assert (!targ0 != !targ1);
2415
2416   mode = GET_MODE (op0);
2417   if (!optab_handler (binoptab, mode)->libfunc)
2418     return false;
2419
2420   /* The value returned by the library function will have twice as
2421      many bits as the nominal MODE.  */
2422   libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2423                                         MODE_INT);
2424   start_sequence ();
2425   libval = emit_library_call_value (optab_handler (binoptab, mode)->libfunc,
2426                                     NULL_RTX, LCT_CONST,
2427                                     libval_mode, 2,
2428                                     op0, mode,
2429                                     op1, mode);
2430   /* Get the part of VAL containing the value that we want.  */
2431   libval = simplify_gen_subreg (mode, libval, libval_mode,
2432                                 targ0 ? 0 : GET_MODE_SIZE (mode));
2433   insns = get_insns ();
2434   end_sequence ();
2435   /* Move the into the desired location.  */
2436   emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2437                       gen_rtx_fmt_ee (code, mode, op0, op1));
2438
2439   return true;
2440 }
2441
2442 \f
2443 /* Wrapper around expand_unop which takes an rtx code to specify
2444    the operation to perform, not an optab pointer.  All other
2445    arguments are the same.  */
2446 rtx
2447 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2448                     rtx target, int unsignedp)
2449 {
2450   optab unop = code_to_optab[(int) code];
2451   gcc_assert (unop);
2452
2453   return expand_unop (mode, unop, op0, target, unsignedp);
2454 }
2455
2456 /* Try calculating
2457         (clz:narrow x)
2458    as
2459         (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2460 static rtx
2461 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2462 {
2463   enum mode_class class = GET_MODE_CLASS (mode);
2464   if (CLASS_HAS_WIDER_MODES_P (class))
2465     {
2466       enum machine_mode wider_mode;
2467       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2468            wider_mode != VOIDmode;
2469            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2470         {
2471           if (optab_handler (clz_optab, wider_mode)->insn_code
2472               != CODE_FOR_nothing)
2473             {
2474               rtx xop0, temp, last;
2475
2476               last = get_last_insn ();
2477
2478               if (target == 0)
2479                 target = gen_reg_rtx (mode);
2480               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2481               temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2482               if (temp != 0)
2483                 temp = expand_binop (wider_mode, sub_optab, temp,
2484                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2485                                               - GET_MODE_BITSIZE (mode)),
2486                                      target, true, OPTAB_DIRECT);
2487               if (temp == 0)
2488                 delete_insns_since (last);
2489
2490               return temp;
2491             }
2492         }
2493     }
2494   return 0;
2495 }
2496
2497 /* Try calculating
2498         (bswap:narrow x)
2499    as
2500         (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))).  */
2501 static rtx
2502 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2503 {
2504   enum mode_class class = GET_MODE_CLASS (mode);
2505   enum machine_mode wider_mode;
2506   rtx x, last;
2507
2508   if (!CLASS_HAS_WIDER_MODES_P (class))
2509     return NULL_RTX;
2510
2511   for (wider_mode = GET_MODE_WIDER_MODE (mode);
2512        wider_mode != VOIDmode;
2513        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2514     if (optab_handler (bswap_optab, wider_mode)->insn_code != CODE_FOR_nothing)
2515       goto found;
2516   return NULL_RTX;
2517
2518  found:
2519   last = get_last_insn ();
2520
2521   x = widen_operand (op0, wider_mode, mode, true, true);
2522   x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2523
2524   if (x != 0)
2525     x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2526                       size_int (GET_MODE_BITSIZE (wider_mode)
2527                                 - GET_MODE_BITSIZE (mode)),
2528                       NULL_RTX, true);
2529
2530   if (x != 0)
2531     {
2532       if (target == 0)
2533         target = gen_reg_rtx (mode);
2534       emit_move_insn (target, gen_lowpart (mode, x));
2535     }
2536   else
2537     delete_insns_since (last);
2538
2539   return target;
2540 }
2541
2542 /* Try calculating bswap as two bswaps of two word-sized operands.  */
2543
2544 static rtx
2545 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2546 {
2547   rtx t0, t1;
2548
2549   t1 = expand_unop (word_mode, bswap_optab,
2550                     operand_subword_force (op, 0, mode), NULL_RTX, true);
2551   t0 = expand_unop (word_mode, bswap_optab,
2552                     operand_subword_force (op, 1, mode), NULL_RTX, true);
2553
2554   if (target == 0)
2555     target = gen_reg_rtx (mode);
2556   if (REG_P (target))
2557     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2558   emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2559   emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2560
2561   return target;
2562 }
2563
2564 /* Try calculating (parity x) as (and (popcount x) 1), where
2565    popcount can also be done in a wider mode.  */
2566 static rtx
2567 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2568 {
2569   enum mode_class class = GET_MODE_CLASS (mode);
2570   if (CLASS_HAS_WIDER_MODES_P (class))
2571     {
2572       enum machine_mode wider_mode;
2573       for (wider_mode = mode; wider_mode != VOIDmode;
2574            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2575         {
2576           if (optab_handler (popcount_optab, wider_mode)->insn_code
2577               != CODE_FOR_nothing)
2578             {
2579               rtx xop0, temp, last;
2580
2581               last = get_last_insn ();
2582
2583               if (target == 0)
2584                 target = gen_reg_rtx (mode);
2585               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2586               temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2587                                   true);
2588               if (temp != 0)
2589                 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2590                                      target, true, OPTAB_DIRECT);
2591               if (temp == 0)
2592                 delete_insns_since (last);
2593
2594               return temp;
2595             }
2596         }
2597     }
2598   return 0;
2599 }
2600
2601 /* Try calculating ffs(x) using clz(x).  Since the ffs builtin promises
2602    to return zero for a zero value and clz may have an undefined value
2603    in that case, only do this if we know clz returns the right thing so
2604    that we don't have to generate a test and branch.  */
2605 static rtx
2606 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2607 {
2608   HOST_WIDE_INT val;
2609   if (clz_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2610       && CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2
2611       && val == GET_MODE_BITSIZE (mode))
2612     {
2613       rtx last = get_last_insn ();
2614       rtx temp;
2615
2616       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, true);
2617       if (temp)
2618         temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2619                              true, OPTAB_DIRECT);
2620       if (temp)
2621         temp = expand_unop (mode, clz_optab, temp, NULL_RTX, true);
2622       if (temp)
2623         temp = expand_binop (mode, sub_optab,
2624                              GEN_INT (GET_MODE_BITSIZE (mode)),
2625                              temp,
2626                              target, true, OPTAB_DIRECT);
2627       if (temp == 0)
2628         delete_insns_since (last);
2629       return temp;
2630     }
2631   return 0;
2632 }
2633
2634 /* We can compute ctz(x) using clz(x) with a similar recipe.  Here the ctz
2635    builtin has an undefined result on zero, just like clz, so we don't have
2636    to do that check.  */
2637 static rtx
2638 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2639 {
2640   if (clz_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2641     {
2642       rtx last = get_last_insn ();
2643       rtx temp;
2644
2645       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, true);
2646       if (temp)
2647         temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2648                              true, OPTAB_DIRECT);
2649       if (temp)
2650         temp = expand_unop (mode, clz_optab, temp, NULL_RTX, true);
2651       if (temp)
2652         temp = expand_binop (mode, xor_optab, temp,
2653                              GEN_INT (GET_MODE_BITSIZE (mode) - 1),
2654                              target,
2655                              true, OPTAB_DIRECT);
2656       if (temp == 0)
2657         delete_insns_since (last);
2658       return temp;
2659     }
2660   return 0;
2661 }
2662
2663 /* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
2664    conditions, VAL may already be a SUBREG against which we cannot generate
2665    a further SUBREG.  In this case, we expect forcing the value into a
2666    register will work around the situation.  */
2667
2668 static rtx
2669 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2670                            enum machine_mode imode)
2671 {
2672   rtx ret;
2673   ret = lowpart_subreg (omode, val, imode);
2674   if (ret == NULL)
2675     {
2676       val = force_reg (imode, val);
2677       ret = lowpart_subreg (omode, val, imode);
2678       gcc_assert (ret != NULL);
2679     }
2680   return ret;
2681 }
2682
2683 /* Expand a floating point absolute value or negation operation via a
2684    logical operation on the sign bit.  */
2685
2686 static rtx
2687 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2688                    rtx op0, rtx target)
2689 {
2690   const struct real_format *fmt;
2691   int bitpos, word, nwords, i;
2692   enum machine_mode imode;
2693   HOST_WIDE_INT hi, lo;
2694   rtx temp, insns;
2695
2696   /* The format has to have a simple sign bit.  */
2697   fmt = REAL_MODE_FORMAT (mode);
2698   if (fmt == NULL)
2699     return NULL_RTX;
2700
2701   bitpos = fmt->signbit_rw;
2702   if (bitpos < 0)
2703     return NULL_RTX;
2704
2705   /* Don't create negative zeros if the format doesn't support them.  */
2706   if (code == NEG && !fmt->has_signed_zero)
2707     return NULL_RTX;
2708
2709   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2710     {
2711       imode = int_mode_for_mode (mode);
2712       if (imode == BLKmode)
2713         return NULL_RTX;
2714       word = 0;
2715       nwords = 1;
2716     }
2717   else
2718     {
2719       imode = word_mode;
2720
2721       if (FLOAT_WORDS_BIG_ENDIAN)
2722         word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2723       else
2724         word = bitpos / BITS_PER_WORD;
2725       bitpos = bitpos % BITS_PER_WORD;
2726       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2727     }
2728
2729   if (bitpos < HOST_BITS_PER_WIDE_INT)
2730     {
2731       hi = 0;
2732       lo = (HOST_WIDE_INT) 1 << bitpos;
2733     }
2734   else
2735     {
2736       hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2737       lo = 0;
2738     }
2739   if (code == ABS)
2740     lo = ~lo, hi = ~hi;
2741
2742   if (target == 0 || target == op0)
2743     target = gen_reg_rtx (mode);
2744
2745   if (nwords > 1)
2746     {
2747       start_sequence ();
2748
2749       for (i = 0; i < nwords; ++i)
2750         {
2751           rtx targ_piece = operand_subword (target, i, 1, mode);
2752           rtx op0_piece = operand_subword_force (op0, i, mode);
2753
2754           if (i == word)
2755             {
2756               temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2757                                    op0_piece,
2758                                    immed_double_const (lo, hi, imode),
2759                                    targ_piece, 1, OPTAB_LIB_WIDEN);
2760               if (temp != targ_piece)
2761                 emit_move_insn (targ_piece, temp);
2762             }
2763           else
2764             emit_move_insn (targ_piece, op0_piece);
2765         }
2766
2767       insns = get_insns ();
2768       end_sequence ();
2769
2770       temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2771       emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2772     }
2773   else
2774     {
2775       temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2776                            gen_lowpart (imode, op0),
2777                            immed_double_const (lo, hi, imode),
2778                            gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2779       target = lowpart_subreg_maybe_copy (mode, temp, imode);
2780
2781       set_unique_reg_note (get_last_insn (), REG_EQUAL,
2782                            gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2783     }
2784
2785   return target;
2786 }
2787
2788 /* Generate code to perform an operation specified by UNOPTAB
2789    on operand OP0, with result having machine-mode MODE.
2790
2791    UNSIGNEDP is for the case where we have to widen the operands
2792    to perform the operation.  It says to use zero-extension.
2793
2794    If TARGET is nonzero, the value
2795    is generated there, if it is convenient to do so.
2796    In all cases an rtx is returned for the locus of the value;
2797    this may or may not be TARGET.  */
2798
2799 rtx
2800 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2801              int unsignedp)
2802 {
2803   enum mode_class class;
2804   enum machine_mode wider_mode;
2805   rtx temp;
2806   rtx last = get_last_insn ();
2807   rtx pat;
2808
2809   class = GET_MODE_CLASS (mode);
2810
2811   if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2812     {
2813       int icode = (int) optab_handler (unoptab, mode)->insn_code;
2814       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2815       rtx xop0 = op0;
2816
2817       if (target)
2818         temp = target;
2819       else
2820         temp = gen_reg_rtx (mode);
2821
2822       if (GET_MODE (xop0) != VOIDmode
2823           && GET_MODE (xop0) != mode0)
2824         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2825
2826       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2827
2828       if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2829         xop0 = copy_to_mode_reg (mode0, xop0);
2830
2831       if (!insn_data[icode].operand[0].predicate (temp, mode))
2832         temp = gen_reg_rtx (mode);
2833
2834       pat = GEN_FCN (icode) (temp, xop0);
2835       if (pat)
2836         {
2837           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2838               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2839             {
2840               delete_insns_since (last);
2841               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2842             }
2843
2844           emit_insn (pat);
2845
2846           return temp;
2847         }
2848       else
2849         delete_insns_since (last);
2850     }
2851
2852   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2853
2854   /* Widening clz needs special treatment.  */
2855   if (unoptab == clz_optab)
2856     {
2857       temp = widen_clz (mode, op0, target);
2858       if (temp)
2859         return temp;
2860       else
2861         goto try_libcall;
2862     }
2863
2864   /* Widening (or narrowing) bswap needs special treatment.  */
2865   if (unoptab == bswap_optab)
2866     {
2867       temp = widen_bswap (mode, op0, target);
2868       if (temp)
2869         return temp;
2870
2871       if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2872           && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
2873         {
2874           temp = expand_doubleword_bswap (mode, op0, target);
2875           if (temp)
2876             return temp;
2877         }
2878
2879       goto try_libcall;
2880     }
2881
2882   if (CLASS_HAS_WIDER_MODES_P (class))
2883     for (wider_mode = GET_MODE_WIDER_MODE (mode);
2884          wider_mode != VOIDmode;
2885          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2886       {
2887         if (optab_handler (unoptab, wider_mode)->insn_code != CODE_FOR_nothing)
2888           {
2889             rtx xop0 = op0;
2890
2891             /* For certain operations, we need not actually extend
2892                the narrow operand, as long as we will truncate the
2893                results to the same narrowness.  */
2894
2895             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2896                                   (unoptab == neg_optab
2897                                    || unoptab == one_cmpl_optab)
2898                                   && class == MODE_INT);
2899
2900             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2901                                 unsignedp);
2902
2903             if (temp)
2904               {
2905                 if (class != MODE_INT
2906                     || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2907                                                GET_MODE_BITSIZE (wider_mode)))
2908                   {
2909                     if (target == 0)
2910                       target = gen_reg_rtx (mode);
2911                     convert_move (target, temp, 0);
2912                     return target;
2913                   }
2914                 else
2915                   return gen_lowpart (mode, temp);
2916               }
2917             else
2918               delete_insns_since (last);
2919           }
2920       }
2921
2922   /* These can be done a word at a time.  */
2923   if (unoptab == one_cmpl_optab
2924       && class == MODE_INT
2925       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2926       && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
2927     {
2928       int i;
2929       rtx insns;
2930
2931       if (target == 0 || target == op0)
2932         target = gen_reg_rtx (mode);
2933
2934       start_sequence ();
2935
2936       /* Do the actual arithmetic.  */
2937       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2938         {
2939           rtx target_piece = operand_subword (target, i, 1, mode);
2940           rtx x = expand_unop (word_mode, unoptab,
2941                                operand_subword_force (op0, i, mode),
2942                                target_piece, unsignedp);
2943
2944           if (target_piece != x)
2945             emit_move_insn (target_piece, x);
2946         }
2947
2948       insns = get_insns ();
2949       end_sequence ();
2950
2951       emit_no_conflict_block (insns, target, op0, NULL_RTX,
2952                               gen_rtx_fmt_e (unoptab->code, mode,
2953                                              copy_rtx (op0)));
2954       return target;
2955     }
2956
2957   if (unoptab->code == NEG)
2958     {
2959       /* Try negating floating point values by flipping the sign bit.  */
2960       if (SCALAR_FLOAT_MODE_P (mode))
2961         {
2962           temp = expand_absneg_bit (NEG, mode, op0, target);
2963           if (temp)
2964             return temp;
2965         }
2966
2967       /* If there is no negation pattern, and we have no negative zero,
2968          try subtracting from zero.  */
2969       if (!HONOR_SIGNED_ZEROS (mode))
2970         {
2971           temp = expand_binop (mode, (unoptab == negv_optab
2972                                       ? subv_optab : sub_optab),
2973                                CONST0_RTX (mode), op0, target,
2974                                unsignedp, OPTAB_DIRECT);
2975           if (temp)
2976             return temp;
2977         }
2978     }
2979
2980   /* Try calculating parity (x) as popcount (x) % 2.  */
2981   if (unoptab == parity_optab)
2982     {
2983       temp = expand_parity (mode, op0, target);
2984       if (temp)
2985         return temp;
2986     }
2987
2988   /* Try implementing ffs (x) in terms of clz (x).  */
2989   if (unoptab == ffs_optab)
2990     {
2991       temp = expand_ffs (mode, op0, target);
2992       if (temp)
2993         return temp;
2994     }
2995
2996   /* Try implementing ctz (x) in terms of clz (x).  */
2997   if (unoptab == ctz_optab)
2998     {
2999       temp = expand_ctz (mode, op0, target);
3000       if (temp)
3001         return temp;
3002     }
3003
3004  try_libcall:
3005   /* Now try a library call in this mode.  */
3006   if (optab_handler (unoptab, mode)->libfunc)
3007     {
3008       rtx insns;
3009       rtx value;
3010       enum machine_mode outmode = mode;
3011
3012       /* All of these functions return small values.  Thus we choose to
3013          have them return something that isn't a double-word.  */
3014       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3015           || unoptab == popcount_optab || unoptab == parity_optab)
3016         outmode
3017             = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
3018
3019       start_sequence ();
3020
3021       /* Pass 1 for NO_QUEUE so we don't lose any increments
3022          if the libcall is cse'd or moved.  */
3023       value = emit_library_call_value (optab_handler (unoptab, mode)->libfunc,
3024                                        NULL_RTX, LCT_CONST, outmode,
3025                                        1, op0, mode);
3026       insns = get_insns ();
3027       end_sequence ();
3028
3029       target = gen_reg_rtx (outmode);
3030       emit_libcall_block (insns, target, value,
3031                           gen_rtx_fmt_e (unoptab->code, outmode, op0));
3032
3033       return target;
3034     }
3035
3036   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3037
3038   if (CLASS_HAS_WIDER_MODES_P (class))
3039     {
3040       for (wider_mode = GET_MODE_WIDER_MODE (mode);
3041            wider_mode != VOIDmode;
3042            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3043         {
3044           if ((optab_handler (unoptab, wider_mode)->insn_code
3045                != CODE_FOR_nothing)
3046               || optab_handler (unoptab, wider_mode)->libfunc)
3047             {
3048               rtx xop0 = op0;
3049
3050               /* For certain operations, we need not actually extend
3051                  the narrow operand, as long as we will truncate the
3052                  results to the same narrowness.  */
3053
3054               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3055                                     (unoptab == neg_optab
3056                                      || unoptab == one_cmpl_optab)
3057                                     && class == MODE_INT);
3058
3059               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3060                                   unsignedp);
3061
3062               /* If we are generating clz using wider mode, adjust the
3063                  result.  */
3064               if (unoptab == clz_optab && temp != 0)
3065                 temp = expand_binop (wider_mode, sub_optab, temp,
3066                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
3067                                               - GET_MODE_BITSIZE (mode)),
3068                                      target, true, OPTAB_DIRECT);
3069
3070               if (temp)
3071                 {
3072                   if (class != MODE_INT)
3073                     {
3074                       if (target == 0)
3075                         target = gen_reg_rtx (mode);
3076                       convert_move (target, temp, 0);
3077                       return target;
3078                     }
3079                   else
3080                     return gen_lowpart (mode, temp);
3081                 }
3082               else
3083                 delete_insns_since (last);
3084             }
3085         }
3086     }
3087
3088   /* One final attempt at implementing negation via subtraction,
3089      this time allowing widening of the operand.  */
3090   if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
3091     {
3092       rtx temp;
3093       temp = expand_binop (mode,
3094                            unoptab == negv_optab ? subv_optab : sub_optab,
3095                            CONST0_RTX (mode), op0,
3096                            target, unsignedp, OPTAB_LIB_WIDEN);
3097       if (temp)
3098         return temp;
3099     }
3100
3101   return 0;
3102 }
3103 \f
3104 /* Emit code to compute the absolute value of OP0, with result to
3105    TARGET if convenient.  (TARGET may be 0.)  The return value says
3106    where the result actually is to be found.
3107
3108    MODE is the mode of the operand; the mode of the result is
3109    different but can be deduced from MODE.
3110
3111  */
3112
3113 rtx
3114 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3115                    int result_unsignedp)
3116 {
3117   rtx temp;
3118
3119   if (! flag_trapv)
3120     result_unsignedp = 1;
3121
3122   /* First try to do it with a special abs instruction.  */
3123   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3124                       op0, target, 0);
3125   if (temp != 0)
3126     return temp;
3127
3128   /* For floating point modes, try clearing the sign bit.  */
3129   if (SCALAR_FLOAT_MODE_P (mode))
3130     {
3131       temp = expand_absneg_bit (ABS, mode, op0, target);
3132       if (temp)
3133         return temp;
3134     }
3135
3136   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
3137   if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing
3138       && !HONOR_SIGNED_ZEROS (mode))
3139     {
3140       rtx last = get_last_insn ();
3141
3142       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3143       if (temp != 0)
3144         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3145                              OPTAB_WIDEN);
3146
3147       if (temp != 0)
3148         return temp;
3149
3150       delete_insns_since (last);
3151     }
3152
3153   /* If this machine has expensive jumps, we can do integer absolute
3154      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3155      where W is the width of MODE.  */
3156
3157   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
3158     {
3159       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3160                                    size_int (GET_MODE_BITSIZE (mode) - 1),
3161                                    NULL_RTX, 0);
3162
3163       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3164                            OPTAB_LIB_WIDEN);
3165       if (temp != 0)
3166         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3167                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
3168
3169       if (temp != 0)
3170         return temp;
3171     }
3172
3173   return NULL_RTX;
3174 }
3175
3176 rtx
3177 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3178             int result_unsignedp, int safe)
3179 {
3180   rtx temp, op1;
3181
3182   if (! flag_trapv)
3183     result_unsignedp = 1;
3184
3185   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3186   if (temp != 0)
3187     return temp;
3188
3189   /* If that does not win, use conditional jump and negate.  */
3190
3191   /* It is safe to use the target if it is the same
3192      as the source if this is also a pseudo register */
3193   if (op0 == target && REG_P (op0)
3194       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3195     safe = 1;
3196
3197   op1 = gen_label_rtx ();
3198   if (target == 0 || ! safe
3199       || GET_MODE (target) != mode
3200       || (MEM_P (target) && MEM_VOLATILE_P (target))
3201       || (REG_P (target)
3202           && REGNO (target) < FIRST_PSEUDO_REGISTER))
3203     target = gen_reg_rtx (mode);
3204
3205   emit_move_insn (target, op0);
3206   NO_DEFER_POP;
3207
3208   do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3209                            NULL_RTX, NULL_RTX, op1);
3210
3211   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3212                      target, target, 0);
3213   if (op0 != target)
3214     emit_move_insn (target, op0);
3215   emit_label (op1);
3216   OK_DEFER_POP;
3217   return target;
3218 }
3219
3220 /* A subroutine of expand_copysign, perform the copysign operation using the
3221    abs and neg primitives advertised to exist on the target.  The assumption
3222    is that we have a split register file, and leaving op0 in fp registers,
3223    and not playing with subregs so much, will help the register allocator.  */
3224
3225 static rtx
3226 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3227                         int bitpos, bool op0_is_abs)
3228 {
3229   enum machine_mode imode;
3230   int icode;
3231   rtx sign, label;
3232
3233   if (target == op1)
3234     target = NULL_RTX;
3235
3236   /* Check if the back end provides an insn that handles signbit for the
3237      argument's mode. */
3238   icode = (int) signbit_optab->handlers [(int) mode].insn_code;
3239   if (icode != CODE_FOR_nothing)
3240     {
3241       imode = insn_data[icode].operand[0].mode;
3242       sign = gen_reg_rtx (imode);
3243       emit_unop_insn (icode, sign, op1, UNKNOWN);
3244     }
3245   else
3246     {
3247       HOST_WIDE_INT hi, lo;
3248
3249       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3250         {
3251           imode = int_mode_for_mode (mode);
3252           if (imode == BLKmode)
3253             return NULL_RTX;
3254           op1 = gen_lowpart (imode, op1);
3255         }
3256       else
3257         {
3258           int word;
3259
3260           imode = word_mode;
3261           if (FLOAT_WORDS_BIG_ENDIAN)
3262             word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3263           else
3264             word = bitpos / BITS_PER_WORD;
3265           bitpos = bitpos % BITS_PER_WORD;
3266           op1 = operand_subword_force (op1, word, mode);
3267         }
3268
3269       if (bitpos < HOST_BITS_PER_WIDE_INT)
3270         {
3271           hi = 0;
3272           lo = (HOST_WIDE_INT) 1 << bitpos;
3273         }
3274       else
3275         {
3276           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3277           lo = 0;
3278         }
3279
3280       sign = gen_reg_rtx (imode);
3281       sign = expand_binop (imode, and_optab, op1,
3282                            immed_double_const (lo, hi, imode),
3283                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
3284     }
3285
3286   if (!op0_is_abs)
3287     {
3288       op0 = expand_unop (mode, abs_optab, op0, target, 0);
3289       if (op0 == NULL)
3290         return NULL_RTX;
3291       target = op0;
3292     }
3293   else
3294     {
3295       if (target == NULL_RTX)
3296         target = copy_to_reg (op0);
3297       else
3298         emit_move_insn (target, op0);
3299     }
3300
3301   label = gen_label_rtx ();
3302   emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3303
3304   if (GET_CODE (op0) == CONST_DOUBLE)
3305     op0 = simplify_unary_operation (NEG, mode, op0, mode);
3306   else
3307     op0 = expand_unop (mode, neg_optab, op0, target, 0);
3308   if (op0 != target)
3309     emit_move_insn (target, op0);
3310
3311   emit_label (label);
3312
3313   return target;
3314 }
3315
3316
3317 /* A subroutine of expand_copysign, perform the entire copysign operation
3318    with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
3319    is true if op0 is known to have its sign bit clear.  */
3320
3321 static rtx
3322 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3323                      int bitpos, bool op0_is_abs)
3324 {
3325   enum machine_mode imode;
3326   HOST_WIDE_INT hi, lo;
3327   int word, nwords, i;
3328   rtx temp, insns;
3329
3330   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3331     {
3332       imode = int_mode_for_mode (mode);
3333       if (imode == BLKmode)
3334         return NULL_RTX;
3335       word = 0;
3336       nwords = 1;
3337     }
3338   else
3339     {
3340       imode = word_mode;
3341
3342       if (FLOAT_WORDS_BIG_ENDIAN)
3343         word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3344       else
3345         word = bitpos / BITS_PER_WORD;
3346       bitpos = bitpos % BITS_PER_WORD;
3347       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3348     }
3349
3350   if (bitpos < HOST_BITS_PER_WIDE_INT)
3351     {
3352       hi = 0;
3353       lo = (HOST_WIDE_INT) 1 << bitpos;
3354     }
3355   else
3356     {
3357       hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3358       lo = 0;
3359     }
3360
3361   if (target == 0 || target == op0 || target == op1)
3362     target = gen_reg_rtx (mode);
3363
3364   if (nwords > 1)
3365     {
3366       start_sequence ();
3367
3368       for (i = 0; i < nwords; ++i)
3369         {
3370           rtx targ_piece = operand_subword (target, i, 1, mode);
3371           rtx op0_piece = operand_subword_force (op0, i, mode);
3372
3373           if (i == word)
3374             {
3375               if (!op0_is_abs)
3376                 op0_piece = expand_binop (imode, and_optab, op0_piece,
3377                                           immed_double_const (~lo, ~hi, imode),
3378                                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
3379
3380               op1 = expand_binop (imode, and_optab,
3381                                   operand_subword_force (op1, i, mode),
3382                                   immed_double_const (lo, hi, imode),
3383                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
3384
3385               temp = expand_binop (imode, ior_optab, op0_piece, op1,
3386                                    targ_piece, 1, OPTAB_LIB_WIDEN);
3387               if (temp != targ_piece)
3388                 emit_move_insn (targ_piece, temp);
3389             }
3390           else
3391             emit_move_insn (targ_piece, op0_piece);
3392         }
3393
3394       insns = get_insns ();
3395       end_sequence ();
3396
3397       emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3398     }
3399   else
3400     {
3401       op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3402                           immed_double_const (lo, hi, imode),
3403                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
3404
3405       op0 = gen_lowpart (imode, op0);
3406       if (!op0_is_abs)
3407         op0 = expand_binop (imode, and_optab, op0,
3408                             immed_double_const (~lo, ~hi, imode),
3409                             NULL_RTX, 1, OPTAB_LIB_WIDEN);
3410
3411       temp = expand_binop (imode, ior_optab, op0, op1,
3412                            gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3413       target = lowpart_subreg_maybe_copy (mode, temp, imode);
3414     }
3415
3416   return target;
3417 }
3418
3419 /* Expand the C99 copysign operation.  OP0 and OP1 must be the same
3420    scalar floating point mode.  Return NULL if we do not know how to
3421    expand the operation inline.  */
3422
3423 rtx
3424 expand_copysign (rtx op0, rtx op1, rtx target)
3425 {
3426   enum machine_mode mode = GET_MODE (op0);
3427   const struct real_format *fmt;
3428   bool op0_is_abs;
3429   rtx temp;
3430
3431   gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3432   gcc_assert (GET_MODE (op1) == mode);
3433
3434   /* First try to do it with a special instruction.  */
3435   temp = expand_binop (mode, copysign_optab, op0, op1,
3436                        target, 0, OPTAB_DIRECT);
3437   if (temp)
3438     return temp;
3439
3440   fmt = REAL_MODE_FORMAT (mode);
3441   if (fmt == NULL || !fmt->has_signed_zero)
3442     return NULL_RTX;
3443
3444   op0_is_abs = false;
3445   if (GET_CODE (op0) == CONST_DOUBLE)
3446     {
3447       if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3448         op0 = simplify_unary_operation (ABS, mode, op0, mode);
3449       op0_is_abs = true;
3450     }
3451
3452   if (fmt->signbit_ro >= 0
3453       && (GET_CODE (op0) == CONST_DOUBLE
3454           || (optab_handler (neg_optab, mode)->insn_code != CODE_FOR_nothing
3455               && optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing)))
3456     {
3457       temp = expand_copysign_absneg (mode, op0, op1, target,
3458                                      fmt->signbit_ro, op0_is_abs);
3459       if (temp)
3460         return temp;
3461     }
3462
3463   if (fmt->signbit_rw < 0)
3464     return NULL_RTX;
3465   return expand_copysign_bit (mode, op0, op1, target,
3466                               fmt->signbit_rw, op0_is_abs);
3467 }
3468 \f
3469 /* Generate an instruction whose insn-code is INSN_CODE,
3470    with two operands: an output TARGET and an input OP0.
3471    TARGET *must* be nonzero, and the output is always stored there.
3472    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3473    the value that is stored into TARGET.  */
3474
3475 void
3476 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3477 {
3478   rtx temp;
3479   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3480   rtx pat;
3481
3482   temp = target;
3483
3484   /* Now, if insn does not accept our operands, put them into pseudos.  */
3485
3486   if (!insn_data[icode].operand[1].predicate (op0, mode0))
3487     op0 = copy_to_mode_reg (mode0, op0);
3488
3489   if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3490     temp = gen_reg_rtx (GET_MODE (temp));
3491
3492   pat = GEN_FCN (icode) (temp, op0);
3493
3494   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3495     add_equal_note (pat, temp, code, op0, NULL_RTX);
3496
3497   emit_insn (pat);
3498
3499   if (temp != target)
3500     emit_move_insn (target, temp);
3501 }
3502 \f
3503 struct no_conflict_data
3504 {
3505   rtx target, first, insn;
3506   bool must_stay;
3507 };
3508
3509 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3510    Set P->must_stay if the currently examined clobber / store has to stay
3511    in the list of insns that constitute the actual no_conflict block /
3512    libcall block.  */
3513 static void
3514 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3515 {
3516   struct no_conflict_data *p= p0;
3517
3518   /* If this inns directly contributes to setting the target, it must stay.  */
3519   if (reg_overlap_mentioned_p (p->target, dest))
3520     p->must_stay = true;
3521   /* If we haven't committed to keeping any other insns in the list yet,
3522      there is nothing more to check.  */
3523   else if (p->insn == p->first)
3524     return;
3525   /* If this insn sets / clobbers a register that feeds one of the insns
3526      already in the list, this insn has to stay too.  */
3527   else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3528            || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3529            || reg_used_between_p (dest, p->first, p->insn)
3530            /* Likewise if this insn depends on a register set by a previous
3531               insn in the list, or if it sets a result (presumably a hard
3532               register) that is set or clobbered by a previous insn.
3533               N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3534               SET_DEST perform the former check on the address, and the latter
3535               check on the MEM.  */
3536            || (GET_CODE (set) == SET
3537                && (modified_in_p (SET_SRC (set), p->first)
3538                    || modified_in_p (SET_DEST (set), p->first)
3539                    || modified_between_p (SET_SRC (set), p->first, p->insn)
3540                    || modified_between_p (SET_DEST (set), p->first, p->insn))))
3541     p->must_stay = true;
3542 }
3543
3544 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3545    logically equivalent to EQUIV, so it gets manipulated as a unit if it
3546    is possible to do so.  */
3547
3548 void
3549 maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3550 {
3551   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3552     {
3553       /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3554          encapsulated region would not be in one basic block, i.e. when
3555          there is a control_flow_insn_p insn between FIRST and LAST.  */
3556       bool attach_libcall_retval_notes = true;
3557       rtx insn, next = NEXT_INSN (last);
3558
3559       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3560         if (control_flow_insn_p (insn))
3561           {
3562             attach_libcall_retval_notes = false;
3563             break;
3564           }
3565
3566       if (attach_libcall_retval_notes)
3567         {
3568           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3569                                                  REG_NOTES (first));
3570           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3571                                                 REG_NOTES (last));
3572           next = NEXT_INSN (last);
3573           for (insn = first; insn != next; insn = NEXT_INSN (insn))
3574             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LIBCALL_ID,
3575                                                   GEN_INT (libcall_id),
3576                                                   REG_NOTES (insn));
3577           libcall_id++;
3578         }
3579     }
3580 }
3581
3582 /* Emit code to perform a series of operations on a multi-word quantity, one
3583    word at a time.
3584
3585    Such a block is preceded by a CLOBBER of the output, consists of multiple
3586    insns, each setting one word of the output, and followed by a SET copying
3587    the output to itself.
3588
3589    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3590    note indicating that it doesn't conflict with the (also multi-word)
3591    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3592    notes.
3593
3594    INSNS is a block of code generated to perform the operation, not including
3595    the CLOBBER and final copy.  All insns that compute intermediate values
3596    are first emitted, followed by the block as described above.
3597
3598    TARGET, OP0, and OP1 are the output and inputs of the operations,
3599    respectively.  OP1 may be zero for a unary operation.
3600
3601    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3602    on the last insn.
3603
3604    If TARGET is not a register, INSNS is simply emitted with no special
3605    processing.  Likewise if anything in INSNS is not an INSN or if
3606    there is a libcall block inside INSNS.
3607
3608    The final insn emitted is returned.  */
3609
3610 rtx
3611 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3612 {
3613   rtx prev, next, first, last, insn;
3614
3615   if (!REG_P (target) || reload_in_progress)
3616     return emit_insn (insns);
3617   else
3618     for (insn = insns; insn; insn = NEXT_INSN (insn))
3619       if (!NONJUMP_INSN_P (insn)
3620           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3621         return emit_insn (insns);
3622
3623   /* First emit all insns that do not store into words of the output and remove
3624      these from the list.  */
3625   for (insn = insns; insn; insn = next)
3626     {
3627       rtx note;
3628       struct no_conflict_data data;
3629
3630       next = NEXT_INSN (insn);
3631
3632       /* Some ports (cris) create a libcall regions at their own.  We must
3633          avoid any potential nesting of LIBCALLs.  */
3634       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3635         remove_note (insn, note);
3636       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3637         remove_note (insn, note);
3638       if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL)) != NULL)
3639         remove_note (insn, note);
3640
3641       data.target = target;
3642       data.first = insns;
3643       data.insn = insn;
3644       data.must_stay = 0;
3645       note_stores (PATTERN (insn), no_conflict_move_test, &data);
3646       if (! data.must_stay)
3647         {
3648           if (PREV_INSN (insn))
3649             NEXT_INSN (PREV_INSN (insn)) = next;
3650           else
3651             insns = next;
3652
3653           if (next)
3654             PREV_INSN (next) = PREV_INSN (insn);
3655
3656           add_insn (insn);
3657         }
3658     }
3659
3660   prev = get_last_insn ();
3661
3662   /* Now write the CLOBBER of the output, followed by the setting of each
3663      of the words, followed by the final copy.  */
3664   if (target != op0 && target != op1)
3665     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3666
3667   for (insn = insns; insn; insn = next)
3668     {
3669       next = NEXT_INSN (insn);
3670       add_insn (insn);
3671
3672       if (op1 && REG_P (op1))
3673         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3674                                               REG_NOTES (insn));
3675
3676       if (op0 && REG_P (op0))
3677         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3678                                               REG_NOTES (insn));
3679     }
3680
3681   if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3682       != CODE_FOR_nothing)
3683     {
3684       last = emit_move_insn (target, target);
3685       if (equiv)
3686         set_unique_reg_note (last, REG_EQUAL, equiv);
3687     }
3688   else
3689     {
3690       last = get_last_insn ();
3691
3692       /* Remove any existing REG_EQUAL note from "last", or else it will
3693          be mistaken for a note referring to the full contents of the
3694          alleged libcall value when found together with the REG_RETVAL
3695          note added below.  An existing note can come from an insn
3696          expansion at "last".  */
3697       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3698     }
3699
3700   if (prev == 0)
3701     first = get_insns ();
3702   else
3703     first = NEXT_INSN (prev);
3704
3705   maybe_encapsulate_block (first, last, equiv);
3706
3707   return last;
3708 }
3709 \f
3710 /* Emit code to make a call to a constant function or a library call.
3711
3712    INSNS is a list containing all insns emitted in the call.
3713    These insns leave the result in RESULT.  Our block is to copy RESULT
3714    to TARGET, which is logically equivalent to EQUIV.
3715
3716    We first emit any insns that set a pseudo on the assumption that these are
3717    loading constants into registers; doing so allows them to be safely cse'ed
3718    between blocks.  Then we emit all the other insns in the block, followed by
3719    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3720    note with an operand of EQUIV.
3721
3722    Moving assignments to pseudos outside of the block is done to improve
3723    the generated code, but is not required to generate correct code,
3724    hence being unable to move an assignment is not grounds for not making
3725    a libcall block.  There are two reasons why it is safe to leave these
3726    insns inside the block: First, we know that these pseudos cannot be
3727    used in generated RTL outside the block since they are created for
3728    temporary purposes within the block.  Second, CSE will not record the
3729    values of anything set inside a libcall block, so we know they must
3730    be dead at the end of the block.
3731
3732    Except for the first group of insns (the ones setting pseudos), the
3733    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3734 void
3735 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3736 {
3737   rtx final_dest = target;
3738   rtx prev, next, first, last, insn;
3739
3740   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3741      into a MEM later.  Protect the libcall block from this change.  */
3742   if (! REG_P (target) || REG_USERVAR_P (target))
3743     target = gen_reg_rtx (GET_MODE (target));
3744
3745   /* If we're using non-call exceptions, a libcall corresponding to an
3746      operation that may trap may also trap.  */
3747   if (flag_non_call_exceptions && may_trap_p (equiv))
3748     {
3749       for (insn = insns; insn; insn = NEXT_INSN (insn))
3750         if (CALL_P (insn))
3751           {
3752             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3753
3754             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3755               remove_note (insn, note);
3756           }
3757     }
3758   else
3759   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3760      reg note to indicate that this call cannot throw or execute a nonlocal
3761      goto (unless there is already a REG_EH_REGION note, in which case
3762      we update it).  */
3763     for (insn = insns; insn; insn = NEXT_INSN (insn))
3764       if (CALL_P (insn))
3765         {
3766           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3767
3768           if (note != 0)
3769             XEXP (note, 0) = constm1_rtx;
3770           else
3771             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3772                                                   REG_NOTES (insn));
3773         }
3774
3775   /* First emit all insns that set pseudos.  Remove them from the list as
3776      we go.  Avoid insns that set pseudos which were referenced in previous
3777      insns.  These can be generated by move_by_pieces, for example,
3778      to update an address.  Similarly, avoid insns that reference things
3779      set in previous insns.  */
3780
3781   for (insn = insns; insn; insn = next)
3782     {
3783       rtx set = single_set (insn);
3784       rtx note;
3785
3786       /* Some ports (cris) create a libcall regions at their own.  We must
3787          avoid any potential nesting of LIBCALLs.  */
3788       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3789         remove_note (insn, note);
3790       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3791         remove_note (insn, note);
3792       if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL)) != NULL)
3793         remove_note (insn, note);
3794
3795       next = NEXT_INSN (insn);
3796
3797       if (set != 0 && REG_P (SET_DEST (set))
3798           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3799         {
3800           struct no_conflict_data data;
3801
3802           data.target = const0_rtx;
3803           data.first = insns;
3804           data.insn = insn;
3805           data.must_stay = 0;
3806           note_stores (PATTERN (insn), no_conflict_move_test, &data);
3807           if (! data.must_stay)
3808             {
3809               if (PREV_INSN (insn))
3810                 NEXT_INSN (PREV_INSN (insn)) = next;
3811               else
3812                 insns = next;
3813
3814               if (next)
3815                 PREV_INSN (next) = PREV_INSN (insn);
3816
3817               add_insn (insn);
3818             }
3819         }
3820
3821       /* Some ports use a loop to copy large arguments onto the stack.
3822          Don't move anything outside such a loop.  */
3823       if (LABEL_P (insn))
3824         break;
3825     }
3826
3827   prev = get_last_insn ();
3828
3829   /* Write the remaining insns followed by the final copy.  */
3830
3831   for (insn = insns; insn; insn = next)
3832     {
3833       next = NEXT_INSN (insn);
3834
3835       add_insn (insn);
3836     }
3837
3838   last = emit_move_insn (target, result);
3839   if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3840       != CODE_FOR_nothing)
3841     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3842   else
3843     {
3844       /* Remove any existing REG_EQUAL note from "last", or else it will
3845          be mistaken for a note referring to the full contents of the
3846          libcall value when found together with the REG_RETVAL note added
3847          below.  An existing note can come from an insn expansion at
3848          "last".  */
3849       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3850     }
3851
3852   if (final_dest != target)
3853     emit_move_insn (final_dest, target);
3854
3855   if (prev == 0)
3856     first = get_insns ();
3857   else
3858     first = NEXT_INSN (prev);
3859
3860   maybe_encapsulate_block (first, last, equiv);
3861 }
3862 \f
3863 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3864    PURPOSE describes how this comparison will be used.  CODE is the rtx
3865    comparison code we will be using.
3866
3867    ??? Actually, CODE is slightly weaker than that.  A target is still
3868    required to implement all of the normal bcc operations, but not
3869    required to implement all (or any) of the unordered bcc operations.  */
3870
3871 int
3872 can_compare_p (enum rtx_code code, enum machine_mode mode,
3873                enum can_compare_purpose purpose)
3874 {
3875   do
3876     {
3877       if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
3878         {
3879           if (purpose == ccp_jump)
3880             return bcc_gen_fctn[(int) code] != NULL;
3881           else if (purpose == ccp_store_flag)
3882             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3883           else
3884             /* There's only one cmov entry point, and it's allowed to fail.  */
3885             return 1;
3886         }
3887       if (purpose == ccp_jump
3888           && optab_handler (cbranch_optab, mode)->insn_code != CODE_FOR_nothing)
3889         return 1;
3890       if (purpose == ccp_cmov
3891           && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
3892         return 1;
3893       if (purpose == ccp_store_flag
3894           && optab_handler (cstore_optab, mode)->insn_code != CODE_FOR_nothing)
3895         return 1;
3896       mode = GET_MODE_WIDER_MODE (mode);
3897     }
3898   while (mode != VOIDmode);
3899
3900   return 0;
3901 }
3902
3903 /* This function is called when we are going to emit a compare instruction that
3904    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3905
3906    *PMODE is the mode of the inputs (in case they are const_int).
3907    *PUNSIGNEDP nonzero says that the operands are unsigned;
3908    this matters if they need to be widened.
3909
3910    If they have mode BLKmode, then SIZE specifies the size of both operands.
3911
3912    This function performs all the setup necessary so that the caller only has
3913    to emit a single comparison insn.  This setup can involve doing a BLKmode
3914    comparison or emitting a library call to perform the comparison if no insn
3915    is available to handle it.
3916    The values which are passed in through pointers can be modified; the caller
3917    should perform the comparison on the modified values.  Constant
3918    comparisons must have already been folded.  */
3919
3920 static void
3921 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3922                   enum machine_mode *pmode, int *punsignedp,
3923                   enum can_compare_purpose purpose)
3924 {
3925   enum machine_mode mode = *pmode;
3926   rtx x = *px, y = *py;
3927   int unsignedp = *punsignedp;
3928
3929   /* If we are inside an appropriately-short loop and we are optimizing,
3930      force expensive constants into a register.  */
3931   if (CONSTANT_P (x) && optimize
3932       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3933     x = force_reg (mode, x);
3934
3935   if (CONSTANT_P (y) && optimize
3936       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3937     y = force_reg (mode, y);
3938
3939 #ifdef HAVE_cc0
3940   /* Make sure if we have a canonical comparison.  The RTL
3941      documentation states that canonical comparisons are required only
3942      for targets which have cc0.  */
3943   gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3944 #endif
3945
3946   /* Don't let both operands fail to indicate the mode.  */
3947   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3948     x = force_reg (mode, x);
3949
3950   /* Handle all BLKmode compares.  */
3951
3952   if (mode == BLKmode)
3953     {
3954       enum machine_mode cmp_mode, result_mode;
3955       enum insn_code cmp_code;
3956       tree length_type;
3957       rtx libfunc;
3958       rtx result;
3959       rtx opalign
3960         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3961
3962       gcc_assert (size);
3963
3964       /* Try to use a memory block compare insn - either cmpstr
3965          or cmpmem will do.  */
3966       for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3967            cmp_mode != VOIDmode;
3968            cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3969         {
3970           cmp_code = cmpmem_optab[cmp_mode];
3971           if (cmp_code == CODE_FOR_nothing)
3972             cmp_code = cmpstr_optab[cmp_mode];
3973           if (cmp_code == CODE_FOR_nothing)
3974             cmp_code = cmpstrn_optab[cmp_mode];
3975           if (cmp_code == CODE_FOR_nothing)
3976             continue;
3977
3978           /* Must make sure the size fits the insn's mode.  */
3979           if ((GET_CODE (size) == CONST_INT
3980                && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3981               || (GET_MODE_BITSIZE (GET_MODE (size))
3982                   > GET_MODE_BITSIZE (cmp_mode)))
3983             continue;
3984
3985           result_mode = insn_data[cmp_code].operand[0].mode;
3986           result = gen_reg_rtx (result_mode);
3987           size = convert_to_mode (cmp_mode, size, 1);
3988           emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3989
3990           *px = result;
3991           *py = const0_rtx;
3992           *pmode = result_mode;
3993           return;
3994         }
3995
3996       /* Otherwise call a library function, memcmp.  */
3997       libfunc = memcmp_libfunc;
3998       length_type = sizetype;
3999       result_mode = TYPE_MODE (integer_type_node);
4000       cmp_mode = TYPE_MODE (length_type);
4001       size = convert_to_mode (TYPE_MODE (length_type), size,
4002                               TYPE_UNSIGNED (length_type));
4003
4004       result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
4005                                         result_mode, 3,
4006                                         XEXP (x, 0), Pmode,
4007                                         XEXP (y, 0), Pmode,
4008                                         size, cmp_mode);
4009       *px = result;
4010       *py = const0_rtx;
4011       *pmode = result_mode;
4012       return;
4013     }
4014
4015   /* Don't allow operands to the compare to trap, as that can put the
4016      compare and branch in different basic blocks.  */
4017   if (flag_non_call_exceptions)
4018     {
4019       if (may_trap_p (x))
4020         x = force_reg (mode, x);
4021       if (may_trap_p (y))
4022         y = force_reg (mode, y);
4023     }
4024
4025   *px = x;
4026   *py = y;
4027   if (can_compare_p (*pcomparison, mode, purpose))
4028     return;
4029
4030   /* Handle a lib call just for the mode we are using.  */
4031
4032   if (optab_handler (cmp_optab, mode)->libfunc && !SCALAR_FLOAT_MODE_P (mode))
4033     {
4034       rtx libfunc = optab_handler (cmp_optab, mode)->libfunc;
4035       rtx result;
4036
4037       /* If we want unsigned, and this mode has a distinct unsigned
4038          comparison routine, use that.  */
4039       if (unsignedp && optab_handler (ucmp_optab, mode)->libfunc)
4040         libfunc = optab_handler (ucmp_optab, mode)->libfunc;
4041
4042       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4043                                         targetm.libgcc_cmp_return_mode (),
4044                                         2, x, mode, y, mode);
4045
4046       /* There are two kinds of comparison routines. Biased routines
4047          return 0/1/2, and unbiased routines return -1/0/1. Other parts
4048          of gcc expect that the comparison operation is equivalent
4049          to the modified comparison. For signed comparisons compare the 
4050          result against 1 in the biased case, and zero in the unbiased
4051          case. For unsigned comparisons always compare against 1 after
4052          biasing the unbiased result by adding 1. This gives us a way to
4053          represent LTU. */
4054       *px = result;
4055       *pmode = word_mode;
4056       *py = const1_rtx;
4057
4058       if (!TARGET_LIB_INT_CMP_BIASED)
4059         {
4060           if (*punsignedp)
4061             *px = plus_constant (result, 1);  
4062           else
4063             *py = const0_rtx;
4064         }
4065       return;
4066     }
4067
4068   gcc_assert (SCALAR_FLOAT_MODE_P (mode));
4069   prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4070 }
4071
4072 /* Before emitting an insn with code ICODE, make sure that X, which is going
4073    to be used for operand OPNUM of the insn, is converted from mode MODE to
4074    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4075    that it is accepted by the operand predicate.  Return the new value.  */
4076
4077 static rtx
4078 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
4079                  enum machine_mode wider_mode, int unsignedp)
4080 {
4081   if (mode != wider_mode)
4082     x = convert_modes (wider_mode, mode, x, unsignedp);
4083
4084   if (!insn_data[icode].operand[opnum].predicate
4085       (x, insn_data[icode].operand[opnum].mode))
4086     {
4087       if (reload_completed)
4088         return NULL_RTX;
4089       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
4090     }
4091
4092   return x;
4093 }
4094
4095 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4096    we can do the comparison.
4097    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
4098    be NULL_RTX which indicates that only a comparison is to be generated.  */
4099
4100 static void
4101 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
4102                           enum rtx_code comparison, int unsignedp, rtx label)
4103 {
4104   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
4105   enum mode_class class = GET_MODE_CLASS (mode);
4106   enum machine_mode wider_mode = mode;
4107
4108   /* Try combined insns first.  */
4109   do
4110     {
4111       enum insn_code icode;
4112       PUT_MODE (test, wider_mode);
4113
4114       if (label)
4115         {
4116           icode = optab_handler (cbranch_optab, wider_mode)->insn_code;
4117
4118           if (icode != CODE_FOR_nothing
4119               && insn_data[icode].operand[0].predicate (test, wider_mode))
4120             {
4121               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
4122               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
4123               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
4124               return;
4125             }
4126         }
4127
4128       /* Handle some compares against zero.  */
4129       icode = (int) optab_handler (tst_optab, wider_mode)->insn_code;
4130       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
4131         {
4132           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4133           emit_insn (GEN_FCN (icode) (x));
4134           if (label)
4135             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4136           return;
4137         }
4138
4139       /* Handle compares for which there is a directly suitable insn.  */
4140
4141       icode = (int) optab_handler (cmp_optab, wider_mode)->insn_code;
4142       if (icode != CODE_FOR_nothing)
4143         {
4144           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4145           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
4146           emit_insn (GEN_FCN (icode) (x, y));
4147           if (label)
4148             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4149           return;
4150         }
4151
4152       if (!CLASS_HAS_WIDER_MODES_P (class))
4153         break;
4154
4155       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
4156     }
4157   while (wider_mode != VOIDmode);
4158
4159   gcc_unreachable ();
4160 }
4161
4162 /* Generate code to compare X with Y so that the condition codes are
4163    set and to jump to LABEL if the condition is true.  If X is a
4164    constant and Y is not a constant, then the comparison is swapped to
4165    ensure that the comparison RTL has the canonical form.
4166
4167    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4168    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
4169    the proper branch condition code.
4170
4171    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4172
4173    MODE is the mode of the inputs (in case they are const_int).
4174
4175    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
4176    be passed unchanged to emit_cmp_insn, then potentially converted into an
4177    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
4178
4179 void
4180 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4181                          enum machine_mode mode, int unsignedp, rtx label)
4182 {
4183   rtx op0 = x, op1 = y;
4184
4185   /* Swap operands and condition to ensure canonical RTL.  */
4186   if (swap_commutative_operands_p (x, y))
4187     {
4188       /* If we're not emitting a branch, callers are required to pass
4189          operands in an order conforming to canonical RTL.  We relax this
4190          for commutative comparisons so callers using EQ don't need to do
4191          swapping by hand.  */
4192       gcc_assert (label || (comparison == swap_condition (comparison)));
4193
4194       op0 = y, op1 = x;
4195       comparison = swap_condition (comparison);
4196     }
4197
4198 #ifdef HAVE_cc0
4199   /* If OP0 is still a constant, then both X and Y must be constants.
4200      Force X into a register to create canonical RTL.  */
4201   if (CONSTANT_P (op0))
4202     op0 = force_reg (mode, op0);
4203 #endif
4204
4205   if (unsignedp)
4206     comparison = unsigned_condition (comparison);
4207
4208   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
4209                     ccp_jump);
4210   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
4211 }
4212
4213 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
4214
4215 void
4216 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4217                enum machine_mode mode, int unsignedp)
4218 {
4219   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
4220 }
4221 \f
4222 /* Emit a library call comparison between floating point X and Y.
4223    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4224
4225 static void
4226 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
4227                        enum machine_mode *pmode, int *punsignedp)
4228 {
4229   enum rtx_code comparison = *pcomparison;
4230   enum rtx_code swapped = swap_condition (comparison);
4231   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4232   rtx x = *px;
4233   rtx y = *py;
4234   enum machine_mode orig_mode = GET_MODE (x);
4235   enum machine_mode mode, cmp_mode;
4236   rtx value, target, insns, equiv;
4237   rtx libfunc = 0;
4238   bool reversed_p = false;
4239   cmp_mode = targetm.libgcc_cmp_return_mode ();
4240
4241   for (mode = orig_mode;
4242        mode != VOIDmode;
4243        mode = GET_MODE_WIDER_MODE (mode))
4244     {
4245       if ((libfunc = optab_handler (code_to_optab[comparison], mode)->libfunc))
4246         break;
4247
4248       if ((libfunc = optab_handler (code_to_optab[swapped], mode)->libfunc))
4249         {
4250           rtx tmp;
4251           tmp = x; x = y; y = tmp;
4252           comparison = swapped;
4253           break;
4254         }
4255
4256       if ((libfunc = optab_handler (code_to_optab[reversed], mode)->libfunc)
4257           && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4258         {
4259           comparison = reversed;
4260           reversed_p = true;
4261           break;
4262         }
4263     }
4264
4265   gcc_assert (mode != VOIDmode);
4266
4267   if (mode != orig_mode)
4268     {
4269       x = convert_to_mode (mode, x, 0);
4270       y = convert_to_mode (mode, y, 0);
4271     }
4272
4273   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4274      the RTL.  The allows the RTL optimizers to delete the libcall if the
4275      condition can be determined at compile-time.  */
4276   if (comparison == UNORDERED)
4277     {
4278       rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4279       equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4280       equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4281                                     temp, const_true_rtx, equiv);
4282     }
4283   else
4284     {
4285       equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4286       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4287         {
4288           rtx true_rtx, false_rtx;
4289
4290           switch (comparison)
4291             {
4292             case EQ:
4293               true_rtx = const0_rtx;
4294               false_rtx = const_true_rtx;
4295               break;
4296
4297             case NE:
4298               true_rtx = const_true_rtx;
4299               false_rtx = const0_rtx;
4300               break;
4301
4302             case GT:
4303               true_rtx = const1_rtx;
4304               false_rtx = const0_rtx;
4305               break;
4306
4307             case GE:
4308               true_rtx = const0_rtx;
4309               false_rtx = constm1_rtx;
4310               break;
4311
4312             case LT:
4313               true_rtx = constm1_rtx;
4314               false_rtx = const0_rtx;
4315               break;
4316
4317             case LE:
4318               true_rtx = const0_rtx;
4319               false_rtx = const1_rtx;
4320               break;
4321
4322             default:
4323               gcc_unreachable ();
4324             }
4325           equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4326                                         equiv, true_rtx, false_rtx);
4327         }
4328     }
4329
4330   start_sequence ();
4331   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4332                                    cmp_mode, 2, x, mode, y, mode);
4333   insns = get_insns ();
4334   end_sequence ();
4335
4336   target = gen_reg_rtx (cmp_mode);
4337   emit_libcall_block (insns, target, value, equiv);
4338
4339   if (comparison == UNORDERED
4340       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4341     comparison = reversed_p ? EQ : NE;
4342
4343   *px = target;
4344   *py = const0_rtx;
4345   *pmode = cmp_mode;
4346   *pcomparison = comparison;
4347   *punsignedp = 0;
4348 }
4349 \f
4350 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4351
4352 void
4353 emit_indirect_jump (rtx loc)
4354 {
4355   if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4356       (loc, Pmode))
4357     loc = copy_to_mode_reg (Pmode, loc);
4358
4359   emit_jump_insn (gen_indirect_jump (loc));
4360   emit_barrier ();
4361 }
4362 \f
4363 #ifdef HAVE_conditional_move
4364
4365 /* Emit a conditional move instruction if the machine supports one for that
4366    condition and machine mode.
4367
4368    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4369    the mode to use should they be constants.  If it is VOIDmode, they cannot
4370    both be constants.
4371
4372    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4373    should be stored there.  MODE is the mode to use should they be constants.
4374    If it is VOIDmode, they cannot both be constants.
4375
4376    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4377    is not supported.  */
4378
4379 rtx
4380 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4381                        enum machine_mode cmode, rtx op2, rtx op3,
4382                        enum machine_mode mode, int unsignedp)
4383 {
4384   rtx tem, subtarget, comparison, insn;
4385   enum insn_code icode;
4386   enum rtx_code reversed;
4387
4388   /* If one operand is constant, make it the second one.  Only do this
4389      if the other operand is not constant as well.  */
4390
4391   if (swap_commutative_operands_p (op0, op1))
4392     {
4393       tem = op0;
4394       op0 = op1;
4395       op1 = tem;
4396       code = swap_condition (code);
4397     }
4398
4399   /* get_condition will prefer to generate LT and GT even if the old
4400      comparison was against zero, so undo that canonicalization here since
4401      comparisons against zero are cheaper.  */
4402   if (code == LT && op1 == const1_rtx)
4403     code = LE, op1 = const0_rtx;
4404   else if (code == GT && op1 == constm1_rtx)
4405     code = GE, op1 = const0_rtx;
4406
4407   if (cmode == VOIDmode)
4408     cmode = GET_MODE (op0);
4409
4410   if (swap_commutative_operands_p (op2, op3)
4411       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4412           != UNKNOWN))
4413     {
4414       tem = op2;
4415       op2 = op3;
4416       op3 = tem;
4417       code = reversed;
4418     }
4419
4420   if (mode == VOIDmode)
4421     mode = GET_MODE (op2);
4422
4423   icode = movcc_gen_code[mode];
4424
4425   if (icode == CODE_FOR_nothing)
4426     return 0;
4427
4428   if (!target)
4429     target = gen_reg_rtx (mode);
4430
4431   subtarget = target;
4432
4433   /* If the insn doesn't accept these operands, put them in pseudos.  */
4434
4435   if (!insn_data[icode].operand[0].predicate
4436       (subtarget, insn_data[icode].operand[0].mode))
4437     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4438
4439   if (!insn_data[icode].operand[2].predicate
4440       (op2, insn_data[icode].operand[2].mode))
4441     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4442
4443   if (!insn_data[icode].operand[3].predicate
4444       (op3, insn_data[icode].operand[3].mode))
4445     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4446
4447   /* Everything should now be in the suitable form, so emit the compare insn
4448      and then the conditional move.  */
4449
4450   comparison
4451     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4452
4453   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4454   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4455      return NULL and let the caller figure out how best to deal with this
4456      situation.  */
4457   if (GET_CODE (comparison) != code)
4458     return NULL_RTX;
4459
4460   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4461
4462   /* If that failed, then give up.  */
4463   if (insn == 0)
4464     return 0;
4465
4466   emit_insn (insn);
4467
4468   if (subtarget != target)
4469     convert_move (target, subtarget, 0);
4470
4471   return target;
4472 }
4473
4474 /* Return nonzero if a conditional move of mode MODE is supported.
4475
4476    This function is for combine so it can tell whether an insn that looks
4477    like a conditional move is actually supported by the hardware.  If we
4478    guess wrong we lose a bit on optimization, but that's it.  */
4479 /* ??? sparc64 supports conditionally moving integers values based on fp
4480    comparisons, and vice versa.  How do we handle them?  */
4481
4482 int
4483 can_conditionally_move_p (enum machine_mode mode)
4484 {
4485   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4486     return 1;
4487
4488   return 0;
4489 }
4490
4491 #endif /* HAVE_conditional_move */
4492
4493 /* Emit a conditional addition instruction if the machine supports one for that
4494    condition and machine mode.
4495
4496    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4497    the mode to use should they be constants.  If it is VOIDmode, they cannot
4498    both be constants.
4499
4500    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4501    should be stored there.  MODE is the mode to use should they be constants.
4502    If it is VOIDmode, they cannot both be constants.
4503
4504    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4505    is not supported.  */
4506
4507 rtx
4508 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4509                       enum machine_mode cmode, rtx op2, rtx op3,
4510                       enum machine_mode mode, int unsignedp)
4511 {
4512   rtx tem, subtarget, comparison, insn;
4513   enum insn_code icode;
4514   enum rtx_code reversed;
4515
4516   /* If one operand is constant, make it the second one.  Only do this
4517      if the other operand is not constant as well.  */
4518
4519   if (swap_commutative_operands_p (op0, op1))
4520     {
4521       tem = op0;
4522       op0 = op1;
4523       op1 = tem;
4524       code = swap_condition (code);
4525     }
4526
4527   /* get_condition will prefer to generate LT and GT even if the old
4528      comparison was against zero, so undo that canonicalization here since
4529      comparisons against zero are cheaper.  */
4530   if (code == LT && op1 == const1_rtx)
4531     code = LE, op1 = const0_rtx;
4532   else if (code == GT && op1 == constm1_rtx)
4533     code = GE, op1 = const0_rtx;
4534
4535   if (cmode == VOIDmode)
4536     cmode = GET_MODE (op0);
4537
4538   if (swap_commutative_operands_p (op2, op3)
4539       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4540           != UNKNOWN))
4541     {
4542       tem = op2;
4543       op2 = op3;
4544       op3 = tem;
4545       code = reversed;
4546     }
4547
4548   if (mode == VOIDmode)
4549     mode = GET_MODE (op2);
4550
4551   icode = optab_handler (addcc_optab, mode)->insn_code;
4552
4553   if (icode == CODE_FOR_nothing)
4554     return 0;
4555
4556   if (!target)
4557     target = gen_reg_rtx (mode);
4558
4559   /* If the insn doesn't accept these operands, put them in pseudos.  */
4560
4561   if (!insn_data[icode].operand[0].predicate
4562       (target, insn_data[icode].operand[0].mode))
4563     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4564   else
4565     subtarget = target;
4566
4567   if (!insn_data[icode].operand[2].predicate
4568       (op2, insn_data[icode].operand[2].mode))
4569     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4570
4571   if (!insn_data[icode].operand[3].predicate
4572       (op3, insn_data[icode].operand[3].mode))
4573     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4574
4575   /* Everything should now be in the suitable form, so emit the compare insn
4576      and then the conditional move.  */
4577
4578   comparison
4579     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4580
4581   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4582   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4583      return NULL and let the caller figure out how best to deal with this
4584      situation.  */
4585   if (GET_CODE (comparison) != code)
4586     return NULL_RTX;
4587
4588   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4589
4590   /* If that failed, then give up.  */
4591   if (insn == 0)
4592     return 0;
4593
4594   emit_insn (insn);
4595
4596   if (subtarget != target)
4597     convert_move (target, subtarget, 0);
4598
4599   return target;
4600 }
4601 \f
4602 /* These functions attempt to generate an insn body, rather than
4603    emitting the insn, but if the gen function already emits them, we
4604    make no attempt to turn them back into naked patterns.  */
4605
4606 /* Generate and return an insn body to add Y to X.  */
4607
4608 rtx
4609 gen_add2_insn (rtx x, rtx y)
4610 {
4611   int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4612
4613   gcc_assert (insn_data[icode].operand[0].predicate
4614               (x, insn_data[icode].operand[0].mode));
4615   gcc_assert (insn_data[icode].operand[1].predicate
4616               (x, insn_data[icode].operand[1].mode));
4617   gcc_assert (insn_data[icode].operand[2].predicate
4618               (y, insn_data[icode].operand[2].mode));
4619
4620   return GEN_FCN (icode) (x, x, y);
4621 }
4622
4623 /* Generate and return an insn body to add r1 and c,
4624    storing the result in r0.  */
4625 rtx
4626 gen_add3_insn (rtx r0, rtx r1, rtx c)
4627 {
4628   int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code;
4629
4630   if (icode == CODE_FOR_nothing
4631       || !(insn_data[icode].operand[0].predicate
4632            (r0, insn_data[icode].operand[0].mode))
4633       || !(insn_data[icode].operand[1].predicate
4634            (r1, insn_data[icode].operand[1].mode))
4635       || !(insn_data[icode].operand[2].predicate
4636            (c, insn_data[icode].operand[2].mode)))
4637     return NULL_RTX;
4638
4639   return GEN_FCN (icode) (r0, r1, c);
4640 }
4641
4642 int
4643 have_add2_insn (rtx x, rtx y)
4644 {
4645   int icode;
4646
4647   gcc_assert (GET_MODE (x) != VOIDmode);
4648
4649   icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4650
4651   if (icode == CODE_FOR_nothing)
4652     return 0;
4653
4654   if (!(insn_data[icode].operand[0].predicate
4655         (x, insn_data[icode].operand[0].mode))
4656       || !(insn_data[icode].operand[1].predicate
4657            (x, insn_data[icode].operand[1].mode))
4658       || !(insn_data[icode].operand[2].predicate
4659            (y, insn_data[icode].operand[2].mode)))
4660     return 0;
4661
4662   return 1;
4663 }
4664
4665 /* Generate and return an insn body to subtract Y from X.  */
4666
4667 rtx
4668 gen_sub2_insn (rtx x, rtx y)
4669 {
4670   int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4671
4672   gcc_assert (insn_data[icode].operand[0].predicate
4673               (x, insn_data[icode].operand[0].mode));
4674   gcc_assert (insn_data[icode].operand[1].predicate
4675               (x, insn_data[icode].operand[1].mode));
4676   gcc_assert  (insn_data[icode].operand[2].predicate
4677                (y, insn_data[icode].operand[2].mode));
4678
4679   return GEN_FCN (icode) (x, x, y);
4680 }
4681
4682 /* Generate and return an insn body to subtract r1 and c,
4683    storing the result in r0.  */
4684 rtx
4685 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4686 {
4687   int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code;
4688
4689   if (icode == CODE_FOR_nothing
4690       || !(insn_data[icode].operand[0].predicate
4691            (r0, insn_data[icode].operand[0].mode))
4692       || !(insn_data[icode].operand[1].predicate
4693            (r1, insn_data[icode].operand[1].mode))
4694       || !(insn_data[icode].operand[2].predicate
4695            (c, insn_data[icode].operand[2].mode)))
4696     return NULL_RTX;
4697
4698   return GEN_FCN (icode) (r0, r1, c);
4699 }
4700
4701 int
4702 have_sub2_insn (rtx x, rtx y)
4703 {
4704   int icode;
4705
4706   gcc_assert (GET_MODE (x) != VOIDmode);
4707
4708   icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4709
4710   if (icode == CODE_FOR_nothing)
4711     return 0;
4712
4713   if (!(insn_data[icode].operand[0].predicate
4714         (x, insn_data[icode].operand[0].mode))
4715       || !(insn_data[icode].operand[1].predicate
4716            (x, insn_data[icode].operand[1].mode))
4717       || !(insn_data[icode].operand[2].predicate
4718            (y, insn_data[icode].operand[2].mode)))
4719     return 0;
4720
4721   return 1;
4722 }
4723
4724 /* Generate the body of an instruction to copy Y into X.
4725    It may be a list of insns, if one insn isn't enough.  */
4726
4727 rtx
4728 gen_move_insn (rtx x, rtx y)
4729 {
4730   rtx seq;
4731
4732   start_sequence ();
4733   emit_move_insn_1 (x, y);
4734   seq = get_insns ();
4735   end_sequence ();
4736   return seq;
4737 }
4738 \f
4739 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4740    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4741    no such operation exists, CODE_FOR_nothing will be returned.  */
4742
4743 enum insn_code
4744 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4745               int unsignedp)
4746 {
4747   convert_optab tab;
4748 #ifdef HAVE_ptr_extend
4749   if (unsignedp < 0)
4750     return CODE_FOR_ptr_extend;
4751 #endif
4752
4753   tab = unsignedp ? zext_optab : sext_optab;
4754   return convert_optab_handler (tab, to_mode, from_mode)->insn_code;
4755 }
4756
4757 /* Generate the body of an insn to extend Y (with mode MFROM)
4758    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4759
4760 rtx
4761 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4762                  enum machine_mode mfrom, int unsignedp)
4763 {
4764   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4765   return GEN_FCN (icode) (x, y);
4766 }
4767 \f
4768 /* can_fix_p and can_float_p say whether the target machine
4769    can directly convert a given fixed point type to
4770    a given floating point type, or vice versa.
4771    The returned value is the CODE_FOR_... value to use,
4772    or CODE_FOR_nothing if these modes cannot be directly converted.
4773
4774    *TRUNCP_PTR is set to 1 if it is necessary to output
4775    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4776
4777 static enum insn_code
4778 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4779            int unsignedp, int *truncp_ptr)
4780 {
4781   convert_optab tab;
4782   enum insn_code icode;
4783
4784   tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4785   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4786   if (icode != CODE_FOR_nothing)
4787     {
4788       *truncp_ptr = 0;
4789       return icode;
4790     }
4791
4792   /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4793      for this to work. We need to rework the fix* and ftrunc* patterns
4794      and documentation.  */
4795   tab = unsignedp ? ufix_optab : sfix_optab;
4796   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4797   if (icode != CODE_FOR_nothing
4798       && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing)
4799     {
4800       *truncp_ptr = 1;
4801       return icode;
4802     }
4803
4804   *truncp_ptr = 0;
4805   return CODE_FOR_nothing;
4806 }
4807
4808 static enum insn_code
4809 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4810              int unsignedp)
4811 {
4812   convert_optab tab;
4813
4814   tab = unsignedp ? ufloat_optab : sfloat_optab;
4815   return convert_optab_handler (tab, fltmode, fixmode)->insn_code;
4816 }
4817 \f
4818 /* Generate code to convert FROM to floating point
4819    and store in TO.  FROM must be fixed point and not VOIDmode.
4820    UNSIGNEDP nonzero means regard FROM as unsigned.
4821    Normally this is done by correcting the final value
4822    if it is negative.  */
4823
4824 void
4825 expand_float (rtx to, rtx from, int unsignedp)
4826 {
4827   enum insn_code icode;
4828   rtx target = to;
4829   enum machine_mode fmode, imode;
4830   bool can_do_signed = false;
4831
4832   /* Crash now, because we won't be able to decide which mode to use.  */
4833   gcc_assert (GET_MODE (from) != VOIDmode);
4834
4835   /* Look for an insn to do the conversion.  Do it in the specified
4836      modes if possible; otherwise convert either input, output or both to
4837      wider mode.  If the integer mode is wider than the mode of FROM,
4838      we can do the conversion signed even if the input is unsigned.  */
4839
4840   for (fmode = GET_MODE (to); fmode != VOIDmode;
4841        fmode = GET_MODE_WIDER_MODE (fmode))
4842     for (imode = GET_MODE (from); imode != VOIDmode;
4843          imode = GET_MODE_WIDER_MODE (imode))
4844       {
4845         int doing_unsigned = unsignedp;
4846
4847         if (fmode != GET_MODE (to)
4848             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4849           continue;
4850
4851         icode = can_float_p (fmode, imode, unsignedp);
4852         if (icode == CODE_FOR_nothing && unsignedp)
4853           {
4854             enum insn_code scode = can_float_p (fmode, imode, 0);
4855             if (scode != CODE_FOR_nothing)
4856               can_do_signed = true;
4857             if (imode != GET_MODE (from))
4858               icode = scode, doing_unsigned = 0;
4859           }
4860
4861         if (icode != CODE_FOR_nothing)
4862           {
4863             if (imode != GET_MODE (from))
4864               from = convert_to_mode (imode, from, unsignedp);
4865
4866             if (fmode != GET_MODE (to))
4867               target = gen_reg_rtx (fmode);
4868
4869             emit_unop_insn (icode, target, from,
4870                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4871
4872             if (target != to)
4873               convert_move (to, target, 0);
4874             return;
4875           }
4876       }
4877
4878   /* Unsigned integer, and no way to convert directly.  For binary
4879      floating point modes, convert as signed, then conditionally adjust
4880      the result.  */
4881   if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
4882     {
4883       rtx label = gen_label_rtx ();
4884       rtx temp;
4885       REAL_VALUE_TYPE offset;
4886
4887       /* Look for a usable floating mode FMODE wider than the source and at
4888          least as wide as the target.  Using FMODE will avoid rounding woes
4889          with unsigned values greater than the signed maximum value.  */
4890
4891       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4892            fmode = GET_MODE_WIDER_MODE (fmode))
4893         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4894             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4895           break;
4896
4897       if (fmode == VOIDmode)
4898         {
4899           /* There is no such mode.  Pretend the target is wide enough.  */
4900           fmode = GET_MODE (to);
4901
4902           /* Avoid double-rounding when TO is narrower than FROM.  */
4903           if ((significand_size (fmode) + 1)
4904               < GET_MODE_BITSIZE (GET_MODE (from)))
4905             {
4906               rtx temp1;
4907               rtx neglabel = gen_label_rtx ();
4908
4909               /* Don't use TARGET if it isn't a register, is a hard register,
4910                  or is the wrong mode.  */
4911               if (!REG_P (target)
4912                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4913                   || GET_MODE (target) != fmode)
4914                 target = gen_reg_rtx (fmode);
4915
4916               imode = GET_MODE (from);
4917               do_pending_stack_adjust ();
4918
4919               /* Test whether the sign bit is set.  */
4920               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4921                                        0, neglabel);
4922
4923               /* The sign bit is not set.  Convert as signed.  */
4924               expand_float (target, from, 0);
4925               emit_jump_insn (gen_jump (label));
4926               emit_barrier ();
4927
4928               /* The sign bit is set.
4929                  Convert to a usable (positive signed) value by shifting right
4930                  one bit, while remembering if a nonzero bit was shifted
4931                  out; i.e., compute  (from & 1) | (from >> 1).  */
4932
4933               emit_label (neglabel);
4934               temp = expand_binop (imode, and_optab, from, const1_rtx,
4935                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4936               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4937                                     NULL_RTX, 1);
4938               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4939                                    OPTAB_LIB_WIDEN);
4940               expand_float (target, temp, 0);
4941
4942               /* Multiply by 2 to undo the shift above.  */
4943               temp = expand_binop (fmode, add_optab, target, target,
4944                                    target, 0, OPTAB_LIB_WIDEN);
4945               if (temp != target)
4946                 emit_move_insn (target, temp);
4947
4948               do_pending_stack_adjust ();
4949               emit_label (label);
4950               goto done;
4951             }
4952         }
4953
4954       /* If we are about to do some arithmetic to correct for an
4955          unsigned operand, do it in a pseudo-register.  */
4956
4957       if (GET_MODE (to) != fmode
4958           || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4959         target = gen_reg_rtx (fmode);
4960
4961       /* Convert as signed integer to floating.  */
4962       expand_float (target, from, 0);
4963
4964       /* If FROM is negative (and therefore TO is negative),
4965          correct its value by 2**bitwidth.  */
4966
4967       do_pending_stack_adjust ();
4968       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4969                                0, label);
4970
4971
4972       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4973       temp = expand_binop (fmode, add_optab, target,
4974                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4975                            target, 0, OPTAB_LIB_WIDEN);
4976       if (temp != target)
4977         emit_move_insn (target, temp);
4978
4979       do_pending_stack_adjust ();
4980       emit_label (label);
4981       goto done;
4982     }
4983
4984   /* No hardware instruction available; call a library routine.  */
4985     {
4986       rtx libfunc;
4987       rtx insns;
4988       rtx value;
4989       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4990
4991       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4992         from = convert_to_mode (SImode, from, unsignedp);
4993
4994       libfunc = convert_optab_handler (tab, GET_MODE (to),
4995                                        GET_MODE (from))->libfunc;
4996       gcc_assert (libfunc);
4997
4998       start_sequence ();
4999
5000       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5001                                        GET_MODE (to), 1, from,
5002                                        GET_MODE (from));
5003       insns = get_insns ();
5004       end_sequence ();
5005
5006       emit_libcall_block (insns, target, value,
5007                           gen_rtx_FLOAT (GET_MODE (to), from));
5008     }
5009
5010  done:
5011
5012   /* Copy result to requested destination
5013      if we have been computing in a temp location.  */
5014
5015   if (target != to)
5016     {
5017       if (GET_MODE (target) == GET_MODE (to))
5018         emit_move_insn (to, target);
5019       else
5020         convert_move (to, target, 0);
5021     }
5022 }
5023 \f
5024 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5025    must be floating point.  */
5026
5027 void
5028 expand_fix (rtx to, rtx from, int unsignedp)
5029 {
5030   enum insn_code icode;
5031   rtx target = to;
5032   enum machine_mode fmode, imode;
5033   int must_trunc = 0;
5034
5035   /* We first try to find a pair of modes, one real and one integer, at
5036      least as wide as FROM and TO, respectively, in which we can open-code
5037      this conversion.  If the integer mode is wider than the mode of TO,
5038      we can do the conversion either signed or unsigned.  */
5039
5040   for (fmode = GET_MODE (from); fmode != VOIDmode;
5041        fmode = GET_MODE_WIDER_MODE (fmode))
5042     for (imode = GET_MODE (to); imode != VOIDmode;
5043          imode = GET_MODE_WIDER_MODE (imode))
5044       {
5045         int doing_unsigned = unsignedp;
5046
5047         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5048         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5049           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5050
5051         if (icode != CODE_FOR_nothing)
5052           {
5053             if (fmode != GET_MODE (from))
5054               from = convert_to_mode (fmode, from, 0);
5055
5056             if (must_trunc)
5057               {
5058                 rtx temp = gen_reg_rtx (GET_MODE (from));
5059                 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5060                                     temp, 0);
5061               }
5062
5063             if (imode != GET_MODE (to))
5064               target = gen_reg_rtx (imode);
5065
5066             emit_unop_insn (icode, target, from,
5067                             doing_unsigned ? UNSIGNED_FIX : FIX);
5068             if (target != to)
5069               convert_move (to, target, unsignedp);
5070             return;
5071           }
5072       }
5073
5074   /* For an unsigned conversion, there is one more way to do it.
5075      If we have a signed conversion, we generate code that compares
5076      the real value to the largest representable positive number.  If if
5077      is smaller, the conversion is done normally.  Otherwise, subtract
5078      one plus the highest signed number, convert, and add it back.
5079
5080      We only need to check all real modes, since we know we didn't find
5081      anything with a wider integer mode.
5082
5083      This code used to extend FP value into mode wider than the destination.
5084      This is not needed.  Consider, for instance conversion from SFmode
5085      into DImode.
5086
5087      The hot path through the code is dealing with inputs smaller than 2^63
5088      and doing just the conversion, so there is no bits to lose.
5089
5090      In the other path we know the value is positive in the range 2^63..2^64-1
5091      inclusive.  (as for other imput overflow happens and result is undefined)
5092      So we know that the most important bit set in mantissa corresponds to
5093      2^63.  The subtraction of 2^63 should not generate any rounding as it
5094      simply clears out that bit.  The rest is trivial.  */
5095
5096   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5097     for (fmode = GET_MODE (from); fmode != VOIDmode;
5098          fmode = GET_MODE_WIDER_MODE (fmode))
5099       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
5100                                          &must_trunc))
5101         {
5102           int bitsize;
5103           REAL_VALUE_TYPE offset;
5104           rtx limit, lab1, lab2, insn;
5105
5106           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5107           real_2expN (&offset, bitsize - 1);
5108           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5109           lab1 = gen_label_rtx ();
5110           lab2 = gen_label_rtx ();
5111
5112           if (fmode != GET_MODE (from))
5113             from = convert_to_mode (fmode, from, 0);
5114
5115           /* See if we need to do the subtraction.  */
5116           do_pending_stack_adjust ();
5117           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5118                                    0, lab1);
5119
5120           /* If not, do the signed "fix" and branch around fixup code.  */
5121           expand_fix (to, from, 0);
5122           emit_jump_insn (gen_jump (lab2));
5123           emit_barrier ();
5124
5125           /* Otherwise, subtract 2**(N-1), convert to signed number,
5126              then add 2**(N-1).  Do the addition using XOR since this
5127              will often generate better code.  */
5128           emit_label (lab1);
5129           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5130                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
5131           expand_fix (to, target, 0);
5132           target = expand_binop (GET_MODE (to), xor_optab, to,
5133                                  gen_int_mode
5134                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
5135                                   GET_MODE (to)),
5136                                  to, 1, OPTAB_LIB_WIDEN);
5137
5138           if (target != to)
5139             emit_move_insn (to, target);
5140
5141           emit_label (lab2);
5142
5143           if (optab_handler (mov_optab, GET_MODE (to))->insn_code
5144               != CODE_FOR_nothing)
5145             {
5146               /* Make a place for a REG_NOTE and add it.  */
5147               insn = emit_move_insn (to, to);
5148               set_unique_reg_note (insn,
5149                                    REG_EQUAL,
5150                                    gen_rtx_fmt_e (UNSIGNED_FIX,
5151                                                   GET_MODE (to),
5152                                                   copy_rtx (from)));
5153             }
5154
5155           return;
5156         }
5157
5158   /* We can't do it with an insn, so use a library call.  But first ensure
5159      that the mode of TO is at least as wide as SImode, since those are the
5160      only library calls we know about.  */
5161
5162   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5163     {
5164       target = gen_reg_rtx (SImode);
5165
5166       expand_fix (target, from, unsignedp);
5167     }
5168   else
5169     {
5170       rtx insns;
5171       rtx value;
5172       rtx libfunc;
5173
5174       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5175       libfunc = convert_optab_handler (tab, GET_MODE (to),
5176                                        GET_MODE (from))->libfunc;
5177       gcc_assert (libfunc);
5178
5179       start_sequence ();
5180
5181       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5182                                        GET_MODE (to), 1, from,
5183                                        GET_MODE (from));
5184       insns = get_insns ();
5185       end_sequence ();
5186
5187       emit_libcall_block (insns, target, value,
5188                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5189                                          GET_MODE (to), from));
5190     }
5191
5192   if (target != to)
5193     {
5194       if (GET_MODE (to) == GET_MODE (target))
5195         emit_move_insn (to, target);
5196       else
5197         convert_move (to, target, 0);
5198     }
5199 }
5200
5201 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5202    must be floating point, TO must be signed.  Use the conversion optab
5203    TAB to do the conversion.  */
5204
5205 bool
5206 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5207 {
5208   enum insn_code icode;
5209   rtx target = to;
5210   enum machine_mode fmode, imode;
5211
5212   /* We first try to find a pair of modes, one real and one integer, at
5213      least as wide as FROM and TO, respectively, in which we can open-code
5214      this conversion.  If the integer mode is wider than the mode of TO,
5215      we can do the conversion either signed or unsigned.  */
5216
5217   for (fmode = GET_MODE (from); fmode != VOIDmode;
5218        fmode = GET_MODE_WIDER_MODE (fmode))
5219     for (imode = GET_MODE (to); imode != VOIDmode;
5220          imode = GET_MODE_WIDER_MODE (imode))
5221       {
5222         icode = convert_optab_handler (tab, imode, fmode)->insn_code;
5223         if (icode != CODE_FOR_nothing)
5224           {
5225             if (fmode != GET_MODE (from))
5226               from = convert_to_mode (fmode, from, 0);
5227
5228             if (imode != GET_MODE (to))
5229               target = gen_reg_rtx (imode);
5230
5231             emit_unop_insn (icode, target, from, UNKNOWN);
5232             if (target != to)
5233               convert_move (to, target, 0);
5234             return true;
5235           }
5236       }
5237
5238   return false;
5239 }
5240 \f
5241 /* Report whether we have an instruction to perform the operation
5242    specified by CODE on operands of mode MODE.  */
5243 int
5244 have_insn_for (enum rtx_code code, enum machine_mode mode)
5245 {
5246   return (code_to_optab[(int) code] != 0
5247           && (optab_handler (code_to_optab[(int) code], mode)->insn_code
5248               != CODE_FOR_nothing));
5249 }
5250
5251 /* Create a blank optab.  */
5252 static optab
5253 new_optab (void)
5254 {
5255   int i;
5256   optab op = ggc_alloc (sizeof (struct optab));
5257   for (i = 0; i < NUM_MACHINE_MODES; i++)
5258     {
5259       optab_handler (op, i)->insn_code = CODE_FOR_nothing;
5260       optab_handler (op, i)->libfunc = 0;
5261     }
5262
5263   return op;
5264 }
5265
5266 static convert_optab
5267 new_convert_optab (void)
5268 {
5269   int i, j;
5270   convert_optab op = ggc_alloc (sizeof (struct convert_optab));
5271   for (i = 0; i < NUM_MACHINE_MODES; i++)
5272     for (j = 0; j < NUM_MACHINE_MODES; j++)
5273       {
5274         convert_optab_handler (op, i, j)->insn_code = CODE_FOR_nothing;
5275         convert_optab_handler (op, i, j)->libfunc = 0;
5276       }
5277   return op;
5278 }
5279
5280 /* Same, but fill in its code as CODE, and write it into the
5281    code_to_optab table.  */
5282 static inline optab
5283 init_optab (enum rtx_code code)
5284 {
5285   optab op = new_optab ();
5286   op->code = code;
5287   code_to_optab[(int) code] = op;
5288   return op;
5289 }
5290
5291 /* Same, but fill in its code as CODE, and do _not_ write it into
5292    the code_to_optab table.  */
5293 static inline optab
5294 init_optabv (enum rtx_code code)
5295 {
5296   optab op = new_optab ();
5297   op->code = code;
5298   return op;
5299 }
5300
5301 /* Conversion optabs never go in the code_to_optab table.  */
5302 static inline convert_optab
5303 init_convert_optab (enum rtx_code code)
5304 {
5305   convert_optab op = new_convert_optab ();
5306   op->code = code;
5307   return op;
5308 }
5309
5310 /* Initialize the libfunc fields of an entire group of entries in some
5311    optab.  Each entry is set equal to a string consisting of a leading
5312    pair of underscores followed by a generic operation name followed by
5313    a mode name (downshifted to lowercase) followed by a single character
5314    representing the number of operands for the given operation (which is
5315    usually one of the characters '2', '3', or '4').
5316
5317    OPTABLE is the table in which libfunc fields are to be initialized.
5318    FIRST_MODE is the first machine mode index in the given optab to
5319      initialize.
5320    LAST_MODE is the last machine mode index in the given optab to
5321      initialize.
5322    OPNAME is the generic (string) name of the operation.
5323    SUFFIX is the character which specifies the number of operands for
5324      the given generic operation.
5325 */
5326
5327 static void
5328 init_libfuncs (optab optable, int first_mode, int last_mode,
5329                const char *opname, int suffix)
5330 {
5331   int mode;
5332   unsigned opname_len = strlen (opname);
5333
5334   for (mode = first_mode; (int) mode <= (int) last_mode;
5335        mode = (enum machine_mode) ((int) mode + 1))
5336     {
5337       const char *mname = GET_MODE_NAME (mode);
5338       unsigned mname_len = strlen (mname);
5339       char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5340       char *p;
5341       const char *q;
5342
5343       p = libfunc_name;
5344       *p++ = '_';
5345       *p++ = '_';
5346       for (q = opname; *q; )
5347         *p++ = *q++;
5348       for (q = mname; *q; q++)
5349         *p++ = TOLOWER (*q);
5350       *p++ = suffix;
5351       *p = '\0';
5352
5353       optab_handler (optable, mode)->libfunc
5354         = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5355     }
5356 }
5357
5358 /* Initialize the libfunc fields of an entire group of entries in some
5359    optab which correspond to all integer mode operations.  The parameters
5360    have the same meaning as similarly named ones for the `init_libfuncs'
5361    routine.  (See above).  */
5362
5363 static void
5364 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5365 {
5366   int maxsize = 2*BITS_PER_WORD;
5367   if (maxsize < LONG_LONG_TYPE_SIZE)
5368     maxsize = LONG_LONG_TYPE_SIZE;
5369   init_libfuncs (optable, word_mode,
5370                  mode_for_size (maxsize, MODE_INT, 0),
5371                  opname, suffix);
5372 }
5373
5374 /* Initialize the libfunc fields of an entire group of entries in some
5375    optab which correspond to all real mode operations.  The parameters
5376    have the same meaning as similarly named ones for the `init_libfuncs'
5377    routine.  (See above).  */
5378
5379 static void
5380 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5381 {
5382   char *dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
5383
5384   /* For BID support, change the name to have either a bid_ or dpd_ prefix
5385      depending on the low level floating format used.  */
5386   memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5387   strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5388
5389   init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5390   init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
5391                  dec_opname, suffix);
5392 }
5393
5394 /* Initialize the libfunc fields of an entire group of entries of an
5395    inter-mode-class conversion optab.  The string formation rules are
5396    similar to the ones for init_libfuncs, above, but instead of having
5397    a mode name and an operand count these functions have two mode names
5398    and no operand count.  */
5399 static void
5400 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5401                                enum mode_class from_class,
5402                                enum mode_class to_class)
5403 {
5404   enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5405   enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5406   size_t opname_len = strlen (opname);
5407   size_t max_mname_len = 0;
5408
5409   enum machine_mode fmode, tmode;
5410   const char *fname, *tname;
5411   const char *q;
5412   char *libfunc_name, *suffix;
5413   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5414   char *p;
5415
5416   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5417      depends on which underlying decimal floating point format is used.  */
5418   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5419
5420   for (fmode = first_from_mode;
5421        fmode != VOIDmode;
5422        fmode = GET_MODE_WIDER_MODE (fmode))
5423     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5424
5425   for (tmode = first_to_mode;
5426        tmode != VOIDmode;
5427        tmode = GET_MODE_WIDER_MODE (tmode))
5428     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5429
5430   nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5431   nondec_name[0] = '_';
5432   nondec_name[1] = '_';
5433   memcpy (&nondec_name[2], opname, opname_len);
5434   nondec_suffix = nondec_name + opname_len + 2;
5435
5436   dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
5437   dec_name[0] = '_';
5438   dec_name[1] = '_';
5439   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5440   memcpy (&dec_name[2+dec_len], opname, opname_len);
5441   dec_suffix = dec_name + dec_len + opname_len + 2;
5442
5443   for (fmode = first_from_mode; fmode != VOIDmode;
5444        fmode = GET_MODE_WIDER_MODE (fmode))
5445     for (tmode = first_to_mode; tmode != VOIDmode;
5446          tmode = GET_MODE_WIDER_MODE (tmode))
5447       {
5448         fname = GET_MODE_NAME (fmode);
5449         tname = GET_MODE_NAME (tmode);
5450
5451         if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5452           {
5453             libfunc_name = dec_name;
5454             suffix = dec_suffix;
5455           }
5456         else
5457           {
5458             libfunc_name = nondec_name;
5459             suffix = nondec_suffix;
5460           }
5461
5462         p = suffix;
5463         for (q = fname; *q; p++, q++)
5464           *p = TOLOWER (*q);
5465         for (q = tname; *q; p++, q++)
5466           *p = TOLOWER (*q);
5467
5468         *p = '\0';
5469
5470         convert_optab_handler (tab, tmode, fmode)->libfunc
5471           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5472                                                 p - libfunc_name));
5473       }
5474 }
5475
5476 /* Initialize the libfunc fields of an entire group of entries of an
5477    intra-mode-class conversion optab.  The string formation rules are
5478    similar to the ones for init_libfunc, above.  WIDENING says whether
5479    the optab goes from narrow to wide modes or vice versa.  These functions
5480    have two mode names _and_ an operand count.  */
5481 static void
5482 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5483                                enum mode_class class, bool widening)
5484 {
5485   enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5486   size_t opname_len = strlen (opname);
5487   size_t max_mname_len = 0;
5488
5489   enum machine_mode nmode, wmode;
5490   const char *nname, *wname;
5491   const char *q;
5492   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5493   char *libfunc_name, *suffix;
5494   char *p;
5495
5496   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5497      depends on which underlying decimal floating point format is used.  */
5498   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5499
5500   for (nmode = first_mode; nmode != VOIDmode;
5501        nmode = GET_MODE_WIDER_MODE (nmode))
5502     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5503
5504   nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5505   nondec_name[0] = '_';
5506   nondec_name[1] = '_';
5507   memcpy (&nondec_name[2], opname, opname_len);
5508   nondec_suffix = nondec_name + opname_len + 2;
5509
5510   dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
5511   dec_name[0] = '_';
5512   dec_name[1] = '_';
5513   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5514   memcpy (&dec_name[2 + dec_len], opname, opname_len);
5515   dec_suffix = dec_name + dec_len + opname_len + 2;
5516
5517   for (nmode = first_mode; nmode != VOIDmode;
5518        nmode = GET_MODE_WIDER_MODE (nmode))
5519     for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5520          wmode = GET_MODE_WIDER_MODE (wmode))
5521       {
5522         nname = GET_MODE_NAME (nmode);
5523         wname = GET_MODE_NAME (wmode);
5524
5525         if (DECIMAL_FLOAT_MODE_P(nmode) || DECIMAL_FLOAT_MODE_P(wmode))
5526           {
5527             libfunc_name = dec_name;
5528             suffix = dec_suffix;
5529           }
5530         else
5531           {
5532             libfunc_name = nondec_name;
5533             suffix = nondec_suffix;
5534           }
5535
5536         p = suffix;
5537         for (q = widening ? nname : wname; *q; p++, q++)
5538           *p = TOLOWER (*q);
5539         for (q = widening ? wname : nname; *q; p++, q++)
5540           *p = TOLOWER (*q);
5541
5542         *p++ = '2';
5543         *p = '\0';
5544
5545         convert_optab_handler(tab, widening ? wmode : nmode,
5546                               widening ? nmode : wmode)->libfunc
5547           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5548                                                 p - libfunc_name));
5549       }
5550 }
5551
5552
5553 rtx
5554 init_one_libfunc (const char *name)
5555 {
5556   rtx symbol;
5557
5558   /* Create a FUNCTION_DECL that can be passed to
5559      targetm.encode_section_info.  */
5560   /* ??? We don't have any type information except for this is
5561      a function.  Pretend this is "int foo()".  */
5562   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5563                           build_function_type (integer_type_node, NULL_TREE));
5564   DECL_ARTIFICIAL (decl) = 1;
5565   DECL_EXTERNAL (decl) = 1;
5566   TREE_PUBLIC (decl) = 1;
5567
5568   symbol = XEXP (DECL_RTL (decl), 0);
5569
5570   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
5571      are the flags assigned by targetm.encode_section_info.  */
5572   SET_SYMBOL_REF_DECL (symbol, 0);
5573
5574   return symbol;
5575 }
5576
5577 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5578    MODE to NAME, which should be either 0 or a string constant.  */
5579 void
5580 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5581 {
5582   if (name)
5583     optab_handler (optable, mode)->libfunc = init_one_libfunc (name);
5584   else
5585     optab_handler (optable, mode)->libfunc = 0;
5586 }
5587
5588 /* Call this to reset the function entry for one conversion optab
5589    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5590    either 0 or a string constant.  */
5591 void
5592 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5593                   enum machine_mode fmode, const char *name)
5594 {
5595   if (name)
5596     convert_optab_handler (optable, tmode, fmode)->libfunc
5597       = init_one_libfunc (name);
5598   else
5599     convert_optab_handler (optable, tmode, fmode)->libfunc = 0;
5600 }
5601
5602 /* Call this to initialize the contents of the optabs
5603    appropriately for the current target machine.  */
5604
5605 void
5606 init_optabs (void)
5607 {
5608   unsigned int i;
5609   enum machine_mode int_mode;
5610
5611   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5612
5613   for (i = 0; i < NUM_RTX_CODE; i++)
5614     setcc_gen_code[i] = CODE_FOR_nothing;
5615
5616 #ifdef HAVE_conditional_move
5617   for (i = 0; i < NUM_MACHINE_MODES; i++)
5618     movcc_gen_code[i] = CODE_FOR_nothing;
5619 #endif
5620
5621   for (i = 0; i < NUM_MACHINE_MODES; i++)
5622     {
5623       vcond_gen_code[i] = CODE_FOR_nothing;
5624       vcondu_gen_code[i] = CODE_FOR_nothing;
5625     }
5626
5627   add_optab = init_optab (PLUS);
5628   addv_optab = init_optabv (PLUS);
5629   sub_optab = init_optab (MINUS);
5630   subv_optab = init_optabv (MINUS);
5631   smul_optab = init_optab (MULT);
5632   smulv_optab = init_optabv (MULT);
5633   smul_highpart_optab = init_optab (UNKNOWN);
5634   umul_highpart_optab = init_optab (UNKNOWN);
5635   smul_widen_optab = init_optab (UNKNOWN);
5636   umul_widen_optab = init_optab (UNKNOWN);
5637   usmul_widen_optab = init_optab (UNKNOWN);
5638   smadd_widen_optab = init_optab (UNKNOWN);
5639   umadd_widen_optab = init_optab (UNKNOWN);
5640   smsub_widen_optab = init_optab (UNKNOWN);
5641   umsub_widen_optab = init_optab (UNKNOWN);
5642   sdiv_optab = init_optab (DIV);
5643   sdivv_optab = init_optabv (DIV);
5644   sdivmod_optab = init_optab (UNKNOWN);
5645   udiv_optab = init_optab (UDIV);
5646   udivmod_optab = init_optab (UNKNOWN);
5647   smod_optab = init_optab (MOD);
5648   umod_optab = init_optab (UMOD);
5649   fmod_optab = init_optab (UNKNOWN);
5650   remainder_optab = init_optab (UNKNOWN);
5651   ftrunc_optab = init_optab (UNKNOWN);
5652   and_optab = init_optab (AND);
5653   ior_optab = init_optab (IOR);
5654   xor_optab = init_optab (XOR);
5655   ashl_optab = init_optab (ASHIFT);
5656   ashr_optab = init_optab (ASHIFTRT);
5657   lshr_optab = init_optab (LSHIFTRT);
5658   rotl_optab = init_optab (ROTATE);
5659   rotr_optab = init_optab (ROTATERT);
5660   smin_optab = init_optab (SMIN);
5661   smax_optab = init_optab (SMAX);
5662   umin_optab = init_optab (UMIN);
5663   umax_optab = init_optab (UMAX);
5664   pow_optab = init_optab (UNKNOWN);
5665   atan2_optab = init_optab (UNKNOWN);
5666
5667   /* These three have codes assigned exclusively for the sake of
5668      have_insn_for.  */
5669   mov_optab = init_optab (SET);
5670   movstrict_optab = init_optab (STRICT_LOW_PART);
5671   cmp_optab = init_optab (COMPARE);
5672
5673   storent_optab = init_optab (UNKNOWN);
5674
5675   ucmp_optab = init_optab (UNKNOWN);
5676   tst_optab = init_optab (UNKNOWN);
5677
5678   eq_optab = init_optab (EQ);
5679   ne_optab = init_optab (NE);
5680   gt_optab = init_optab (GT);
5681   ge_optab = init_optab (GE);
5682   lt_optab = init_optab (LT);
5683   le_optab = init_optab (LE);
5684   unord_optab = init_optab (UNORDERED);
5685
5686   neg_optab = init_optab (NEG);
5687   negv_optab = init_optabv (NEG);
5688   abs_optab = init_optab (ABS);
5689   absv_optab = init_optabv (ABS);
5690   addcc_optab = init_optab (UNKNOWN);
5691   one_cmpl_optab = init_optab (NOT);
5692   bswap_optab = init_optab (BSWAP);
5693   ffs_optab = init_optab (FFS);
5694   clz_optab = init_optab (CLZ);
5695   ctz_optab = init_optab (CTZ);
5696   popcount_optab = init_optab (POPCOUNT);
5697   parity_optab = init_optab (PARITY);
5698   sqrt_optab = init_optab (SQRT);
5699   floor_optab = init_optab (UNKNOWN);
5700   ceil_optab = init_optab (UNKNOWN);
5701   round_optab = init_optab (UNKNOWN);
5702   btrunc_optab = init_optab (UNKNOWN);
5703   nearbyint_optab = init_optab (UNKNOWN);
5704   rint_optab = init_optab (UNKNOWN);
5705   sincos_optab = init_optab (UNKNOWN);
5706   sin_optab = init_optab (UNKNOWN);
5707   asin_optab = init_optab (UNKNOWN);
5708   cos_optab = init_optab (UNKNOWN);
5709   acos_optab = init_optab (UNKNOWN);
5710   exp_optab = init_optab (UNKNOWN);
5711   exp10_optab = init_optab (UNKNOWN);
5712   exp2_optab = init_optab (UNKNOWN);
5713   expm1_optab = init_optab (UNKNOWN);
5714   ldexp_optab = init_optab (UNKNOWN);
5715   scalb_optab = init_optab (UNKNOWN);
5716   logb_optab = init_optab (UNKNOWN);
5717   ilogb_optab = init_optab (UNKNOWN);
5718   log_optab = init_optab (UNKNOWN);
5719   log10_optab = init_optab (UNKNOWN);
5720   log2_optab = init_optab (UNKNOWN);
5721   log1p_optab = init_optab (UNKNOWN);
5722   tan_optab = init_optab (UNKNOWN);
5723   atan_optab = init_optab (UNKNOWN);
5724   copysign_optab = init_optab (UNKNOWN);
5725   signbit_optab = init_optab (UNKNOWN);
5726
5727   isinf_optab = init_optab (UNKNOWN);
5728
5729   strlen_optab = init_optab (UNKNOWN);
5730   cbranch_optab = init_optab (UNKNOWN);
5731   cmov_optab = init_optab (UNKNOWN);
5732   cstore_optab = init_optab (UNKNOWN);
5733   push_optab = init_optab (UNKNOWN);
5734
5735   reduc_smax_optab = init_optab (UNKNOWN);
5736   reduc_umax_optab = init_optab (UNKNOWN);
5737   reduc_smin_optab = init_optab (UNKNOWN);
5738   reduc_umin_optab = init_optab (UNKNOWN);
5739   reduc_splus_optab = init_optab (UNKNOWN);
5740   reduc_uplus_optab = init_optab (UNKNOWN);
5741
5742   ssum_widen_optab = init_optab (UNKNOWN);
5743   usum_widen_optab = init_optab (UNKNOWN);
5744   sdot_prod_optab = init_optab (UNKNOWN); 
5745   udot_prod_optab = init_optab (UNKNOWN);
5746
5747   vec_extract_optab = init_optab (UNKNOWN);
5748   vec_extract_even_optab = init_optab (UNKNOWN);
5749   vec_extract_odd_optab = init_optab (UNKNOWN);
5750   vec_interleave_high_optab = init_optab (UNKNOWN);
5751   vec_interleave_low_optab = init_optab (UNKNOWN);
5752   vec_set_optab = init_optab (UNKNOWN);
5753   vec_init_optab = init_optab (UNKNOWN);
5754   vec_shl_optab = init_optab (UNKNOWN);
5755   vec_shr_optab = init_optab (UNKNOWN);
5756   vec_realign_load_optab = init_optab (UNKNOWN);
5757   movmisalign_optab = init_optab (UNKNOWN);
5758   vec_widen_umult_hi_optab = init_optab (UNKNOWN);
5759   vec_widen_umult_lo_optab = init_optab (UNKNOWN);
5760   vec_widen_smult_hi_optab = init_optab (UNKNOWN);
5761   vec_widen_smult_lo_optab = init_optab (UNKNOWN);
5762   vec_unpacks_hi_optab = init_optab (UNKNOWN);
5763   vec_unpacks_lo_optab = init_optab (UNKNOWN);
5764   vec_unpacku_hi_optab = init_optab (UNKNOWN);
5765   vec_unpacku_lo_optab = init_optab (UNKNOWN);
5766   vec_unpacks_float_hi_optab = init_optab (UNKNOWN);
5767   vec_unpacks_float_lo_optab = init_optab (UNKNOWN);
5768   vec_unpacku_float_hi_optab = init_optab (UNKNOWN);
5769   vec_unpacku_float_lo_optab = init_optab (UNKNOWN);
5770   vec_pack_trunc_optab = init_optab (UNKNOWN);
5771   vec_pack_usat_optab = init_optab (UNKNOWN);
5772   vec_pack_ssat_optab = init_optab (UNKNOWN);
5773   vec_pack_ufix_trunc_optab = init_optab (UNKNOWN);
5774   vec_pack_sfix_trunc_optab = init_optab (UNKNOWN);
5775
5776   powi_optab = init_optab (UNKNOWN);
5777
5778   /* Conversions.  */
5779   sext_optab = init_convert_optab (SIGN_EXTEND);
5780   zext_optab = init_convert_optab (ZERO_EXTEND);
5781   trunc_optab = init_convert_optab (TRUNCATE);
5782   sfix_optab = init_convert_optab (FIX);
5783   ufix_optab = init_convert_optab (UNSIGNED_FIX);
5784   sfixtrunc_optab = init_convert_optab (UNKNOWN);
5785   ufixtrunc_optab = init_convert_optab (UNKNOWN);
5786   sfloat_optab = init_convert_optab (FLOAT);
5787   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5788   lrint_optab = init_convert_optab (UNKNOWN);
5789   lround_optab = init_convert_optab (UNKNOWN);
5790   lfloor_optab = init_convert_optab (UNKNOWN);
5791   lceil_optab = init_convert_optab (UNKNOWN);
5792
5793   for (i = 0; i < NUM_MACHINE_MODES; i++)
5794     {
5795       movmem_optab[i] = CODE_FOR_nothing;
5796       cmpstr_optab[i] = CODE_FOR_nothing;
5797       cmpstrn_optab[i] = CODE_FOR_nothing;
5798       cmpmem_optab[i] = CODE_FOR_nothing;
5799       setmem_optab[i] = CODE_FOR_nothing;
5800
5801       sync_add_optab[i] = CODE_FOR_nothing;
5802       sync_sub_optab[i] = CODE_FOR_nothing;
5803       sync_ior_optab[i] = CODE_FOR_nothing;
5804       sync_and_optab[i] = CODE_FOR_nothing;
5805       sync_xor_optab[i] = CODE_FOR_nothing;
5806       sync_nand_optab[i] = CODE_FOR_nothing;
5807       sync_old_add_optab[i] = CODE_FOR_nothing;
5808       sync_old_sub_optab[i] = CODE_FOR_nothing;
5809       sync_old_ior_optab[i] = CODE_FOR_nothing;
5810       sync_old_and_optab[i] = CODE_FOR_nothing;
5811       sync_old_xor_optab[i] = CODE_FOR_nothing;
5812       sync_old_nand_optab[i] = CODE_FOR_nothing;
5813       sync_new_add_optab[i] = CODE_FOR_nothing;
5814       sync_new_sub_optab[i] = CODE_FOR_nothing;
5815       sync_new_ior_optab[i] = CODE_FOR_nothing;
5816       sync_new_and_optab[i] = CODE_FOR_nothing;
5817       sync_new_xor_optab[i] = CODE_FOR_nothing;
5818       sync_new_nand_optab[i] = CODE_FOR_nothing;
5819       sync_compare_and_swap[i] = CODE_FOR_nothing;
5820       sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5821       sync_lock_test_and_set[i] = CODE_FOR_nothing;
5822       sync_lock_release[i] = CODE_FOR_nothing;
5823
5824       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5825     }
5826
5827   /* Fill in the optabs with the insns we support.  */
5828   init_all_optabs ();
5829
5830   /* The ffs function operates on `int'.  Fall back on it if we do not
5831      have a libgcc2 function for that width.  */
5832   int_mode = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
5833   optab_handler (ffs_optab, int_mode)->libfunc = init_one_libfunc ("ffs");
5834
5835   /* Initialize the optabs with the names of the library functions.  */
5836   init_integral_libfuncs (add_optab, "add", '3');
5837   init_floating_libfuncs (add_optab, "add", '3');
5838   init_integral_libfuncs (addv_optab, "addv", '3');
5839   init_floating_libfuncs (addv_optab, "add", '3');
5840   init_integral_libfuncs (sub_optab, "sub", '3');
5841   init_floating_libfuncs (sub_optab, "sub", '3');
5842   init_integral_libfuncs (subv_optab, "subv", '3');
5843   init_floating_libfuncs (subv_optab, "sub", '3');
5844   init_integral_libfuncs (smul_optab, "mul", '3');
5845   init_floating_libfuncs (smul_optab, "mul", '3');
5846   init_integral_libfuncs (smulv_optab, "mulv", '3');
5847   init_floating_libfuncs (smulv_optab, "mul", '3');
5848   init_integral_libfuncs (sdiv_optab, "div", '3');
5849   init_floating_libfuncs (sdiv_optab, "div", '3');
5850   init_integral_libfuncs (sdivv_optab, "divv", '3');
5851   init_integral_libfuncs (udiv_optab, "udiv", '3');
5852   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5853   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5854   init_integral_libfuncs (smod_optab, "mod", '3');
5855   init_integral_libfuncs (umod_optab, "umod", '3');
5856   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5857   init_integral_libfuncs (and_optab, "and", '3');
5858   init_integral_libfuncs (ior_optab, "ior", '3');
5859   init_integral_libfuncs (xor_optab, "xor", '3');
5860   init_integral_libfuncs (ashl_optab, "ashl", '3');
5861   init_integral_libfuncs (ashr_optab, "ashr", '3');
5862   init_integral_libfuncs (lshr_optab, "lshr", '3');
5863   init_integral_libfuncs (smin_optab, "min", '3');
5864   init_floating_libfuncs (smin_optab, "min", '3');
5865   init_integral_libfuncs (smax_optab, "max", '3');
5866   init_floating_libfuncs (smax_optab, "max", '3');
5867   init_integral_libfuncs (umin_optab, "umin", '3');
5868   init_integral_libfuncs (umax_optab, "umax", '3');
5869   init_integral_libfuncs (neg_optab, "neg", '2');
5870   init_floating_libfuncs (neg_optab, "neg", '2');
5871   init_integral_libfuncs (negv_optab, "negv", '2');
5872   init_floating_libfuncs (negv_optab, "neg", '2');
5873   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5874   init_integral_libfuncs (ffs_optab, "ffs", '2');
5875   init_integral_libfuncs (clz_optab, "clz", '2');
5876   init_integral_libfuncs (ctz_optab, "ctz", '2');
5877   init_integral_libfuncs (popcount_optab, "popcount", '2');
5878   init_integral_libfuncs (parity_optab, "parity", '2');
5879
5880   /* Comparison libcalls for integers MUST come in pairs,
5881      signed/unsigned.  */
5882   init_integral_libfuncs (cmp_optab, "cmp", '2');
5883   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5884   init_floating_libfuncs (cmp_optab, "cmp", '2');
5885
5886   /* EQ etc are floating point only.  */
5887   init_floating_libfuncs (eq_optab, "eq", '2');
5888   init_floating_libfuncs (ne_optab, "ne", '2');
5889   init_floating_libfuncs (gt_optab, "gt", '2');
5890   init_floating_libfuncs (ge_optab, "ge", '2');
5891   init_floating_libfuncs (lt_optab, "lt", '2');
5892   init_floating_libfuncs (le_optab, "le", '2');
5893   init_floating_libfuncs (unord_optab, "unord", '2');
5894
5895   init_floating_libfuncs (powi_optab, "powi", '2');
5896
5897   /* Conversions.  */
5898   init_interclass_conv_libfuncs (sfloat_optab, "float",
5899                                  MODE_INT, MODE_FLOAT);
5900   init_interclass_conv_libfuncs (sfloat_optab, "float",
5901                                  MODE_INT, MODE_DECIMAL_FLOAT);
5902   init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5903                                  MODE_INT, MODE_FLOAT);
5904   init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5905                                  MODE_INT, MODE_DECIMAL_FLOAT);
5906   init_interclass_conv_libfuncs (sfix_optab, "fix",
5907                                  MODE_FLOAT, MODE_INT);
5908   init_interclass_conv_libfuncs (sfix_optab, "fix",
5909                                  MODE_DECIMAL_FLOAT, MODE_INT);
5910   init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5911                                  MODE_FLOAT, MODE_INT);
5912   init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5913                                  MODE_DECIMAL_FLOAT, MODE_INT);
5914   init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
5915                                  MODE_INT, MODE_DECIMAL_FLOAT);
5916   init_interclass_conv_libfuncs (lrint_optab, "lrint",
5917                                  MODE_INT, MODE_FLOAT);
5918   init_interclass_conv_libfuncs (lround_optab, "lround",
5919                                  MODE_INT, MODE_FLOAT);
5920   init_interclass_conv_libfuncs (lfloor_optab, "lfloor",
5921                                  MODE_INT, MODE_FLOAT);
5922   init_interclass_conv_libfuncs (lceil_optab, "lceil",
5923                                  MODE_INT, MODE_FLOAT);
5924
5925   /* sext_optab is also used for FLOAT_EXTEND.  */
5926   init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5927   init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
5928   init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5929   init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5930   init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5931   init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
5932   init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5933   init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5934
5935   /* Explicitly initialize the bswap libfuncs since we need them to be
5936      valid for things other than word_mode.  */
5937   set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
5938   set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
5939
5940   /* Use cabs for double complex abs, since systems generally have cabs.
5941      Don't define any libcall for float complex, so that cabs will be used.  */
5942   if (complex_double_type_node)
5943     optab_handler (abs_optab, TYPE_MODE (complex_double_type_node))->libfunc
5944       = init_one_libfunc ("cabs");
5945
5946   abort_libfunc = init_one_libfunc ("abort");
5947   memcpy_libfunc = init_one_libfunc ("memcpy");
5948   memmove_libfunc = init_one_libfunc ("memmove");
5949   memcmp_libfunc = init_one_libfunc ("memcmp");
5950   memset_libfunc = init_one_libfunc ("memset");
5951   setbits_libfunc = init_one_libfunc ("__setbits");
5952
5953 #ifndef DONT_USE_BUILTIN_SETJMP
5954   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5955   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5956 #else
5957   setjmp_libfunc = init_one_libfunc ("setjmp");
5958   longjmp_libfunc = init_one_libfunc ("longjmp");
5959 #endif
5960   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5961   unwind_sjlj_unregister_libfunc
5962     = init_one_libfunc ("_Unwind_SjLj_Unregister");
5963
5964   /* For function entry/exit instrumentation.  */
5965   profile_function_entry_libfunc
5966     = init_one_libfunc ("__cyg_profile_func_enter");
5967   profile_function_exit_libfunc
5968     = init_one_libfunc ("__cyg_profile_func_exit");
5969
5970   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5971
5972   if (HAVE_conditional_trap)
5973     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5974
5975   /* Allow the target to add more libcalls or rename some, etc.  */
5976   targetm.init_libfuncs ();
5977 }
5978
5979 #ifdef DEBUG
5980
5981 /* Print information about the current contents of the optabs on
5982    STDERR.  */
5983
5984 static void
5985 debug_optab_libfuncs (void)
5986 {
5987   int i;
5988   int j;
5989   int k;
5990
5991   /* Dump the arithmetic optabs.  */
5992   for (i = 0; i != (int) OTI_MAX; i++)
5993     for (j = 0; j < NUM_MACHINE_MODES; ++j)
5994       {
5995         optab o;
5996         struct optab_handlers *h;
5997
5998         o = optab_table[i];
5999         h = optab_handler (o, j);
6000         if (h->libfunc)
6001           {
6002             gcc_assert (GET_CODE (h->libfunc) == SYMBOL_REF);
6003             fprintf (stderr, "%s\t%s:\t%s\n",
6004                      GET_RTX_NAME (o->code),
6005                      GET_MODE_NAME (j),
6006                      XSTR (h->libfunc, 0));
6007           }
6008       }
6009
6010   /* Dump the conversion optabs.  */
6011   for (i = 0; i < (int) COI_MAX; ++i)
6012     for (j = 0; j < NUM_MACHINE_MODES; ++j)
6013       for (k = 0; k < NUM_MACHINE_MODES; ++k)
6014         {
6015           convert_optab o;
6016           struct optab_handlers *h;
6017
6018           o = &convert_optab_table[i];
6019           h = convert_optab_handler(o, j, k);
6020           if (h->libfunc)
6021             {
6022               gcc_assert (GET_CODE (h->libfunc) == SYMBOL_REF);
6023               fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6024                        GET_RTX_NAME (o->code),
6025                        GET_MODE_NAME (j),
6026                        GET_MODE_NAME (k),
6027                        XSTR (h->libfunc, 0));
6028             }
6029         }
6030 }
6031
6032 #endif /* DEBUG */
6033
6034 \f
6035 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6036    CODE.  Return 0 on failure.  */
6037
6038 rtx
6039 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
6040                rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
6041 {
6042   enum machine_mode mode = GET_MODE (op1);
6043   enum insn_code icode;
6044   rtx insn;
6045
6046   if (!HAVE_conditional_trap)
6047     return 0;
6048
6049   if (mode == VOIDmode)
6050     return 0;
6051
6052   icode = optab_handler (cmp_optab, mode)->insn_code;
6053   if (icode == CODE_FOR_nothing)
6054     return 0;
6055
6056   start_sequence ();
6057   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
6058   op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
6059   if (!op1 || !op2)
6060     {
6061       end_sequence ();
6062       return 0;
6063     }
6064   emit_insn (GEN_FCN (icode) (op1, op2));
6065
6066   PUT_CODE (trap_rtx, code);
6067   gcc_assert (HAVE_conditional_trap);
6068   insn = gen_conditional_trap (trap_rtx, tcode);
6069   if (insn)
6070     {
6071       emit_insn (insn);
6072       insn = get_insns ();
6073     }
6074   end_sequence ();
6075
6076   return insn;
6077 }
6078
6079 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6080    or unsigned operation code.  */
6081
6082 static enum rtx_code
6083 get_rtx_code (enum tree_code tcode, bool unsignedp)
6084 {
6085   enum rtx_code code;
6086   switch (tcode)
6087     {
6088     case EQ_EXPR:
6089       code = EQ;
6090       break;
6091     case NE_EXPR:
6092       code = NE;
6093       break;
6094     case LT_EXPR:
6095       code = unsignedp ? LTU : LT;
6096       break;
6097     case LE_EXPR:
6098       code = unsignedp ? LEU : LE;
6099       break;
6100     case GT_EXPR:
6101       code = unsignedp ? GTU : GT;
6102       break;
6103     case GE_EXPR:
6104       code = unsignedp ? GEU : GE;
6105       break;
6106
6107     case UNORDERED_EXPR:
6108       code = UNORDERED;
6109       break;
6110     case ORDERED_EXPR:
6111       code = ORDERED;
6112       break;
6113     case UNLT_EXPR:
6114       code = UNLT;
6115       break;
6116     case UNLE_EXPR:
6117       code = UNLE;
6118       break;
6119     case UNGT_EXPR:
6120       code = UNGT;
6121       break;
6122     case UNGE_EXPR:
6123       code = UNGE;
6124       break;
6125     case UNEQ_EXPR:
6126       code = UNEQ;
6127       break;
6128     case LTGT_EXPR:
6129       code = LTGT;
6130       break;
6131
6132     default:
6133       gcc_unreachable ();
6134     }
6135   return code;
6136 }
6137
6138 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6139    unsigned operators. Do not generate compare instruction.  */
6140
6141 static rtx
6142 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6143 {
6144   enum rtx_code rcode;
6145   tree t_op0, t_op1;
6146   rtx rtx_op0, rtx_op1;
6147
6148   /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6149      ensures that condition is a relational operation.  */
6150   gcc_assert (COMPARISON_CLASS_P (cond));
6151
6152   rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6153   t_op0 = TREE_OPERAND (cond, 0);
6154   t_op1 = TREE_OPERAND (cond, 1);
6155
6156   /* Expand operands.  */
6157   rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6158                          EXPAND_STACK_PARM);
6159   rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6160                          EXPAND_STACK_PARM);
6161
6162   if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
6163       && GET_MODE (rtx_op0) != VOIDmode)
6164     rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
6165
6166   if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
6167       && GET_MODE (rtx_op1) != VOIDmode)
6168     rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
6169
6170   return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
6171 }
6172
6173 /* Return insn code for VEC_COND_EXPR EXPR.  */
6174
6175 static inline enum insn_code
6176 get_vcond_icode (tree expr, enum machine_mode mode)
6177 {
6178   enum insn_code icode = CODE_FOR_nothing;
6179
6180   if (TYPE_UNSIGNED (TREE_TYPE (expr)))
6181     icode = vcondu_gen_code[mode];
6182   else
6183     icode = vcond_gen_code[mode];
6184   return icode;
6185 }
6186
6187 /* Return TRUE iff, appropriate vector insns are available
6188    for vector cond expr expr in VMODE mode.  */
6189
6190 bool
6191 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
6192 {
6193   if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
6194     return false;
6195   return true;
6196 }
6197
6198 /* Generate insns for VEC_COND_EXPR.  */
6199
6200 rtx
6201 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
6202 {
6203   enum insn_code icode;
6204   rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
6205   enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
6206   bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
6207
6208   icode = get_vcond_icode (vec_cond_expr, mode);
6209   if (icode == CODE_FOR_nothing)
6210     return 0;
6211
6212   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6213     target = gen_reg_rtx (mode);
6214
6215   /* Get comparison rtx.  First expand both cond expr operands.  */
6216   comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
6217                                    unsignedp, icode);
6218   cc_op0 = XEXP (comparison, 0);
6219   cc_op1 = XEXP (comparison, 1);
6220   /* Expand both operands and force them in reg, if required.  */
6221   rtx_op1 = expand_normal (TREE_OPERAND (vec_cond_expr, 1));
6222   if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
6223       && mode != VOIDmode)
6224     rtx_op1 = force_reg (mode, rtx_op1);
6225
6226   rtx_op2 = expand_normal (TREE_OPERAND (vec_cond_expr, 2));
6227   if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
6228       && mode != VOIDmode)
6229     rtx_op2 = force_reg (mode, rtx_op2);
6230
6231   /* Emit instruction! */
6232   emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
6233                               comparison, cc_op0,  cc_op1));
6234
6235   return target;
6236 }
6237
6238 \f
6239 /* This is an internal subroutine of the other compare_and_swap expanders.
6240    MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6241    operation.  TARGET is an optional place to store the value result of
6242    the operation.  ICODE is the particular instruction to expand.  Return
6243    the result of the operation.  */
6244
6245 static rtx
6246 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6247                                rtx target, enum insn_code icode)
6248 {
6249   enum machine_mode mode = GET_MODE (mem);
6250   rtx insn;
6251
6252   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6253     target = gen_reg_rtx (mode);
6254
6255   if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
6256     old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
6257   if (!insn_data[icode].operand[2].predicate (old_val, mode))
6258     old_val = force_reg (mode, old_val);
6259
6260   if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
6261     new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
6262   if (!insn_data[icode].operand[3].predicate (new_val, mode))
6263     new_val = force_reg (mode, new_val);
6264
6265   insn = GEN_FCN (icode) (target, mem, old_val, new_val);
6266   if (insn == NULL_RTX)
6267     return NULL_RTX;
6268   emit_insn (insn);
6269
6270   return target;
6271 }
6272
6273 /* Expand a compare-and-swap operation and return its value.  */
6274
6275 rtx
6276 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6277 {
6278   enum machine_mode mode = GET_MODE (mem);
6279   enum insn_code icode = sync_compare_and_swap[mode];
6280
6281   if (icode == CODE_FOR_nothing)
6282     return NULL_RTX;
6283
6284   return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
6285 }
6286
6287 /* Expand a compare-and-swap operation and store true into the result if
6288    the operation was successful and false otherwise.  Return the result.
6289    Unlike other routines, TARGET is not optional.  */
6290
6291 rtx
6292 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6293 {
6294   enum machine_mode mode = GET_MODE (mem);
6295   enum insn_code icode;
6296   rtx subtarget, label0, label1;
6297
6298   /* If the target supports a compare-and-swap pattern that simultaneously
6299      sets some flag for success, then use it.  Otherwise use the regular
6300      compare-and-swap and follow that immediately with a compare insn.  */
6301   icode = sync_compare_and_swap_cc[mode];
6302   switch (icode)
6303     {
6304     default:
6305       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
6306                                                  NULL_RTX, icode);
6307       if (subtarget != NULL_RTX)
6308         break;
6309
6310       /* FALLTHRU */
6311     case CODE_FOR_nothing:
6312       icode = sync_compare_and_swap[mode];
6313       if (icode == CODE_FOR_nothing)
6314         return NULL_RTX;
6315
6316       /* Ensure that if old_val == mem, that we're not comparing
6317          against an old value.  */
6318       if (MEM_P (old_val))
6319         old_val = force_reg (mode, old_val);
6320
6321       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
6322                                                  NULL_RTX, icode);
6323       if (subtarget == NULL_RTX)
6324         return NULL_RTX;
6325
6326       emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
6327     }
6328
6329   /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
6330      setcc instruction from the beginning.  We don't work too hard here,
6331      but it's nice to not be stupid about initial code gen either.  */
6332   if (STORE_FLAG_VALUE == 1)
6333     {
6334       icode = setcc_gen_code[EQ];
6335       if (icode != CODE_FOR_nothing)
6336         {
6337           enum machine_mode cmode = insn_data[icode].operand[0].mode;
6338           rtx insn;
6339
6340           subtarget = target;
6341           if (!insn_data[icode].operand[0].predicate (target, cmode))
6342             subtarget = gen_reg_rtx (cmode);
6343
6344           insn = GEN_FCN (icode) (subtarget);
6345           if (insn)
6346             {
6347               emit_insn (insn);
6348               if (GET_MODE (target) != GET_MODE (subtarget))
6349                 {
6350                   convert_move (target, subtarget, 1);
6351                   subtarget = target;
6352                 }
6353               return subtarget;
6354             }
6355         }
6356     }
6357
6358   /* Without an appropriate setcc instruction, use a set of branches to
6359      get 1 and 0 stored into target.  Presumably if the target has a
6360      STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt.  */
6361
6362   label0 = gen_label_rtx ();
6363   label1 = gen_label_rtx ();
6364
6365   emit_jump_insn (bcc_gen_fctn[EQ] (label0));
6366   emit_move_insn (target, const0_rtx);
6367   emit_jump_insn (gen_jump (label1));
6368   emit_barrier ();
6369   emit_label (label0);
6370   emit_move_insn (target, const1_rtx);
6371   emit_label (label1);
6372
6373   return target;
6374 }
6375
6376 /* This is a helper function for the other atomic operations.  This function
6377    emits a loop that contains SEQ that iterates until a compare-and-swap
6378    operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
6379    a set of instructions that takes a value from OLD_REG as an input and
6380    produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
6381    set to the current contents of MEM.  After SEQ, a compare-and-swap will
6382    attempt to update MEM with NEW_REG.  The function returns true when the
6383    loop was generated successfully.  */
6384
6385 static bool
6386 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6387 {
6388   enum machine_mode mode = GET_MODE (mem);
6389   enum insn_code icode;
6390   rtx label, cmp_reg, subtarget;
6391
6392   /* The loop we want to generate looks like
6393
6394         cmp_reg = mem;
6395       label:
6396         old_reg = cmp_reg;
6397         seq;
6398         cmp_reg = compare-and-swap(mem, old_reg, new_reg)
6399         if (cmp_reg != old_reg)
6400           goto label;
6401
6402      Note that we only do the plain load from memory once.  Subsequent
6403      iterations use the value loaded by the compare-and-swap pattern.  */
6404
6405   label = gen_label_rtx ();
6406   cmp_reg = gen_reg_rtx (mode);
6407
6408   emit_move_insn (cmp_reg, mem);
6409   emit_label (label);
6410   emit_move_insn (old_reg, cmp_reg);
6411   if (seq)
6412     emit_insn (seq);
6413
6414   /* If the target supports a compare-and-swap pattern that simultaneously
6415      sets some flag for success, then use it.  Otherwise use the regular
6416      compare-and-swap and follow that immediately with a compare insn.  */
6417   icode = sync_compare_and_swap_cc[mode];
6418   switch (icode)
6419     {
6420     default:
6421       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6422                                                  cmp_reg, icode);
6423       if (subtarget != NULL_RTX)
6424         {
6425           gcc_assert (subtarget == cmp_reg);
6426           break;
6427         }
6428
6429       /* FALLTHRU */
6430     case CODE_FOR_nothing:
6431       icode = sync_compare_and_swap[mode];
6432       if (icode == CODE_FOR_nothing)
6433         return false;
6434
6435       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6436                                                  cmp_reg, icode);
6437       if (subtarget == NULL_RTX)
6438         return false;
6439       if (subtarget != cmp_reg)
6440         emit_move_insn (cmp_reg, subtarget);
6441
6442       emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
6443     }
6444
6445   /* ??? Mark this jump predicted not taken?  */
6446   emit_jump_insn (bcc_gen_fctn[NE] (label));
6447
6448   return true;
6449 }
6450
6451 /* This function generates the atomic operation MEM CODE= VAL.  In this
6452    case, we do not care about any resulting value.  Returns NULL if we
6453    cannot generate the operation.  */
6454
6455 rtx
6456 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
6457 {
6458   enum machine_mode mode = GET_MODE (mem);
6459   enum insn_code icode;
6460   rtx insn;
6461
6462   /* Look to see if the target supports the operation directly.  */
6463   switch (code)
6464     {
6465     case PLUS:
6466       icode = sync_add_optab[mode];
6467       break;
6468     case IOR:
6469       icode = sync_ior_optab[mode];
6470       break;
6471     case XOR:
6472       icode = sync_xor_optab[mode];
6473       break;
6474     case AND:
6475       icode = sync_and_optab[mode];
6476       break;
6477     case NOT:
6478       icode = sync_nand_optab[mode];
6479       break;
6480
6481     case MINUS:
6482       icode = sync_sub_optab[mode];
6483       if (icode == CODE_FOR_nothing)
6484         {
6485           icode = sync_add_optab[mode];
6486           if (icode != CODE_FOR_nothing)
6487             {
6488               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6489               code = PLUS;
6490             }
6491         }
6492       break;
6493
6494     default:
6495       gcc_unreachable ();
6496     }
6497
6498   /* Generate the direct operation, if present.  */
6499   if (icode != CODE_FOR_nothing)
6500     {
6501       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6502         val = convert_modes (mode, GET_MODE (val), val, 1);
6503       if (!insn_data[icode].operand[1].predicate (val, mode))
6504         val = force_reg (mode, val);
6505
6506       insn = GEN_FCN (icode) (mem, val);
6507       if (insn)
6508         {
6509           emit_insn (insn);
6510           return const0_rtx;
6511         }
6512     }
6513
6514   /* Failing that, generate a compare-and-swap loop in which we perform the
6515      operation with normal arithmetic instructions.  */
6516   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6517     {
6518       rtx t0 = gen_reg_rtx (mode), t1;
6519
6520       start_sequence ();
6521
6522       t1 = t0;
6523       if (code == NOT)
6524         {
6525           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6526           code = AND;
6527         }
6528       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6529                                 true, OPTAB_LIB_WIDEN);
6530
6531       insn = get_insns ();
6532       end_sequence ();
6533
6534       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6535         return const0_rtx;
6536     }
6537
6538   return NULL_RTX;
6539 }
6540
6541 /* This function generates the atomic operation MEM CODE= VAL.  In this
6542    case, we do care about the resulting value: if AFTER is true then
6543    return the value MEM holds after the operation, if AFTER is false
6544    then return the value MEM holds before the operation.  TARGET is an
6545    optional place for the result value to be stored.  */
6546
6547 rtx
6548 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6549                              bool after, rtx target)
6550 {
6551   enum machine_mode mode = GET_MODE (mem);
6552   enum insn_code old_code, new_code, icode;
6553   bool compensate;
6554   rtx insn;
6555
6556   /* Look to see if the target supports the operation directly.  */
6557   switch (code)
6558     {
6559     case PLUS:
6560       old_code = sync_old_add_optab[mode];
6561       new_code = sync_new_add_optab[mode];
6562       break;
6563     case IOR:
6564       old_code = sync_old_ior_optab[mode];
6565       new_code = sync_new_ior_optab[mode];
6566       break;
6567     case XOR:
6568       old_code = sync_old_xor_optab[mode];
6569       new_code = sync_new_xor_optab[mode];
6570       break;
6571     case AND:
6572       old_code = sync_old_and_optab[mode];
6573       new_code = sync_new_and_optab[mode];
6574       break;
6575     case NOT:
6576       old_code = sync_old_nand_optab[mode];
6577       new_code = sync_new_nand_optab[mode];
6578       break;
6579
6580     case MINUS:
6581       old_code = sync_old_sub_optab[mode];
6582       new_code = sync_new_sub_optab[mode];
6583       if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6584         {
6585           old_code = sync_old_add_optab[mode];
6586           new_code = sync_new_add_optab[mode];
6587           if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6588             {
6589               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6590               code = PLUS;
6591             }
6592         }
6593       break;
6594
6595     default:
6596       gcc_unreachable ();
6597     }
6598
6599   /* If the target does supports the proper new/old operation, great.  But
6600      if we only support the opposite old/new operation, check to see if we
6601      can compensate.  In the case in which the old value is supported, then
6602      we can always perform the operation again with normal arithmetic.  In
6603      the case in which the new value is supported, then we can only handle
6604      this in the case the operation is reversible.  */
6605   compensate = false;
6606   if (after)
6607     {
6608       icode = new_code;
6609       if (icode == CODE_FOR_nothing)
6610         {
6611           icode = old_code;
6612           if (icode != CODE_FOR_nothing)
6613             compensate = true;
6614         }
6615     }
6616   else
6617     {
6618       icode = old_code;
6619       if (icode == CODE_FOR_nothing
6620           && (code == PLUS || code == MINUS || code == XOR))
6621         {
6622           icode = new_code;
6623           if (icode != CODE_FOR_nothing)
6624             compensate = true;
6625         }
6626     }
6627
6628   /* If we found something supported, great.  */
6629   if (icode != CODE_FOR_nothing)
6630     {
6631       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6632         target = gen_reg_rtx (mode);
6633
6634       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6635         val = convert_modes (mode, GET_MODE (val), val, 1);
6636       if (!insn_data[icode].operand[2].predicate (val, mode))
6637         val = force_reg (mode, val);
6638
6639       insn = GEN_FCN (icode) (target, mem, val);
6640       if (insn)
6641         {
6642           emit_insn (insn);
6643
6644           /* If we need to compensate for using an operation with the
6645              wrong return value, do so now.  */
6646           if (compensate)
6647             {
6648               if (!after)
6649                 {
6650                   if (code == PLUS)
6651                     code = MINUS;
6652                   else if (code == MINUS)
6653                     code = PLUS;
6654                 }
6655
6656               if (code == NOT)
6657                 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6658               target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6659                                             true, OPTAB_LIB_WIDEN);
6660             }
6661
6662           return target;
6663         }
6664     }
6665
6666   /* Failing that, generate a compare-and-swap loop in which we perform the
6667      operation with normal arithmetic instructions.  */
6668   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6669     {
6670       rtx t0 = gen_reg_rtx (mode), t1;
6671
6672       if (!target || !register_operand (target, mode))
6673         target = gen_reg_rtx (mode);
6674
6675       start_sequence ();
6676
6677       if (!after)
6678         emit_move_insn (target, t0);
6679       t1 = t0;
6680       if (code == NOT)
6681         {
6682           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6683           code = AND;
6684         }
6685       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6686                                 true, OPTAB_LIB_WIDEN);
6687       if (after)
6688         emit_move_insn (target, t1);
6689
6690       insn = get_insns ();
6691       end_sequence ();
6692
6693       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6694         return target;
6695     }
6696
6697   return NULL_RTX;
6698 }
6699
6700 /* This function expands a test-and-set operation.  Ideally we atomically
6701    store VAL in MEM and return the previous value in MEM.  Some targets
6702    may not support this operation and only support VAL with the constant 1;
6703    in this case while the return value will be 0/1, but the exact value
6704    stored in MEM is target defined.  TARGET is an option place to stick
6705    the return value.  */
6706
6707 rtx
6708 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6709 {
6710   enum machine_mode mode = GET_MODE (mem);
6711   enum insn_code icode;
6712   rtx insn;
6713
6714   /* If the target supports the test-and-set directly, great.  */
6715   icode = sync_lock_test_and_set[mode];
6716   if (icode != CODE_FOR_nothing)
6717     {
6718       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6719         target = gen_reg_rtx (mode);
6720
6721       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6722         val = convert_modes (mode, GET_MODE (val), val, 1);
6723       if (!insn_data[icode].operand[2].predicate (val, mode))
6724         val = force_reg (mode, val);
6725
6726       insn = GEN_FCN (icode) (target, mem, val);
6727       if (insn)
6728         {
6729           emit_insn (insn);
6730           return target;
6731         }
6732     }
6733
6734   /* Otherwise, use a compare-and-swap loop for the exchange.  */
6735   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6736     {
6737       if (!target || !register_operand (target, mode))
6738         target = gen_reg_rtx (mode);
6739       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6740         val = convert_modes (mode, GET_MODE (val), val, 1);
6741       if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6742         return target;
6743     }
6744
6745   return NULL_RTX;
6746 }
6747
6748 #include "gt-optabs.h"