OSDN Git Service

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