OSDN Git Service

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