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