OSDN Git Service

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