OSDN Git Service

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