OSDN Git Service

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