OSDN Git Service

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