OSDN Git Service

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