OSDN Git Service

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