OSDN Git Service

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