OSDN Git Service

2007-11-05 H.J. Lu <hongjiu.lu@intel.com>
[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, 2006, 2007
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
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[COI_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 void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
99                                    enum machine_mode *, int *);
100 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
101
102 /* Debug facility for use in GDB.  */
103 void debug_optab_libfuncs (void);
104
105 #ifndef HAVE_conditional_trap
106 #define HAVE_conditional_trap 0
107 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
108 #endif
109
110 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
111 #if ENABLE_DECIMAL_BID_FORMAT
112 #define DECIMAL_PREFIX "bid_"
113 #else
114 #define DECIMAL_PREFIX "dpd_"
115 #endif
116 \f
117
118 /* Info about libfunc.  We use same hashtable for normal optabs and conversion
119    optab.  In the first case mode2 is unused.  */
120 struct libfunc_entry GTY(())
121 {
122   size_t optab;
123   enum machine_mode mode1, mode2;
124   rtx libfunc;
125 };
126
127 /* Hash table used to convert declarations into nodes.  */
128 static GTY((param_is (struct libfunc_entry))) htab_t libfunc_hash;
129
130 /* Used for attribute_hash.  */
131
132 static hashval_t
133 hash_libfunc (const void *p)
134 {
135   const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
136
137   return (((int) e->mode1 + (int) e->mode2 * NUM_MACHINE_MODES)
138           ^ e->optab);
139 }
140
141 /* Used for optab_hash.  */
142
143 static int
144 eq_libfunc (const void *p, const void *q)
145 {
146   const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
147   const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
148
149   return (e1->optab == e2->optab
150           && e1->mode1 == e2->mode1
151           && e1->mode2 == e2->mode2);
152 }
153
154 /* Return libfunc corresponding operation defined by OPTAB converting
155    from MODE2 to MODE1.  Trigger lazy initialization if needed, return NULL
156    if no libfunc is available.  */
157 rtx
158 convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
159                        enum machine_mode mode2)
160 {
161   struct libfunc_entry e;
162   struct libfunc_entry **slot;
163
164   e.optab = (size_t) (convert_optab_table[0] - optab);
165   e.mode1 = mode1;
166   e.mode2 = mode2;
167   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
168   if (!slot)
169     {
170       if (optab->libcall_gen)
171         {
172           optab->libcall_gen (optab, optab->libcall_basename, mode1, mode2);
173           slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
174           if (slot)
175             return (*slot)->libfunc;
176           else
177             return NULL;
178         }
179       return NULL;
180     }
181   return (*slot)->libfunc;
182 }
183
184 /* Return libfunc corresponding operation defined by OPTAB in MODE.
185    Trigger lazy initialization if needed, return NULL if no libfunc is
186    available.  */
187 rtx
188 optab_libfunc (optab optab, enum machine_mode mode)
189 {
190   struct libfunc_entry e;
191   struct libfunc_entry **slot;
192
193   e.optab = (size_t) (optab_table[0] - optab);
194   e.mode1 = mode;
195   e.mode2 = VOIDmode;
196   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
197   if (!slot)
198     {
199       if (optab->libcall_gen)
200         {
201           optab->libcall_gen (optab, optab->libcall_basename,
202                               optab->libcall_suffix, mode);
203           slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash,
204                                                            &e, NO_INSERT);
205           if (slot)
206             return (*slot)->libfunc;
207           else
208             return NULL;
209         }
210       return NULL;
211     }
212   return (*slot)->libfunc;
213 }
214
215 \f
216 /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
217    the result of operation CODE applied to OP0 (and OP1 if it is a binary
218    operation).
219
220    If the last insn does not set TARGET, don't do anything, but return 1.
221
222    If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
223    don't add the REG_EQUAL note but return 0.  Our caller can then try
224    again, ensuring that TARGET is not one of the operands.  */
225
226 static int
227 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
228 {
229   rtx last_insn, insn, set;
230   rtx note;
231
232   gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
233
234   if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
235       && GET_RTX_CLASS (code) != RTX_BIN_ARITH
236       && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
237       && GET_RTX_CLASS (code) != RTX_COMPARE
238       && GET_RTX_CLASS (code) != RTX_UNARY)
239     return 1;
240
241   if (GET_CODE (target) == ZERO_EXTRACT)
242     return 1;
243
244   for (last_insn = insns;
245        NEXT_INSN (last_insn) != NULL_RTX;
246        last_insn = NEXT_INSN (last_insn))
247     ;
248
249   set = single_set (last_insn);
250   if (set == NULL_RTX)
251     return 1;
252
253   if (! rtx_equal_p (SET_DEST (set), target)
254       /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
255       && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
256           || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
257     return 1;
258
259   /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
260      besides the last insn.  */
261   if (reg_overlap_mentioned_p (target, op0)
262       || (op1 && reg_overlap_mentioned_p (target, op1)))
263     {
264       insn = PREV_INSN (last_insn);
265       while (insn != NULL_RTX)
266         {
267           if (reg_set_p (target, insn))
268             return 0;
269
270           insn = PREV_INSN (insn);
271         }
272     }
273
274   if (GET_RTX_CLASS (code) == RTX_UNARY)
275     note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
276   else
277     note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
278
279   set_unique_reg_note (last_insn, REG_EQUAL, note);
280
281   return 1;
282 }
283 \f
284 /* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
285    says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
286    not actually do a sign-extend or zero-extend, but can leave the
287    higher-order bits of the result rtx undefined, for example, in the case
288    of logical operations, but not right shifts.  */
289
290 static rtx
291 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
292                int unsignedp, int no_extend)
293 {
294   rtx result;
295
296   /* If we don't have to extend and this is a constant, return it.  */
297   if (no_extend && GET_MODE (op) == VOIDmode)
298     return op;
299
300   /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
301      extend since it will be more efficient to do so unless the signedness of
302      a promoted object differs from our extension.  */
303   if (! no_extend
304       || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
305           && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
306     return convert_modes (mode, oldmode, op, unsignedp);
307
308   /* If MODE is no wider than a single word, we return a paradoxical
309      SUBREG.  */
310   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
311     return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
312
313   /* Otherwise, get an object of MODE, clobber it, and set the low-order
314      part to OP.  */
315
316   result = gen_reg_rtx (mode);
317   emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
318   emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
319   return result;
320 }
321 \f
322 /* Return the optab used for computing the operation given by
323    the tree code, CODE.  This function is not always usable (for
324    example, it cannot give complete results for multiplication
325    or division) but probably ought to be relied on more widely
326    throughout the expander.  */
327 optab
328 optab_for_tree_code (enum tree_code code, const_tree type)
329 {
330   bool trapv;
331   switch (code)
332     {
333     case BIT_AND_EXPR:
334       return and_optab;
335
336     case BIT_IOR_EXPR:
337       return ior_optab;
338
339     case BIT_NOT_EXPR:
340       return one_cmpl_optab;
341
342     case BIT_XOR_EXPR:
343       return xor_optab;
344
345     case TRUNC_MOD_EXPR:
346     case CEIL_MOD_EXPR:
347     case FLOOR_MOD_EXPR:
348     case ROUND_MOD_EXPR:
349       return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
350
351     case RDIV_EXPR:
352     case TRUNC_DIV_EXPR:
353     case CEIL_DIV_EXPR:
354     case FLOOR_DIV_EXPR:
355     case ROUND_DIV_EXPR:
356     case EXACT_DIV_EXPR:
357       if (TYPE_SATURATING(type))
358         return TYPE_UNSIGNED(type) ? usdiv_optab : ssdiv_optab;
359       return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
360
361     case LSHIFT_EXPR:
362       if (TYPE_SATURATING(type))
363         return TYPE_UNSIGNED(type) ? usashl_optab : ssashl_optab;
364       return ashl_optab;
365
366     case RSHIFT_EXPR:
367       return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
368
369     case LROTATE_EXPR:
370       return rotl_optab;
371
372     case RROTATE_EXPR:
373       return rotr_optab;
374
375     case MAX_EXPR:
376       return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
377
378     case MIN_EXPR:
379       return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
380
381     case REALIGN_LOAD_EXPR:
382       return vec_realign_load_optab;
383
384     case WIDEN_SUM_EXPR:
385       return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
386
387     case DOT_PROD_EXPR:
388       return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
389
390     case REDUC_MAX_EXPR:
391       return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
392
393     case REDUC_MIN_EXPR:
394       return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
395
396     case REDUC_PLUS_EXPR:
397       return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
398
399     case VEC_LSHIFT_EXPR:
400       return vec_shl_optab;
401
402     case VEC_RSHIFT_EXPR:
403       return vec_shr_optab;
404
405     case VEC_WIDEN_MULT_HI_EXPR:
406       return TYPE_UNSIGNED (type) ? 
407         vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
408
409     case VEC_WIDEN_MULT_LO_EXPR:
410       return TYPE_UNSIGNED (type) ? 
411         vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
412
413     case VEC_UNPACK_HI_EXPR:
414       return TYPE_UNSIGNED (type) ?
415         vec_unpacku_hi_optab : vec_unpacks_hi_optab;
416
417     case VEC_UNPACK_LO_EXPR:
418       return TYPE_UNSIGNED (type) ? 
419         vec_unpacku_lo_optab : vec_unpacks_lo_optab;
420
421     case VEC_UNPACK_FLOAT_HI_EXPR:
422       /* The signedness is determined from input operand.  */
423       return TYPE_UNSIGNED (type) ?
424         vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
425
426     case VEC_UNPACK_FLOAT_LO_EXPR:
427       /* The signedness is determined from input operand.  */
428       return TYPE_UNSIGNED (type) ? 
429         vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
430
431     case VEC_PACK_TRUNC_EXPR:
432       return vec_pack_trunc_optab;
433
434     case VEC_PACK_SAT_EXPR:
435       return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
436
437     case VEC_PACK_FIX_TRUNC_EXPR:
438       /* The signedness is determined from output operand.  */
439       return TYPE_UNSIGNED (type) ?
440         vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
441
442     default:
443       break;
444     }
445
446   trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
447   switch (code)
448     {
449     case POINTER_PLUS_EXPR:
450     case PLUS_EXPR:
451       if (TYPE_SATURATING(type))
452         return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
453       return trapv ? addv_optab : add_optab;
454
455     case MINUS_EXPR:
456       if (TYPE_SATURATING(type))
457         return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
458       return trapv ? subv_optab : sub_optab;
459
460     case MULT_EXPR:
461       if (TYPE_SATURATING(type))
462         return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
463       return trapv ? smulv_optab : smul_optab;
464
465     case NEGATE_EXPR:
466       if (TYPE_SATURATING(type))
467         return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
468       return trapv ? negv_optab : neg_optab;
469
470     case ABS_EXPR:
471       return trapv ? absv_optab : abs_optab;
472
473     case VEC_EXTRACT_EVEN_EXPR:
474       return vec_extract_even_optab;
475
476     case VEC_EXTRACT_ODD_EXPR:
477       return vec_extract_odd_optab;
478
479     case VEC_INTERLEAVE_HIGH_EXPR:
480       return vec_interleave_high_optab;
481
482     case VEC_INTERLEAVE_LOW_EXPR:
483       return vec_interleave_low_optab;
484
485     default:
486       return NULL;
487     }
488 }
489 \f
490
491 /* Expand vector widening operations.
492
493    There are two different classes of operations handled here:
494    1) Operations whose result is wider than all the arguments to the operation.
495       Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
496       In this case OP0 and optionally OP1 would be initialized,
497       but WIDE_OP wouldn't (not relevant for this case).
498    2) Operations whose result is of the same size as the last argument to the
499       operation, but wider than all the other arguments to the operation.
500       Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
501       In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
502
503    E.g, when called to expand the following operations, this is how
504    the arguments will be initialized:
505                                 nops    OP0     OP1     WIDE_OP
506    widening-sum                 2       oprnd0  -       oprnd1          
507    widening-dot-product         3       oprnd0  oprnd1  oprnd2
508    widening-mult                2       oprnd0  oprnd1  -
509    type-promotion (vec-unpack)  1       oprnd0  -       -  */
510
511 rtx
512 expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
513                            int unsignedp)
514 {   
515   tree oprnd0, oprnd1, oprnd2;
516   enum machine_mode wmode = 0, tmode0, tmode1 = 0;
517   optab widen_pattern_optab;
518   int icode; 
519   enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
520   rtx temp;
521   rtx pat;
522   rtx xop0, xop1, wxop;
523   int nops = TREE_OPERAND_LENGTH (exp);
524
525   oprnd0 = TREE_OPERAND (exp, 0);
526   tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
527   widen_pattern_optab =
528         optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
529   icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code;
530   gcc_assert (icode != CODE_FOR_nothing);
531   xmode0 = insn_data[icode].operand[1].mode;
532
533   if (nops >= 2)
534     {
535       oprnd1 = TREE_OPERAND (exp, 1);
536       tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
537       xmode1 = insn_data[icode].operand[2].mode;
538     }
539
540   /* The last operand is of a wider mode than the rest of the operands.  */
541   if (nops == 2)
542     {
543       wmode = tmode1;
544       wxmode = xmode1;
545     }
546   else if (nops == 3)
547     {
548       gcc_assert (tmode1 == tmode0);
549       gcc_assert (op1);
550       oprnd2 = TREE_OPERAND (exp, 2);
551       wmode = TYPE_MODE (TREE_TYPE (oprnd2));
552       wxmode = insn_data[icode].operand[3].mode;
553     }
554
555   if (!wide_op)
556     wmode = wxmode = insn_data[icode].operand[0].mode;
557
558   if (!target
559       || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
560     temp = gen_reg_rtx (wmode);
561   else
562     temp = target;
563
564   xop0 = op0;
565   xop1 = op1;
566   wxop = wide_op;
567
568   /* In case the insn wants input operands in modes different from
569      those of the actual operands, convert the operands.  It would
570      seem that we don't need to convert CONST_INTs, but we do, so
571      that they're properly zero-extended, sign-extended or truncated
572      for their mode.  */
573
574   if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
575     xop0 = convert_modes (xmode0,
576                           GET_MODE (op0) != VOIDmode
577                           ? GET_MODE (op0)
578                           : tmode0,
579                           xop0, unsignedp);
580
581   if (op1)
582     if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
583       xop1 = convert_modes (xmode1,
584                             GET_MODE (op1) != VOIDmode
585                             ? GET_MODE (op1)
586                             : tmode1,
587                             xop1, unsignedp);
588
589   if (wide_op)
590     if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
591       wxop = convert_modes (wxmode,
592                             GET_MODE (wide_op) != VOIDmode
593                             ? GET_MODE (wide_op)
594                             : wmode,
595                             wxop, unsignedp);
596
597   /* Now, if insn's predicates don't allow our operands, put them into
598      pseudo regs.  */
599
600   if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
601       && xmode0 != VOIDmode)
602     xop0 = copy_to_mode_reg (xmode0, xop0);
603
604   if (op1)
605     {
606       if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
607           && xmode1 != VOIDmode)
608         xop1 = copy_to_mode_reg (xmode1, xop1);
609
610       if (wide_op)
611         {
612           if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
613               && wxmode != VOIDmode)
614             wxop = copy_to_mode_reg (wxmode, wxop);
615
616           pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
617         }
618       else
619         pat = GEN_FCN (icode) (temp, xop0, xop1);
620     }
621   else
622     {
623       if (wide_op)
624         {
625           if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
626               && wxmode != VOIDmode)
627             wxop = copy_to_mode_reg (wxmode, wxop);
628
629           pat = GEN_FCN (icode) (temp, xop0, wxop);
630         }
631       else
632         pat = GEN_FCN (icode) (temp, xop0);
633     }
634
635   emit_insn (pat);
636   return temp;
637 }
638
639 /* Generate code to perform an operation specified by TERNARY_OPTAB
640    on operands OP0, OP1 and OP2, with result having machine-mode MODE.
641
642    UNSIGNEDP is for the case where we have to widen the operands
643    to perform the operation.  It says to use zero-extension.
644
645    If TARGET is nonzero, the value
646    is generated there, if it is convenient to do so.
647    In all cases an rtx is returned for the locus of the value;
648    this may or may not be TARGET.  */
649
650 rtx
651 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
652                    rtx op1, rtx op2, rtx target, int unsignedp)
653 {
654   int icode = (int) optab_handler (ternary_optab, mode)->insn_code;
655   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
656   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
657   enum machine_mode mode2 = insn_data[icode].operand[3].mode;
658   rtx temp;
659   rtx pat;
660   rtx xop0 = op0, xop1 = op1, xop2 = op2;
661
662   gcc_assert (optab_handler (ternary_optab, mode)->insn_code
663               != CODE_FOR_nothing);
664
665   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
666     temp = gen_reg_rtx (mode);
667   else
668     temp = target;
669
670   /* In case the insn wants input operands in modes different from
671      those of the actual operands, convert the operands.  It would
672      seem that we don't need to convert CONST_INTs, but we do, so
673      that they're properly zero-extended, sign-extended or truncated
674      for their mode.  */
675
676   if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
677     xop0 = convert_modes (mode0,
678                           GET_MODE (op0) != VOIDmode
679                           ? GET_MODE (op0)
680                           : mode,
681                           xop0, unsignedp);
682
683   if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
684     xop1 = convert_modes (mode1,
685                           GET_MODE (op1) != VOIDmode
686                           ? GET_MODE (op1)
687                           : mode,
688                           xop1, unsignedp);
689
690   if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
691     xop2 = convert_modes (mode2,
692                           GET_MODE (op2) != VOIDmode
693                           ? GET_MODE (op2)
694                           : mode,
695                           xop2, unsignedp);
696
697   /* Now, if insn's predicates don't allow our operands, put them into
698      pseudo regs.  */
699
700   if (!insn_data[icode].operand[1].predicate (xop0, mode0)
701       && mode0 != VOIDmode)
702     xop0 = copy_to_mode_reg (mode0, xop0);
703
704   if (!insn_data[icode].operand[2].predicate (xop1, mode1)
705       && mode1 != VOIDmode)
706     xop1 = copy_to_mode_reg (mode1, xop1);
707
708   if (!insn_data[icode].operand[3].predicate (xop2, mode2)
709       && mode2 != VOIDmode)
710     xop2 = copy_to_mode_reg (mode2, xop2);
711
712   pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
713
714   emit_insn (pat);
715   return temp;
716 }
717
718
719 /* Like expand_binop, but return a constant rtx if the result can be
720    calculated at compile time.  The arguments and return value are
721    otherwise the same as for expand_binop.  */
722
723 static rtx
724 simplify_expand_binop (enum machine_mode mode, optab binoptab,
725                        rtx op0, rtx op1, rtx target, int unsignedp,
726                        enum optab_methods methods)
727 {
728   if (CONSTANT_P (op0) && CONSTANT_P (op1))
729     {
730       rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
731
732       if (x)
733         return x;
734     }
735
736   return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
737 }
738
739 /* Like simplify_expand_binop, but always put the result in TARGET.
740    Return true if the expansion succeeded.  */
741
742 bool
743 force_expand_binop (enum machine_mode mode, optab binoptab,
744                     rtx op0, rtx op1, rtx target, int unsignedp,
745                     enum optab_methods methods)
746 {
747   rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
748                                  target, unsignedp, methods);
749   if (x == 0)
750     return false;
751   if (x != target)
752     emit_move_insn (target, x);
753   return true;
754 }
755
756 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR.  */
757
758 rtx
759 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
760 {
761   enum insn_code icode;
762   rtx rtx_op1, rtx_op2;
763   enum machine_mode mode1;
764   enum machine_mode mode2;
765   enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
766   tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
767   tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
768   optab shift_optab;
769   rtx pat;
770
771   switch (TREE_CODE (vec_shift_expr))
772     {
773       case VEC_RSHIFT_EXPR:
774         shift_optab = vec_shr_optab;
775         break;
776       case VEC_LSHIFT_EXPR:
777         shift_optab = vec_shl_optab;
778         break;
779       default:
780         gcc_unreachable ();
781     }
782
783   icode = (int) optab_handler (shift_optab, mode)->insn_code;
784   gcc_assert (icode != CODE_FOR_nothing);
785
786   mode1 = insn_data[icode].operand[1].mode;
787   mode2 = insn_data[icode].operand[2].mode;
788
789   rtx_op1 = expand_normal (vec_oprnd);
790   if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
791       && mode1 != VOIDmode)
792     rtx_op1 = force_reg (mode1, rtx_op1);
793
794   rtx_op2 = expand_normal (shift_oprnd);
795   if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
796       && mode2 != VOIDmode)
797     rtx_op2 = force_reg (mode2, rtx_op2);
798
799   if (!target
800       || ! (*insn_data[icode].operand[0].predicate) (target, mode))
801     target = gen_reg_rtx (mode);
802
803   /* Emit instruction */
804   pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
805   gcc_assert (pat);
806   emit_insn (pat);
807
808   return target;
809 }
810
811 /* This subroutine of expand_doubleword_shift handles the cases in which
812    the effective shift value is >= BITS_PER_WORD.  The arguments and return
813    value are the same as for the parent routine, except that SUPERWORD_OP1
814    is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
815    INTO_TARGET may be null if the caller has decided to calculate it.  */
816
817 static bool
818 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
819                         rtx outof_target, rtx into_target,
820                         int unsignedp, enum optab_methods methods)
821 {
822   if (into_target != 0)
823     if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
824                              into_target, unsignedp, methods))
825       return false;
826
827   if (outof_target != 0)
828     {
829       /* For a signed right shift, we must fill OUTOF_TARGET with copies
830          of the sign bit, otherwise we must fill it with zeros.  */
831       if (binoptab != ashr_optab)
832         emit_move_insn (outof_target, CONST0_RTX (word_mode));
833       else
834         if (!force_expand_binop (word_mode, binoptab,
835                                  outof_input, GEN_INT (BITS_PER_WORD - 1),
836                                  outof_target, unsignedp, methods))
837           return false;
838     }
839   return true;
840 }
841
842 /* This subroutine of expand_doubleword_shift handles the cases in which
843    the effective shift value is < BITS_PER_WORD.  The arguments and return
844    value are the same as for the parent routine.  */
845
846 static bool
847 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
848                       rtx outof_input, rtx into_input, rtx op1,
849                       rtx outof_target, rtx into_target,
850                       int unsignedp, enum optab_methods methods,
851                       unsigned HOST_WIDE_INT shift_mask)
852 {
853   optab reverse_unsigned_shift, unsigned_shift;
854   rtx tmp, carries;
855
856   reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
857   unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
858
859   /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
860      We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
861      the opposite direction to BINOPTAB.  */
862   if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
863     {
864       carries = outof_input;
865       tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
866       tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
867                                    0, true, methods);
868     }
869   else
870     {
871       /* We must avoid shifting by BITS_PER_WORD bits since that is either
872          the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
873          has unknown behavior.  Do a single shift first, then shift by the
874          remainder.  It's OK to use ~OP1 as the remainder if shift counts
875          are truncated to the mode size.  */
876       carries = expand_binop (word_mode, reverse_unsigned_shift,
877                               outof_input, const1_rtx, 0, unsignedp, methods);
878       if (shift_mask == BITS_PER_WORD - 1)
879         {
880           tmp = immed_double_const (-1, -1, op1_mode);
881           tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
882                                        0, true, methods);
883         }
884       else
885         {
886           tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
887           tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
888                                        0, true, methods);
889         }
890     }
891   if (tmp == 0 || carries == 0)
892     return false;
893   carries = expand_binop (word_mode, reverse_unsigned_shift,
894                           carries, tmp, 0, unsignedp, methods);
895   if (carries == 0)
896     return false;
897
898   /* Shift INTO_INPUT logically by OP1.  This is the last use of INTO_INPUT
899      so the result can go directly into INTO_TARGET if convenient.  */
900   tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
901                       into_target, unsignedp, methods);
902   if (tmp == 0)
903     return false;
904
905   /* Now OR in the bits carried over from OUTOF_INPUT.  */
906   if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
907                            into_target, unsignedp, methods))
908     return false;
909
910   /* Use a standard word_mode shift for the out-of half.  */
911   if (outof_target != 0)
912     if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
913                              outof_target, unsignedp, methods))
914       return false;
915
916   return true;
917 }
918
919
920 #ifdef HAVE_conditional_move
921 /* Try implementing expand_doubleword_shift using conditional moves.
922    The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
923    otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
924    are the shift counts to use in the former and latter case.  All other
925    arguments are the same as the parent routine.  */
926
927 static bool
928 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
929                                   enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
930                                   rtx outof_input, rtx into_input,
931                                   rtx subword_op1, rtx superword_op1,
932                                   rtx outof_target, rtx into_target,
933                                   int unsignedp, enum optab_methods methods,
934                                   unsigned HOST_WIDE_INT shift_mask)
935 {
936   rtx outof_superword, into_superword;
937
938   /* Put the superword version of the output into OUTOF_SUPERWORD and
939      INTO_SUPERWORD.  */
940   outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
941   if (outof_target != 0 && subword_op1 == superword_op1)
942     {
943       /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
944          OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
945       into_superword = outof_target;
946       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
947                                    outof_superword, 0, unsignedp, methods))
948         return false;
949     }
950   else
951     {
952       into_superword = gen_reg_rtx (word_mode);
953       if (!expand_superword_shift (binoptab, outof_input, superword_op1,
954                                    outof_superword, into_superword,
955                                    unsignedp, methods))
956         return false;
957     }
958
959   /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
960   if (!expand_subword_shift (op1_mode, binoptab,
961                              outof_input, into_input, subword_op1,
962                              outof_target, into_target,
963                              unsignedp, methods, shift_mask))
964     return false;
965
966   /* Select between them.  Do the INTO half first because INTO_SUPERWORD
967      might be the current value of OUTOF_TARGET.  */
968   if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
969                               into_target, into_superword, word_mode, false))
970     return false;
971
972   if (outof_target != 0)
973     if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
974                                 outof_target, outof_superword,
975                                 word_mode, false))
976       return false;
977
978   return true;
979 }
980 #endif
981
982 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
983    OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
984    input operand; the shift moves bits in the direction OUTOF_INPUT->
985    INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
986    of the target.  OP1 is the shift count and OP1_MODE is its mode.
987    If OP1 is constant, it will have been truncated as appropriate
988    and is known to be nonzero.
989
990    If SHIFT_MASK is zero, the result of word shifts is undefined when the
991    shift count is outside the range [0, BITS_PER_WORD).  This routine must
992    avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
993
994    If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
995    masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
996    fill with zeros or sign bits as appropriate.
997
998    If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
999    a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1000    Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1001    In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1002    are undefined.
1003
1004    BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
1005    may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1006    OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
1007    function wants to calculate it itself.
1008
1009    Return true if the shift could be successfully synthesized.  */
1010
1011 static bool
1012 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
1013                          rtx outof_input, rtx into_input, rtx op1,
1014                          rtx outof_target, rtx into_target,
1015                          int unsignedp, enum optab_methods methods,
1016                          unsigned HOST_WIDE_INT shift_mask)
1017 {
1018   rtx superword_op1, tmp, cmp1, cmp2;
1019   rtx subword_label, done_label;
1020   enum rtx_code cmp_code;
1021
1022   /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1023      fill the result with sign or zero bits as appropriate.  If so, the value
1024      of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
1025      this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1026      and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1027
1028      This isn't worthwhile for constant shifts since the optimizers will
1029      cope better with in-range shift counts.  */
1030   if (shift_mask >= BITS_PER_WORD
1031       && outof_target != 0
1032       && !CONSTANT_P (op1))
1033     {
1034       if (!expand_doubleword_shift (op1_mode, binoptab,
1035                                     outof_input, into_input, op1,
1036                                     0, into_target,
1037                                     unsignedp, methods, shift_mask))
1038         return false;
1039       if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
1040                                outof_target, unsignedp, methods))
1041         return false;
1042       return true;
1043     }
1044
1045   /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1046      is true when the effective shift value is less than BITS_PER_WORD.
1047      Set SUPERWORD_OP1 to the shift count that should be used to shift
1048      OUTOF_INPUT into INTO_TARGET when the condition is false.  */
1049   tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
1050   if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
1051     {
1052       /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
1053          is a subword shift count.  */
1054       cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
1055                                     0, true, methods);
1056       cmp2 = CONST0_RTX (op1_mode);
1057       cmp_code = EQ;
1058       superword_op1 = op1;
1059     }
1060   else
1061     {
1062       /* Set CMP1 to OP1 - BITS_PER_WORD.  */
1063       cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
1064                                     0, true, methods);
1065       cmp2 = CONST0_RTX (op1_mode);
1066       cmp_code = LT;
1067       superword_op1 = cmp1;
1068     }
1069   if (cmp1 == 0)
1070     return false;
1071
1072   /* If we can compute the condition at compile time, pick the
1073      appropriate subroutine.  */
1074   tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
1075   if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
1076     {
1077       if (tmp == const0_rtx)
1078         return expand_superword_shift (binoptab, outof_input, superword_op1,
1079                                        outof_target, into_target,
1080                                        unsignedp, methods);
1081       else
1082         return expand_subword_shift (op1_mode, binoptab,
1083                                      outof_input, into_input, op1,
1084                                      outof_target, into_target,
1085                                      unsignedp, methods, shift_mask);
1086     }
1087
1088 #ifdef HAVE_conditional_move
1089   /* Try using conditional moves to generate straight-line code.  */
1090   {
1091     rtx start = get_last_insn ();
1092     if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1093                                           cmp_code, cmp1, cmp2,
1094                                           outof_input, into_input,
1095                                           op1, superword_op1,
1096                                           outof_target, into_target,
1097                                           unsignedp, methods, shift_mask))
1098       return true;
1099     delete_insns_since (start);
1100   }
1101 #endif
1102
1103   /* As a last resort, use branches to select the correct alternative.  */
1104   subword_label = gen_label_rtx ();
1105   done_label = gen_label_rtx ();
1106
1107   NO_DEFER_POP;
1108   do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1109                            0, 0, subword_label);
1110   OK_DEFER_POP;
1111
1112   if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1113                                outof_target, into_target,
1114                                unsignedp, methods))
1115     return false;
1116
1117   emit_jump_insn (gen_jump (done_label));
1118   emit_barrier ();
1119   emit_label (subword_label);
1120
1121   if (!expand_subword_shift (op1_mode, binoptab,
1122                              outof_input, into_input, op1,
1123                              outof_target, into_target,
1124                              unsignedp, methods, shift_mask))
1125     return false;
1126
1127   emit_label (done_label);
1128   return true;
1129 }
1130 \f
1131 /* Subroutine of expand_binop.  Perform a double word multiplication of
1132    operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1133    as the target's word_mode.  This function return NULL_RTX if anything
1134    goes wrong, in which case it may have already emitted instructions
1135    which need to be deleted.
1136
1137    If we want to multiply two two-word values and have normal and widening
1138    multiplies of single-word values, we can do this with three smaller
1139    multiplications.  Note that we do not make a REG_NO_CONFLICT block here
1140    because we are not operating on one word at a time.
1141
1142    The multiplication proceeds as follows:
1143                                  _______________________
1144                                 [__op0_high_|__op0_low__]
1145                                  _______________________
1146         *                       [__op1_high_|__op1_low__]
1147         _______________________________________________
1148                                  _______________________
1149     (1)                         [__op0_low__*__op1_low__]
1150                      _______________________
1151     (2a)            [__op0_low__*__op1_high_]
1152                      _______________________
1153     (2b)            [__op0_high_*__op1_low__]
1154          _______________________
1155     (3) [__op0_high_*__op1_high_]
1156
1157
1158   This gives a 4-word result.  Since we are only interested in the
1159   lower 2 words, partial result (3) and the upper words of (2a) and
1160   (2b) don't need to be calculated.  Hence (2a) and (2b) can be
1161   calculated using non-widening multiplication.
1162
1163   (1), however, needs to be calculated with an unsigned widening
1164   multiplication.  If this operation is not directly supported we
1165   try using a signed widening multiplication and adjust the result.
1166   This adjustment works as follows:
1167
1168       If both operands are positive then no adjustment is needed.
1169
1170       If the operands have different signs, for example op0_low < 0 and
1171       op1_low >= 0, the instruction treats the most significant bit of
1172       op0_low as a sign bit instead of a bit with significance
1173       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1174       with 2**BITS_PER_WORD - op0_low, and two's complements the
1175       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1176       the result.
1177
1178       Similarly, if both operands are negative, we need to add
1179       (op0_low + op1_low) * 2**BITS_PER_WORD.
1180
1181       We use a trick to adjust quickly.  We logically shift op0_low right
1182       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1183       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
1184       logical shift exists, we do an arithmetic right shift and subtract
1185       the 0 or -1.  */
1186
1187 static rtx
1188 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1189                        bool umulp, enum optab_methods methods)
1190 {
1191   int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1192   int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1193   rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1194   rtx product, adjust, product_high, temp;
1195
1196   rtx op0_high = operand_subword_force (op0, high, mode);
1197   rtx op0_low = operand_subword_force (op0, low, mode);
1198   rtx op1_high = operand_subword_force (op1, high, mode);
1199   rtx op1_low = operand_subword_force (op1, low, mode);
1200
1201   /* If we're using an unsigned multiply to directly compute the product
1202      of the low-order words of the operands and perform any required
1203      adjustments of the operands, we begin by trying two more multiplications
1204      and then computing the appropriate sum.
1205
1206      We have checked above that the required addition is provided.
1207      Full-word addition will normally always succeed, especially if
1208      it is provided at all, so we don't worry about its failure.  The
1209      multiplication may well fail, however, so we do handle that.  */
1210
1211   if (!umulp)
1212     {
1213       /* ??? This could be done with emit_store_flag where available.  */
1214       temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1215                            NULL_RTX, 1, methods);
1216       if (temp)
1217         op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1218                                  NULL_RTX, 0, OPTAB_DIRECT);
1219       else
1220         {
1221           temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1222                                NULL_RTX, 0, methods);
1223           if (!temp)
1224             return NULL_RTX;
1225           op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1226                                    NULL_RTX, 0, OPTAB_DIRECT);
1227         }
1228
1229       if (!op0_high)
1230         return NULL_RTX;
1231     }
1232
1233   adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1234                          NULL_RTX, 0, OPTAB_DIRECT);
1235   if (!adjust)
1236     return NULL_RTX;
1237
1238   /* OP0_HIGH should now be dead.  */
1239
1240   if (!umulp)
1241     {
1242       /* ??? This could be done with emit_store_flag where available.  */
1243       temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1244                            NULL_RTX, 1, methods);
1245       if (temp)
1246         op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1247                                  NULL_RTX, 0, OPTAB_DIRECT);
1248       else
1249         {
1250           temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1251                                NULL_RTX, 0, methods);
1252           if (!temp)
1253             return NULL_RTX;
1254           op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1255                                    NULL_RTX, 0, OPTAB_DIRECT);
1256         }
1257
1258       if (!op1_high)
1259         return NULL_RTX;
1260     }
1261
1262   temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1263                        NULL_RTX, 0, OPTAB_DIRECT);
1264   if (!temp)
1265     return NULL_RTX;
1266
1267   /* OP1_HIGH should now be dead.  */
1268
1269   adjust = expand_binop (word_mode, add_optab, adjust, temp,
1270                          adjust, 0, OPTAB_DIRECT);
1271
1272   if (target && !REG_P (target))
1273     target = NULL_RTX;
1274
1275   if (umulp)
1276     product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1277                             target, 1, OPTAB_DIRECT);
1278   else
1279     product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1280                             target, 1, OPTAB_DIRECT);
1281
1282   if (!product)
1283     return NULL_RTX;
1284
1285   product_high = operand_subword (product, high, 1, mode);
1286   adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1287                          REG_P (product_high) ? product_high : adjust,
1288                          0, OPTAB_DIRECT);
1289   emit_move_insn (product_high, adjust);
1290   return product;
1291 }
1292 \f
1293 /* Wrapper around expand_binop which takes an rtx code to specify
1294    the operation to perform, not an optab pointer.  All other
1295    arguments are the same.  */
1296 rtx
1297 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1298                      rtx op1, rtx target, int unsignedp,
1299                      enum optab_methods methods)
1300 {
1301   optab binop = code_to_optab[(int) code];
1302   gcc_assert (binop);
1303
1304   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1305 }
1306
1307 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1308    binop.  Order them according to commutative_operand_precedence and, if
1309    possible, try to put TARGET or a pseudo first.  */
1310 static bool
1311 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1312 {
1313   int op0_prec = commutative_operand_precedence (op0);
1314   int op1_prec = commutative_operand_precedence (op1);
1315
1316   if (op0_prec < op1_prec)
1317     return true;
1318
1319   if (op0_prec > op1_prec)
1320     return false;
1321
1322   /* With equal precedence, both orders are ok, but it is better if the
1323      first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
1324   if (target == 0 || REG_P (target))
1325     return (REG_P (op1) && !REG_P (op0)) || target == op1;
1326   else
1327     return rtx_equal_p (op1, target);
1328 }
1329
1330 /* Return true if BINOPTAB implements a shift operation.  */
1331
1332 static bool
1333 shift_optab_p (optab binoptab)
1334 {
1335   switch (binoptab->code)
1336     {
1337     case ASHIFT:
1338     case SS_ASHIFT:
1339     case US_ASHIFT:
1340     case ASHIFTRT:
1341     case LSHIFTRT:
1342     case ROTATE:
1343     case ROTATERT:
1344       return true;
1345
1346     default:
1347       return false;
1348     }
1349 }
1350
1351 /* Return true if BINOPTAB implements a commutative binary operation.  */
1352
1353 static bool
1354 commutative_optab_p (optab binoptab)
1355 {
1356   return (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1357           || binoptab == smul_widen_optab
1358           || binoptab == umul_widen_optab
1359           || binoptab == smul_highpart_optab
1360           || binoptab == umul_highpart_optab);
1361 }
1362
1363 /* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
1364    optimizing, and if the operand is a constant that costs more than
1365    1 instruction, force the constant into a register and return that
1366    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
1367
1368 static rtx
1369 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1370                           rtx x, bool unsignedp)
1371 {
1372   if (mode != VOIDmode
1373       && optimize
1374       && CONSTANT_P (x)
1375       && rtx_cost (x, binoptab->code) > COSTS_N_INSNS (1))
1376     {
1377       if (GET_CODE (x) == CONST_INT)
1378         {
1379           HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1380           if (intval != INTVAL (x))
1381             x = GEN_INT (intval);
1382         }
1383       else
1384         x = convert_modes (mode, VOIDmode, x, unsignedp);
1385       x = force_reg (mode, x);
1386     }
1387   return x;
1388 }
1389
1390 /* Helper function for expand_binop: handle the case where there
1391    is an insn that directly implements the indicated operation.
1392    Returns null if this is not possible.  */
1393 static rtx
1394 expand_binop_directly (enum machine_mode mode, optab binoptab,
1395                        rtx op0, rtx op1,
1396                        rtx target, int unsignedp, enum optab_methods methods,
1397                        rtx last)
1398 {
1399   int icode = (int) optab_handler (binoptab, mode)->insn_code;
1400   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1401   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1402   enum machine_mode tmp_mode;
1403   bool commutative_p;
1404   rtx pat;
1405   rtx xop0 = op0, xop1 = op1;
1406   rtx temp;
1407   rtx swap;
1408   
1409   if (target)
1410     temp = target;
1411   else
1412     temp = gen_reg_rtx (mode);
1413
1414   /* If it is a commutative operator and the modes would match
1415      if we would swap the operands, we can save the conversions.  */
1416   commutative_p = commutative_optab_p (binoptab);
1417   if (commutative_p
1418       && GET_MODE (xop0) != mode0 && GET_MODE (xop1) != mode1
1419       && GET_MODE (xop0) == mode1 && GET_MODE (xop1) == mode1)
1420     {
1421       swap = xop0;
1422       xop0 = xop1;
1423       xop1 = swap;
1424     }
1425   
1426   /* If we are optimizing, force expensive constants into a register.  */
1427   xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
1428   if (!shift_optab_p (binoptab))
1429     xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
1430
1431   /* In case the insn wants input operands in modes different from
1432      those of the actual operands, convert the operands.  It would
1433      seem that we don't need to convert CONST_INTs, but we do, so
1434      that they're properly zero-extended, sign-extended or truncated
1435      for their mode.  */
1436   
1437   if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode)
1438     xop0 = convert_modes (mode0,
1439                           GET_MODE (xop0) != VOIDmode
1440                           ? GET_MODE (xop0)
1441                           : mode,
1442                           xop0, unsignedp);
1443   
1444   if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode)
1445     xop1 = convert_modes (mode1,
1446                           GET_MODE (xop1) != VOIDmode
1447                           ? GET_MODE (xop1)
1448                           : mode,
1449                           xop1, unsignedp);
1450   
1451   /* If operation is commutative,
1452      try to make the first operand a register.
1453      Even better, try to make it the same as the target.
1454      Also try to make the last operand a constant.  */
1455   if (commutative_p
1456       && swap_commutative_operands_with_target (target, xop0, xop1))
1457     {
1458       swap = xop1;
1459       xop1 = xop0;
1460       xop0 = swap;
1461     }
1462
1463   /* Now, if insn's predicates don't allow our operands, put them into
1464      pseudo regs.  */
1465   
1466   if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1467       && mode0 != VOIDmode)
1468     xop0 = copy_to_mode_reg (mode0, xop0);
1469   
1470   if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1471       && mode1 != VOIDmode)
1472     xop1 = copy_to_mode_reg (mode1, xop1);
1473   
1474   if (binoptab == vec_pack_trunc_optab 
1475       || binoptab == vec_pack_usat_optab
1476       || binoptab == vec_pack_ssat_optab
1477       || binoptab == vec_pack_ufix_trunc_optab
1478       || binoptab == vec_pack_sfix_trunc_optab)
1479     {
1480       /* The mode of the result is different then the mode of the
1481          arguments.  */
1482       tmp_mode = insn_data[icode].operand[0].mode;
1483       if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1484         return 0;
1485     }
1486   else
1487     tmp_mode = mode;
1488
1489   if (!insn_data[icode].operand[0].predicate (temp, tmp_mode))
1490     temp = gen_reg_rtx (tmp_mode);
1491   
1492   pat = GEN_FCN (icode) (temp, xop0, xop1);
1493   if (pat)
1494     {
1495       /* If PAT is composed of more than one insn, try to add an appropriate
1496          REG_EQUAL note to it.  If we can't because TEMP conflicts with an
1497          operand, call expand_binop again, this time without a target.  */
1498       if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1499           && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1500         {
1501           delete_insns_since (last);
1502           return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1503                                unsignedp, methods);
1504         }
1505       
1506       emit_insn (pat);
1507       return temp;
1508     }
1509
1510   delete_insns_since (last);
1511   return NULL_RTX;
1512 }
1513
1514 /* Generate code to perform an operation specified by BINOPTAB
1515    on operands OP0 and OP1, with result having machine-mode MODE.
1516
1517    UNSIGNEDP is for the case where we have to widen the operands
1518    to perform the operation.  It says to use zero-extension.
1519
1520    If TARGET is nonzero, the value
1521    is generated there, if it is convenient to do so.
1522    In all cases an rtx is returned for the locus of the value;
1523    this may or may not be TARGET.  */
1524
1525 rtx
1526 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1527               rtx target, int unsignedp, enum optab_methods methods)
1528 {
1529   enum optab_methods next_methods
1530     = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1531        ? OPTAB_WIDEN : methods);
1532   enum mode_class class;
1533   enum machine_mode wider_mode;
1534   rtx libfunc;
1535   rtx temp;
1536   rtx entry_last = get_last_insn ();
1537   rtx last;
1538
1539   class = GET_MODE_CLASS (mode);
1540
1541   /* If subtracting an integer constant, convert this into an addition of
1542      the negated constant.  */
1543
1544   if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1545     {
1546       op1 = negate_rtx (mode, op1);
1547       binoptab = add_optab;
1548     }
1549
1550   /* Record where to delete back to if we backtrack.  */
1551   last = get_last_insn ();
1552
1553   /* If we can do it with a three-operand insn, do so.  */
1554
1555   if (methods != OPTAB_MUST_WIDEN
1556       && optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
1557     {
1558       temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1559                                     unsignedp, methods, last);
1560       if (temp)
1561         return temp;
1562     }
1563
1564   /* If we were trying to rotate, and that didn't work, try rotating
1565      the other direction before falling back to shifts and bitwise-or.  */
1566   if (((binoptab == rotl_optab
1567         && optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing)
1568        || (binoptab == rotr_optab
1569            && optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing))
1570       && class == MODE_INT)
1571     {
1572       optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1573       rtx newop1;
1574       unsigned int bits = GET_MODE_BITSIZE (mode);
1575
1576       if (GET_CODE (op1) == CONST_INT)
1577         newop1 = GEN_INT (bits - INTVAL (op1));
1578       else if (targetm.shift_truncation_mask (mode) == bits - 1)
1579         newop1 = negate_rtx (mode, op1);
1580       else
1581         newop1 = expand_binop (mode, sub_optab,
1582                                GEN_INT (bits), op1,
1583                                NULL_RTX, unsignedp, OPTAB_DIRECT);
1584                                    
1585       temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1586                                     target, unsignedp, methods, last);
1587       if (temp)
1588         return temp;
1589     }
1590
1591   /* If this is a multiply, see if we can do a widening operation that
1592      takes operands of this mode and makes a wider mode.  */
1593
1594   if (binoptab == smul_optab
1595       && GET_MODE_WIDER_MODE (mode) != VOIDmode
1596       && ((optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),
1597                           GET_MODE_WIDER_MODE (mode))->insn_code)
1598           != CODE_FOR_nothing))
1599     {
1600       temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1601                            unsignedp ? umul_widen_optab : smul_widen_optab,
1602                            op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1603
1604       if (temp != 0)
1605         {
1606           if (GET_MODE_CLASS (mode) == MODE_INT
1607               && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1608                                         GET_MODE_BITSIZE (GET_MODE (temp))))
1609             return gen_lowpart (mode, temp);
1610           else
1611             return convert_to_mode (mode, temp, unsignedp);
1612         }
1613     }
1614
1615   /* Look for a wider mode of the same class for which we think we
1616      can open-code the operation.  Check for a widening multiply at the
1617      wider mode as well.  */
1618
1619   if (CLASS_HAS_WIDER_MODES_P (class)
1620       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1621     for (wider_mode = GET_MODE_WIDER_MODE (mode);
1622          wider_mode != VOIDmode;
1623          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1624       {
1625         if (optab_handler (binoptab, wider_mode)->insn_code != CODE_FOR_nothing
1626             || (binoptab == smul_optab
1627                 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1628                 && ((optab_handler ((unsignedp ? umul_widen_optab
1629                                      : smul_widen_optab),
1630                                      GET_MODE_WIDER_MODE (wider_mode))->insn_code)
1631                     != CODE_FOR_nothing)))
1632           {
1633             rtx xop0 = op0, xop1 = op1;
1634             int no_extend = 0;
1635
1636             /* For certain integer operations, we need not actually extend
1637                the narrow operands, as long as we will truncate
1638                the results to the same narrowness.  */
1639
1640             if ((binoptab == ior_optab || binoptab == and_optab
1641                  || binoptab == xor_optab
1642                  || binoptab == add_optab || binoptab == sub_optab
1643                  || binoptab == smul_optab || binoptab == ashl_optab)
1644                 && class == MODE_INT)
1645               {
1646                 no_extend = 1;
1647                 xop0 = avoid_expensive_constant (mode, binoptab,
1648                                                  xop0, unsignedp);
1649                 if (binoptab != ashl_optab)
1650                   xop1 = avoid_expensive_constant (mode, binoptab,
1651                                                    xop1, unsignedp);
1652               }
1653
1654             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1655
1656             /* The second operand of a shift must always be extended.  */
1657             xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1658                                   no_extend && binoptab != ashl_optab);
1659
1660             temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1661                                  unsignedp, OPTAB_DIRECT);
1662             if (temp)
1663               {
1664                 if (class != MODE_INT
1665                     || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1666                                                GET_MODE_BITSIZE (wider_mode)))
1667                   {
1668                     if (target == 0)
1669                       target = gen_reg_rtx (mode);
1670                     convert_move (target, temp, 0);
1671                     return target;
1672                   }
1673                 else
1674                   return gen_lowpart (mode, temp);
1675               }
1676             else
1677               delete_insns_since (last);
1678           }
1679       }
1680
1681   /* If operation is commutative,
1682      try to make the first operand a register.
1683      Even better, try to make it the same as the target.
1684      Also try to make the last operand a constant.  */
1685   if (commutative_optab_p (binoptab)
1686       && swap_commutative_operands_with_target (target, op0, op1))
1687     {
1688       temp = op1;
1689       op1 = op0;
1690       op0 = temp;
1691     }
1692
1693   /* These can be done a word at a time.  */
1694   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1695       && class == MODE_INT
1696       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1697       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1698     {
1699       int i;
1700       rtx insns;
1701       rtx equiv_value;
1702
1703       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1704          won't be accurate, so use a new target.  */
1705       if (target == 0 || target == op0 || target == op1)
1706         target = gen_reg_rtx (mode);
1707
1708       start_sequence ();
1709
1710       /* Do the actual arithmetic.  */
1711       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1712         {
1713           rtx target_piece = operand_subword (target, i, 1, mode);
1714           rtx x = expand_binop (word_mode, binoptab,
1715                                 operand_subword_force (op0, i, mode),
1716                                 operand_subword_force (op1, i, mode),
1717                                 target_piece, unsignedp, next_methods);
1718
1719           if (x == 0)
1720             break;
1721
1722           if (target_piece != x)
1723             emit_move_insn (target_piece, x);
1724         }
1725
1726       insns = get_insns ();
1727       end_sequence ();
1728
1729       if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1730         {
1731           if (binoptab->code != UNKNOWN)
1732             equiv_value
1733               = gen_rtx_fmt_ee (binoptab->code, mode,
1734                                 copy_rtx (op0), copy_rtx (op1));
1735           else
1736             equiv_value = 0;
1737
1738           emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1739           return target;
1740         }
1741     }
1742
1743   /* Synthesize double word shifts from single word shifts.  */
1744   if ((binoptab == lshr_optab || binoptab == ashl_optab
1745        || binoptab == ashr_optab)
1746       && class == MODE_INT
1747       && (GET_CODE (op1) == CONST_INT || !optimize_size)
1748       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1749       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing
1750       && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1751       && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1752     {
1753       unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1754       enum machine_mode op1_mode;
1755
1756       double_shift_mask = targetm.shift_truncation_mask (mode);
1757       shift_mask = targetm.shift_truncation_mask (word_mode);
1758       op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1759
1760       /* Apply the truncation to constant shifts.  */
1761       if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1762         op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1763
1764       if (op1 == CONST0_RTX (op1_mode))
1765         return op0;
1766
1767       /* Make sure that this is a combination that expand_doubleword_shift
1768          can handle.  See the comments there for details.  */
1769       if (double_shift_mask == 0
1770           || (shift_mask == BITS_PER_WORD - 1
1771               && double_shift_mask == BITS_PER_WORD * 2 - 1))
1772         {
1773           rtx insns, equiv_value;
1774           rtx into_target, outof_target;
1775           rtx into_input, outof_input;
1776           int left_shift, outof_word;
1777
1778           /* If TARGET is the same as one of the operands, the REG_EQUAL note
1779              won't be accurate, so use a new target.  */
1780           if (target == 0 || target == op0 || target == op1)
1781             target = gen_reg_rtx (mode);
1782
1783           start_sequence ();
1784
1785           /* OUTOF_* is the word we are shifting bits away from, and
1786              INTO_* is the word that we are shifting bits towards, thus
1787              they differ depending on the direction of the shift and
1788              WORDS_BIG_ENDIAN.  */
1789
1790           left_shift = binoptab == ashl_optab;
1791           outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1792
1793           outof_target = operand_subword (target, outof_word, 1, mode);
1794           into_target = operand_subword (target, 1 - outof_word, 1, mode);
1795
1796           outof_input = operand_subword_force (op0, outof_word, mode);
1797           into_input = operand_subword_force (op0, 1 - outof_word, mode);
1798
1799           if (expand_doubleword_shift (op1_mode, binoptab,
1800                                        outof_input, into_input, op1,
1801                                        outof_target, into_target,
1802                                        unsignedp, next_methods, shift_mask))
1803             {
1804               insns = get_insns ();
1805               end_sequence ();
1806
1807               equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1808               emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1809               return target;
1810             }
1811           end_sequence ();
1812         }
1813     }
1814
1815   /* Synthesize double word rotates from single word shifts.  */
1816   if ((binoptab == rotl_optab || binoptab == rotr_optab)
1817       && class == MODE_INT
1818       && GET_CODE (op1) == CONST_INT
1819       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1820       && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1821       && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1822     {
1823       rtx insns;
1824       rtx into_target, outof_target;
1825       rtx into_input, outof_input;
1826       rtx inter;
1827       int shift_count, left_shift, outof_word;
1828
1829       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1830          won't be accurate, so use a new target. Do this also if target is not
1831          a REG, first because having a register instead may open optimization
1832          opportunities, and second because if target and op0 happen to be MEMs
1833          designating the same location, we would risk clobbering it too early
1834          in the code sequence we generate below.  */
1835       if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1836         target = gen_reg_rtx (mode);
1837
1838       start_sequence ();
1839
1840       shift_count = INTVAL (op1);
1841
1842       /* OUTOF_* is the word we are shifting bits away from, and
1843          INTO_* is the word that we are shifting bits towards, thus
1844          they differ depending on the direction of the shift and
1845          WORDS_BIG_ENDIAN.  */
1846
1847       left_shift = (binoptab == rotl_optab);
1848       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1849
1850       outof_target = operand_subword (target, outof_word, 1, mode);
1851       into_target = operand_subword (target, 1 - outof_word, 1, mode);
1852
1853       outof_input = operand_subword_force (op0, outof_word, mode);
1854       into_input = operand_subword_force (op0, 1 - outof_word, mode);
1855
1856       if (shift_count == BITS_PER_WORD)
1857         {
1858           /* This is just a word swap.  */
1859           emit_move_insn (outof_target, into_input);
1860           emit_move_insn (into_target, outof_input);
1861           inter = const0_rtx;
1862         }
1863       else
1864         {
1865           rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1866           rtx first_shift_count, second_shift_count;
1867           optab reverse_unsigned_shift, unsigned_shift;
1868
1869           reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1870                                     ? lshr_optab : ashl_optab);
1871
1872           unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1873                             ? ashl_optab : lshr_optab);
1874
1875           if (shift_count > BITS_PER_WORD)
1876             {
1877               first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1878               second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1879             }
1880           else
1881             {
1882               first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1883               second_shift_count = GEN_INT (shift_count);
1884             }
1885
1886           into_temp1 = expand_binop (word_mode, unsigned_shift,
1887                                      outof_input, first_shift_count,
1888                                      NULL_RTX, unsignedp, next_methods);
1889           into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1890                                      into_input, second_shift_count,
1891                                      NULL_RTX, unsignedp, next_methods);
1892
1893           if (into_temp1 != 0 && into_temp2 != 0)
1894             inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1895                                   into_target, unsignedp, next_methods);
1896           else
1897             inter = 0;
1898
1899           if (inter != 0 && inter != into_target)
1900             emit_move_insn (into_target, inter);
1901
1902           outof_temp1 = expand_binop (word_mode, unsigned_shift,
1903                                       into_input, first_shift_count,
1904                                       NULL_RTX, unsignedp, next_methods);
1905           outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1906                                       outof_input, second_shift_count,
1907                                       NULL_RTX, unsignedp, next_methods);
1908
1909           if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1910             inter = expand_binop (word_mode, ior_optab,
1911                                   outof_temp1, outof_temp2,
1912                                   outof_target, unsignedp, next_methods);
1913
1914           if (inter != 0 && inter != outof_target)
1915             emit_move_insn (outof_target, inter);
1916         }
1917
1918       insns = get_insns ();
1919       end_sequence ();
1920
1921       if (inter != 0)
1922         {
1923           /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1924              block to help the register allocator a bit.  But a multi-word
1925              rotate will need all the input bits when setting the output
1926              bits, so there clearly is a conflict between the input and
1927              output registers.  So we can't use a no-conflict block here.  */
1928           emit_insn (insns);
1929           return target;
1930         }
1931     }
1932
1933   /* These can be done a word at a time by propagating carries.  */
1934   if ((binoptab == add_optab || binoptab == sub_optab)
1935       && class == MODE_INT
1936       && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1937       && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1938     {
1939       unsigned int i;
1940       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1941       const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1942       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1943       rtx xop0, xop1, xtarget;
1944
1945       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1946          value is one of those, use it.  Otherwise, use 1 since it is the
1947          one easiest to get.  */
1948 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1949       int normalizep = STORE_FLAG_VALUE;
1950 #else
1951       int normalizep = 1;
1952 #endif
1953
1954       /* Prepare the operands.  */
1955       xop0 = force_reg (mode, op0);
1956       xop1 = force_reg (mode, op1);
1957
1958       xtarget = gen_reg_rtx (mode);
1959
1960       if (target == 0 || !REG_P (target))
1961         target = xtarget;
1962
1963       /* Indicate for flow that the entire target reg is being set.  */
1964       if (REG_P (target))
1965         emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1966
1967       /* Do the actual arithmetic.  */
1968       for (i = 0; i < nwords; i++)
1969         {
1970           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1971           rtx target_piece = operand_subword (xtarget, index, 1, mode);
1972           rtx op0_piece = operand_subword_force (xop0, index, mode);
1973           rtx op1_piece = operand_subword_force (xop1, index, mode);
1974           rtx x;
1975
1976           /* Main add/subtract of the input operands.  */
1977           x = expand_binop (word_mode, binoptab,
1978                             op0_piece, op1_piece,
1979                             target_piece, unsignedp, next_methods);
1980           if (x == 0)
1981             break;
1982
1983           if (i + 1 < nwords)
1984             {
1985               /* Store carry from main add/subtract.  */
1986               carry_out = gen_reg_rtx (word_mode);
1987               carry_out = emit_store_flag_force (carry_out,
1988                                                  (binoptab == add_optab
1989                                                   ? LT : GT),
1990                                                  x, op0_piece,
1991                                                  word_mode, 1, normalizep);
1992             }
1993
1994           if (i > 0)
1995             {
1996               rtx newx;
1997
1998               /* Add/subtract previous carry to main result.  */
1999               newx = expand_binop (word_mode,
2000                                    normalizep == 1 ? binoptab : otheroptab,
2001                                    x, carry_in,
2002                                    NULL_RTX, 1, next_methods);
2003
2004               if (i + 1 < nwords)
2005                 {
2006                   /* Get out carry from adding/subtracting carry in.  */
2007                   rtx carry_tmp = gen_reg_rtx (word_mode);
2008                   carry_tmp = emit_store_flag_force (carry_tmp,
2009                                                      (binoptab == add_optab
2010                                                       ? LT : GT),
2011                                                      newx, x,
2012                                                      word_mode, 1, normalizep);
2013
2014                   /* Logical-ior the two poss. carry together.  */
2015                   carry_out = expand_binop (word_mode, ior_optab,
2016                                             carry_out, carry_tmp,
2017                                             carry_out, 0, next_methods);
2018                   if (carry_out == 0)
2019                     break;
2020                 }
2021               emit_move_insn (target_piece, newx);
2022             }
2023           else
2024             {
2025               if (x != target_piece)
2026                 emit_move_insn (target_piece, x);
2027             }
2028
2029           carry_in = carry_out;
2030         }
2031
2032       if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
2033         {
2034           if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing
2035               || ! rtx_equal_p (target, xtarget))
2036             {
2037               rtx temp = emit_move_insn (target, xtarget);
2038
2039               set_unique_reg_note (temp,
2040                                    REG_EQUAL,
2041                                    gen_rtx_fmt_ee (binoptab->code, mode,
2042                                                    copy_rtx (xop0),
2043                                                    copy_rtx (xop1)));
2044             }
2045           else
2046             target = xtarget;
2047
2048           return target;
2049         }
2050
2051       else
2052         delete_insns_since (last);
2053     }
2054
2055   /* Attempt to synthesize double word multiplies using a sequence of word
2056      mode multiplications.  We first attempt to generate a sequence using a
2057      more efficient unsigned widening multiply, and if that fails we then
2058      try using a signed widening multiply.  */
2059
2060   if (binoptab == smul_optab
2061       && class == MODE_INT
2062       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2063       && optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing
2064       && optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing)
2065     {
2066       rtx product = NULL_RTX;
2067
2068       if (optab_handler (umul_widen_optab, mode)->insn_code
2069           != CODE_FOR_nothing)
2070         {
2071           product = expand_doubleword_mult (mode, op0, op1, target,
2072                                             true, methods);
2073           if (!product)
2074             delete_insns_since (last);
2075         }
2076
2077       if (product == NULL_RTX
2078           && optab_handler (smul_widen_optab, mode)->insn_code
2079              != CODE_FOR_nothing)
2080         {
2081           product = expand_doubleword_mult (mode, op0, op1, target,
2082                                             false, methods);
2083           if (!product)
2084             delete_insns_since (last);
2085         }
2086
2087       if (product != NULL_RTX)
2088         {
2089           if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing)
2090             {
2091               temp = emit_move_insn (target ? target : product, product);
2092               set_unique_reg_note (temp,
2093                                    REG_EQUAL,
2094                                    gen_rtx_fmt_ee (MULT, mode,
2095                                                    copy_rtx (op0),
2096                                                    copy_rtx (op1)));
2097             }
2098           return product;
2099         }
2100     }
2101
2102   /* It can't be open-coded in this mode.
2103      Use a library call if one is available and caller says that's ok.  */
2104
2105   libfunc = optab_libfunc (binoptab, mode);
2106   if (libfunc
2107       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2108     {
2109       rtx insns;
2110       rtx op1x = op1;
2111       enum machine_mode op1_mode = mode;
2112       rtx value;
2113
2114       start_sequence ();
2115
2116       if (shift_optab_p (binoptab))
2117         {
2118           op1_mode = targetm.libgcc_shift_count_mode ();
2119           /* Specify unsigned here,
2120              since negative shift counts are meaningless.  */
2121           op1x = convert_to_mode (op1_mode, op1, 1);
2122         }
2123
2124       if (GET_MODE (op0) != VOIDmode
2125           && GET_MODE (op0) != mode)
2126         op0 = convert_to_mode (mode, op0, unsignedp);
2127
2128       /* Pass 1 for NO_QUEUE so we don't lose any increments
2129          if the libcall is cse'd or moved.  */
2130       value = emit_library_call_value (libfunc,
2131                                        NULL_RTX, LCT_CONST, mode, 2,
2132                                        op0, mode, op1x, op1_mode);
2133
2134       insns = get_insns ();
2135       end_sequence ();
2136
2137       target = gen_reg_rtx (mode);
2138       emit_libcall_block (insns, target, value,
2139                           gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
2140
2141       return target;
2142     }
2143
2144   delete_insns_since (last);
2145
2146   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2147
2148   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2149          || methods == OPTAB_MUST_WIDEN))
2150     {
2151       /* Caller says, don't even try.  */
2152       delete_insns_since (entry_last);
2153       return 0;
2154     }
2155
2156   /* Compute the value of METHODS to pass to recursive calls.
2157      Don't allow widening to be tried recursively.  */
2158
2159   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2160
2161   /* Look for a wider mode of the same class for which it appears we can do
2162      the operation.  */
2163
2164   if (CLASS_HAS_WIDER_MODES_P (class))
2165     {
2166       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2167            wider_mode != VOIDmode;
2168            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2169         {
2170           if ((optab_handler (binoptab, wider_mode)->insn_code
2171                != CODE_FOR_nothing)
2172               || (methods == OPTAB_LIB
2173                   && optab_libfunc (binoptab, wider_mode)))
2174             {
2175               rtx xop0 = op0, xop1 = op1;
2176               int no_extend = 0;
2177
2178               /* For certain integer operations, we need not actually extend
2179                  the narrow operands, as long as we will truncate
2180                  the results to the same narrowness.  */
2181
2182               if ((binoptab == ior_optab || binoptab == and_optab
2183                    || binoptab == xor_optab
2184                    || binoptab == add_optab || binoptab == sub_optab
2185                    || binoptab == smul_optab || binoptab == ashl_optab)
2186                   && class == MODE_INT)
2187                 no_extend = 1;
2188
2189               xop0 = widen_operand (xop0, wider_mode, mode,
2190                                     unsignedp, no_extend);
2191
2192               /* The second operand of a shift must always be extended.  */
2193               xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2194                                     no_extend && binoptab != ashl_optab);
2195
2196               temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2197                                    unsignedp, methods);
2198               if (temp)
2199                 {
2200                   if (class != MODE_INT
2201                       || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2202                                                  GET_MODE_BITSIZE (wider_mode)))
2203                     {
2204                       if (target == 0)
2205                         target = gen_reg_rtx (mode);
2206                       convert_move (target, temp, 0);
2207                       return target;
2208                     }
2209                   else
2210                     return gen_lowpart (mode, temp);
2211                 }
2212               else
2213                 delete_insns_since (last);
2214             }
2215         }
2216     }
2217
2218   delete_insns_since (entry_last);
2219   return 0;
2220 }
2221 \f
2222 /* Expand a binary operator which has both signed and unsigned forms.
2223    UOPTAB is the optab for unsigned operations, and SOPTAB is for
2224    signed operations.
2225
2226    If we widen unsigned operands, we may use a signed wider operation instead
2227    of an unsigned wider operation, since the result would be the same.  */
2228
2229 rtx
2230 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2231                    rtx op0, rtx op1, rtx target, int unsignedp,
2232                    enum optab_methods methods)
2233 {
2234   rtx temp;
2235   optab direct_optab = unsignedp ? uoptab : soptab;
2236   struct optab wide_soptab;
2237
2238   /* Do it without widening, if possible.  */
2239   temp = expand_binop (mode, direct_optab, op0, op1, target,
2240                        unsignedp, OPTAB_DIRECT);
2241   if (temp || methods == OPTAB_DIRECT)
2242     return temp;
2243
2244   /* Try widening to a signed int.  Make a fake signed optab that
2245      hides any signed insn for direct use.  */
2246   wide_soptab = *soptab;
2247   optab_handler (&wide_soptab, mode)->insn_code = CODE_FOR_nothing;
2248   /* We don't want to generate new hash table entries from this fake
2249      optab.  */
2250   wide_soptab.libcall_gen = NULL;
2251
2252   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2253                        unsignedp, OPTAB_WIDEN);
2254
2255   /* For unsigned operands, try widening to an unsigned int.  */
2256   if (temp == 0 && unsignedp)
2257     temp = expand_binop (mode, uoptab, op0, op1, target,
2258                          unsignedp, OPTAB_WIDEN);
2259   if (temp || methods == OPTAB_WIDEN)
2260     return temp;
2261
2262   /* Use the right width lib call if that exists.  */
2263   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2264   if (temp || methods == OPTAB_LIB)
2265     return temp;
2266
2267   /* Must widen and use a lib call, use either signed or unsigned.  */
2268   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2269                        unsignedp, methods);
2270   if (temp != 0)
2271     return temp;
2272   if (unsignedp)
2273     return expand_binop (mode, uoptab, op0, op1, target,
2274                          unsignedp, methods);
2275   return 0;
2276 }
2277 \f
2278 /* Generate code to perform an operation specified by UNOPPTAB
2279    on operand OP0, with two results to TARG0 and TARG1.
2280    We assume that the order of the operands for the instruction
2281    is TARG0, TARG1, OP0.
2282
2283    Either TARG0 or TARG1 may be zero, but what that means is that
2284    the result is not actually wanted.  We will generate it into
2285    a dummy pseudo-reg and discard it.  They may not both be zero.
2286
2287    Returns 1 if this operation can be performed; 0 if not.  */
2288
2289 int
2290 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2291                     int unsignedp)
2292 {
2293   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2294   enum mode_class class;
2295   enum machine_mode wider_mode;
2296   rtx entry_last = get_last_insn ();
2297   rtx last;
2298
2299   class = GET_MODE_CLASS (mode);
2300
2301   if (!targ0)
2302     targ0 = gen_reg_rtx (mode);
2303   if (!targ1)
2304     targ1 = gen_reg_rtx (mode);
2305
2306   /* Record where to go back to if we fail.  */
2307   last = get_last_insn ();
2308
2309   if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2310     {
2311       int icode = (int) optab_handler (unoptab, mode)->insn_code;
2312       enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2313       rtx pat;
2314       rtx xop0 = op0;
2315
2316       if (GET_MODE (xop0) != VOIDmode
2317           && GET_MODE (xop0) != mode0)
2318         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2319
2320       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2321       if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2322         xop0 = copy_to_mode_reg (mode0, xop0);
2323
2324       /* We could handle this, but we should always be called with a pseudo
2325          for our targets and all insns should take them as outputs.  */
2326       gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2327       gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2328
2329       pat = GEN_FCN (icode) (targ0, targ1, xop0);
2330       if (pat)
2331         {
2332           emit_insn (pat);
2333           return 1;
2334         }
2335       else
2336         delete_insns_since (last);
2337     }
2338
2339   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2340
2341   if (CLASS_HAS_WIDER_MODES_P (class))
2342     {
2343       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2344            wider_mode != VOIDmode;
2345            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2346         {
2347           if (optab_handler (unoptab, wider_mode)->insn_code
2348               != CODE_FOR_nothing)
2349             {
2350               rtx t0 = gen_reg_rtx (wider_mode);
2351               rtx t1 = gen_reg_rtx (wider_mode);
2352               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2353
2354               if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2355                 {
2356                   convert_move (targ0, t0, unsignedp);
2357                   convert_move (targ1, t1, unsignedp);
2358                   return 1;
2359                 }
2360               else
2361                 delete_insns_since (last);
2362             }
2363         }
2364     }
2365
2366   delete_insns_since (entry_last);
2367   return 0;
2368 }
2369 \f
2370 /* Generate code to perform an operation specified by BINOPTAB
2371    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2372    We assume that the order of the operands for the instruction
2373    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2374    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2375
2376    Either TARG0 or TARG1 may be zero, but what that means is that
2377    the result is not actually wanted.  We will generate it into
2378    a dummy pseudo-reg and discard it.  They may not both be zero.
2379
2380    Returns 1 if this operation can be performed; 0 if not.  */
2381
2382 int
2383 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2384                      int unsignedp)
2385 {
2386   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2387   enum mode_class class;
2388   enum machine_mode wider_mode;
2389   rtx entry_last = get_last_insn ();
2390   rtx last;
2391
2392   class = GET_MODE_CLASS (mode);
2393
2394   if (!targ0)
2395     targ0 = gen_reg_rtx (mode);
2396   if (!targ1)
2397     targ1 = gen_reg_rtx (mode);
2398
2399   /* Record where to go back to if we fail.  */
2400   last = get_last_insn ();
2401
2402   if (optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
2403     {
2404       int icode = (int) optab_handler (binoptab, mode)->insn_code;
2405       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2406       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2407       rtx pat;
2408       rtx xop0 = op0, xop1 = op1;
2409
2410       /* If we are optimizing, force expensive constants into a register.  */
2411       xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
2412       xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
2413
2414       /* In case the insn wants input operands in modes different from
2415          those of the actual operands, convert the operands.  It would
2416          seem that we don't need to convert CONST_INTs, but we do, so
2417          that they're properly zero-extended, sign-extended or truncated
2418          for their mode.  */
2419
2420       if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2421         xop0 = convert_modes (mode0,
2422                               GET_MODE (op0) != VOIDmode
2423                               ? GET_MODE (op0)
2424                               : mode,
2425                               xop0, unsignedp);
2426
2427       if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2428         xop1 = convert_modes (mode1,
2429                               GET_MODE (op1) != VOIDmode
2430                               ? GET_MODE (op1)
2431                               : mode,
2432                               xop1, unsignedp);
2433
2434       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2435       if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2436         xop0 = copy_to_mode_reg (mode0, xop0);
2437
2438       if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2439         xop1 = copy_to_mode_reg (mode1, xop1);
2440
2441       /* We could handle this, but we should always be called with a pseudo
2442          for our targets and all insns should take them as outputs.  */
2443       gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2444       gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2445
2446       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2447       if (pat)
2448         {
2449           emit_insn (pat);
2450           return 1;
2451         }
2452       else
2453         delete_insns_since (last);
2454     }
2455
2456   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2457
2458   if (CLASS_HAS_WIDER_MODES_P (class))
2459     {
2460       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2461            wider_mode != VOIDmode;
2462            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2463         {
2464           if (optab_handler (binoptab, wider_mode)->insn_code
2465               != CODE_FOR_nothing)
2466             {
2467               rtx t0 = gen_reg_rtx (wider_mode);
2468               rtx t1 = gen_reg_rtx (wider_mode);
2469               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2470               rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2471
2472               if (expand_twoval_binop (binoptab, cop0, cop1,
2473                                        t0, t1, unsignedp))
2474                 {
2475                   convert_move (targ0, t0, unsignedp);
2476                   convert_move (targ1, t1, unsignedp);
2477                   return 1;
2478                 }
2479               else
2480                 delete_insns_since (last);
2481             }
2482         }
2483     }
2484
2485   delete_insns_since (entry_last);
2486   return 0;
2487 }
2488
2489 /* Expand the two-valued library call indicated by BINOPTAB, but
2490    preserve only one of the values.  If TARG0 is non-NULL, the first
2491    value is placed into TARG0; otherwise the second value is placed
2492    into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2493    value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2494    This routine assumes that the value returned by the library call is
2495    as if the return value was of an integral mode twice as wide as the
2496    mode of OP0.  Returns 1 if the call was successful.  */
2497
2498 bool
2499 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2500                              rtx targ0, rtx targ1, enum rtx_code code)
2501 {
2502   enum machine_mode mode;
2503   enum machine_mode libval_mode;
2504   rtx libval;
2505   rtx insns;
2506   rtx libfunc;
2507
2508   /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2509   gcc_assert (!targ0 != !targ1);
2510
2511   mode = GET_MODE (op0);
2512   libfunc = optab_libfunc (binoptab, mode);
2513   if (!libfunc)
2514     return false;
2515
2516   /* The value returned by the library function will have twice as
2517      many bits as the nominal MODE.  */
2518   libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2519                                         MODE_INT);
2520   start_sequence ();
2521   libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2522                                     libval_mode, 2,
2523                                     op0, mode,
2524                                     op1, mode);
2525   /* Get the part of VAL containing the value that we want.  */
2526   libval = simplify_gen_subreg (mode, libval, libval_mode,
2527                                 targ0 ? 0 : GET_MODE_SIZE (mode));
2528   insns = get_insns ();
2529   end_sequence ();
2530   /* Move the into the desired location.  */
2531   emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2532                       gen_rtx_fmt_ee (code, mode, op0, op1));
2533
2534   return true;
2535 }
2536
2537 \f
2538 /* Wrapper around expand_unop which takes an rtx code to specify
2539    the operation to perform, not an optab pointer.  All other
2540    arguments are the same.  */
2541 rtx
2542 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2543                     rtx target, int unsignedp)
2544 {
2545   optab unop = code_to_optab[(int) code];
2546   gcc_assert (unop);
2547
2548   return expand_unop (mode, unop, op0, target, unsignedp);
2549 }
2550
2551 /* Try calculating
2552         (clz:narrow x)
2553    as
2554         (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2555 static rtx
2556 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2557 {
2558   enum mode_class class = GET_MODE_CLASS (mode);
2559   if (CLASS_HAS_WIDER_MODES_P (class))
2560     {
2561       enum machine_mode wider_mode;
2562       for (wider_mode = GET_MODE_WIDER_MODE (mode);
2563            wider_mode != VOIDmode;
2564            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2565         {
2566           if (optab_handler (clz_optab, wider_mode)->insn_code
2567               != CODE_FOR_nothing)
2568             {
2569               rtx xop0, temp, last;
2570
2571               last = get_last_insn ();
2572
2573               if (target == 0)
2574                 target = gen_reg_rtx (mode);
2575               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2576               temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2577               if (temp != 0)
2578                 temp = expand_binop (wider_mode, sub_optab, temp,
2579                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2580                                               - GET_MODE_BITSIZE (mode)),
2581                                      target, true, OPTAB_DIRECT);
2582               if (temp == 0)
2583                 delete_insns_since (last);
2584
2585               return temp;
2586             }
2587         }
2588     }
2589   return 0;
2590 }
2591
2592 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2593    quantities, choosing which based on whether the high word is nonzero.  */
2594 static rtx
2595 expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2596 {
2597   rtx xop0 = force_reg (mode, op0);
2598   rtx subhi = gen_highpart (word_mode, xop0);
2599   rtx sublo = gen_lowpart (word_mode, xop0);
2600   rtx hi0_label = gen_label_rtx ();
2601   rtx after_label = gen_label_rtx ();
2602   rtx seq, temp, result;
2603
2604   /* If we were not given a target, use a word_mode register, not a
2605      'mode' register.  The result will fit, and nobody is expecting
2606      anything bigger (the return type of __builtin_clz* is int).  */
2607   if (!target)
2608     target = gen_reg_rtx (word_mode);
2609
2610   /* In any case, write to a word_mode scratch in both branches of the
2611      conditional, so we can ensure there is a single move insn setting
2612      'target' to tag a REG_EQUAL note on.  */
2613   result = gen_reg_rtx (word_mode);
2614
2615   start_sequence ();
2616
2617   /* If the high word is not equal to zero,
2618      then clz of the full value is clz of the high word.  */
2619   emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2620                            word_mode, true, hi0_label);
2621
2622   temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2623   if (!temp)
2624     goto fail;
2625
2626   if (temp != result)
2627     convert_move (result, temp, true);
2628
2629   emit_jump_insn (gen_jump (after_label));
2630   emit_barrier ();
2631
2632   /* Else clz of the full value is clz of the low word plus the number
2633      of bits in the high word.  */
2634   emit_label (hi0_label);
2635
2636   temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2637   if (!temp)
2638     goto fail;
2639   temp = expand_binop (word_mode, add_optab, temp,
2640                        GEN_INT (GET_MODE_BITSIZE (word_mode)),
2641                        result, true, OPTAB_DIRECT);
2642   if (!temp)
2643     goto fail;
2644   if (temp != result)
2645     convert_move (result, temp, true);
2646
2647   emit_label (after_label);
2648   convert_move (target, result, true);
2649
2650   seq = get_insns ();
2651   end_sequence ();
2652
2653   add_equal_note (seq, target, CLZ, xop0, 0);
2654   emit_insn (seq);
2655   return target;
2656
2657  fail:
2658   end_sequence ();
2659   return 0;
2660 }
2661
2662 /* Try calculating
2663         (bswap:narrow x)
2664    as
2665         (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))).  */
2666 static rtx
2667 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2668 {
2669   enum mode_class class = GET_MODE_CLASS (mode);
2670   enum machine_mode wider_mode;
2671   rtx x, last;
2672
2673   if (!CLASS_HAS_WIDER_MODES_P (class))
2674     return NULL_RTX;
2675
2676   for (wider_mode = GET_MODE_WIDER_MODE (mode);
2677        wider_mode != VOIDmode;
2678        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2679     if (optab_handler (bswap_optab, wider_mode)->insn_code != CODE_FOR_nothing)
2680       goto found;
2681   return NULL_RTX;
2682
2683  found:
2684   last = get_last_insn ();
2685
2686   x = widen_operand (op0, wider_mode, mode, true, true);
2687   x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2688
2689   if (x != 0)
2690     x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2691                       size_int (GET_MODE_BITSIZE (wider_mode)
2692                                 - GET_MODE_BITSIZE (mode)),
2693                       NULL_RTX, true);
2694
2695   if (x != 0)
2696     {
2697       if (target == 0)
2698         target = gen_reg_rtx (mode);
2699       emit_move_insn (target, gen_lowpart (mode, x));
2700     }
2701   else
2702     delete_insns_since (last);
2703
2704   return target;
2705 }
2706
2707 /* Try calculating bswap as two bswaps of two word-sized operands.  */
2708
2709 static rtx
2710 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2711 {
2712   rtx t0, t1;
2713
2714   t1 = expand_unop (word_mode, bswap_optab,
2715                     operand_subword_force (op, 0, mode), NULL_RTX, true);
2716   t0 = expand_unop (word_mode, bswap_optab,
2717                     operand_subword_force (op, 1, mode), NULL_RTX, true);
2718
2719   if (target == 0)
2720     target = gen_reg_rtx (mode);
2721   if (REG_P (target))
2722     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2723   emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2724   emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2725
2726   return target;
2727 }
2728
2729 /* Try calculating (parity x) as (and (popcount x) 1), where
2730    popcount can also be done in a wider mode.  */
2731 static rtx
2732 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2733 {
2734   enum mode_class class = GET_MODE_CLASS (mode);
2735   if (CLASS_HAS_WIDER_MODES_P (class))
2736     {
2737       enum machine_mode wider_mode;
2738       for (wider_mode = mode; wider_mode != VOIDmode;
2739            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2740         {
2741           if (optab_handler (popcount_optab, wider_mode)->insn_code
2742               != CODE_FOR_nothing)
2743             {
2744               rtx xop0, temp, last;
2745
2746               last = get_last_insn ();
2747
2748               if (target == 0)
2749                 target = gen_reg_rtx (mode);
2750               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2751               temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2752                                   true);
2753               if (temp != 0)
2754                 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2755                                      target, true, OPTAB_DIRECT);
2756               if (temp == 0)
2757                 delete_insns_since (last);
2758
2759               return temp;
2760             }
2761         }
2762     }
2763   return 0;
2764 }
2765
2766 /* Try calculating ctz(x) as K - clz(x & -x) ,
2767    where K is GET_MODE_BITSIZE(mode) - 1.
2768
2769    Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2770    don't have to worry about what the hardware does in that case.  (If
2771    the clz instruction produces the usual value at 0, which is K, the
2772    result of this code sequence will be -1; expand_ffs, below, relies
2773    on this.  It might be nice to have it be K instead, for consistency
2774    with the (very few) processors that provide a ctz with a defined
2775    value, but that would take one more instruction, and it would be
2776    less convenient for expand_ffs anyway.  */
2777
2778 static rtx
2779 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2780 {
2781   rtx seq, temp;
2782   
2783   if (optab_handler (clz_optab, mode)->insn_code == CODE_FOR_nothing)
2784     return 0;
2785   
2786   start_sequence ();
2787
2788   temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2789   if (temp)
2790     temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2791                          true, OPTAB_DIRECT);
2792   if (temp)
2793     temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2794   if (temp)
2795     temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_BITSIZE (mode) - 1),
2796                          temp, target,
2797                          true, OPTAB_DIRECT);
2798   if (temp == 0)
2799     {
2800       end_sequence ();
2801       return 0;
2802     }
2803
2804   seq = get_insns ();
2805   end_sequence ();
2806
2807   add_equal_note (seq, temp, CTZ, op0, 0);
2808   emit_insn (seq);
2809   return temp;
2810 }
2811
2812
2813 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2814    else with the sequence used by expand_clz.
2815    
2816    The ffs builtin promises to return zero for a zero value and ctz/clz
2817    may have an undefined value in that case.  If they do not give us a
2818    convenient value, we have to generate a test and branch.  */
2819 static rtx
2820 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2821 {
2822   HOST_WIDE_INT val = 0;
2823   bool defined_at_zero = false;
2824   rtx temp, seq;
2825
2826   if (optab_handler (ctz_optab, mode)->insn_code != CODE_FOR_nothing)
2827     {
2828       start_sequence ();
2829
2830       temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2831       if (!temp)
2832         goto fail;
2833
2834       defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2835     }
2836   else if (optab_handler (clz_optab, mode)->insn_code != CODE_FOR_nothing)
2837     {
2838       start_sequence ();
2839       temp = expand_ctz (mode, op0, 0);
2840       if (!temp)
2841         goto fail;
2842
2843       if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2844         {
2845           defined_at_zero = true;
2846           val = (GET_MODE_BITSIZE (mode) - 1) - val;
2847         }
2848     }
2849   else
2850     return 0;
2851
2852   if (defined_at_zero && val == -1)
2853     /* No correction needed at zero.  */;
2854   else 
2855     {
2856       /* We don't try to do anything clever with the situation found
2857          on some processors (eg Alpha) where ctz(0:mode) ==
2858          bitsize(mode).  If someone can think of a way to send N to -1
2859          and leave alone all values in the range 0..N-1 (where N is a
2860          power of two), cheaper than this test-and-branch, please add it.
2861
2862          The test-and-branch is done after the operation itself, in case
2863          the operation sets condition codes that can be recycled for this.
2864          (This is true on i386, for instance.)  */
2865
2866       rtx nonzero_label = gen_label_rtx ();
2867       emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2868                                mode, true, nonzero_label);
2869
2870       convert_move (temp, GEN_INT (-1), false);
2871       emit_label (nonzero_label);
2872     }
2873
2874   /* temp now has a value in the range -1..bitsize-1.  ffs is supposed
2875      to produce a value in the range 0..bitsize.  */
2876   temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2877                        target, false, OPTAB_DIRECT);
2878   if (!temp)
2879     goto fail;
2880
2881   seq = get_insns ();
2882   end_sequence ();
2883
2884   add_equal_note (seq, temp, FFS, op0, 0);
2885   emit_insn (seq);
2886   return temp;
2887
2888  fail:
2889   end_sequence ();
2890   return 0;
2891 }
2892
2893 /* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
2894    conditions, VAL may already be a SUBREG against which we cannot generate
2895    a further SUBREG.  In this case, we expect forcing the value into a
2896    register will work around the situation.  */
2897
2898 static rtx
2899 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2900                            enum machine_mode imode)
2901 {
2902   rtx ret;
2903   ret = lowpart_subreg (omode, val, imode);
2904   if (ret == NULL)
2905     {
2906       val = force_reg (imode, val);
2907       ret = lowpart_subreg (omode, val, imode);
2908       gcc_assert (ret != NULL);
2909     }
2910   return ret;
2911 }
2912
2913 /* Expand a floating point absolute value or negation operation via a
2914    logical operation on the sign bit.  */
2915
2916 static rtx
2917 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2918                    rtx op0, rtx target)
2919 {
2920   const struct real_format *fmt;
2921   int bitpos, word, nwords, i;
2922   enum machine_mode imode;
2923   HOST_WIDE_INT hi, lo;
2924   rtx temp, insns;
2925
2926   /* The format has to have a simple sign bit.  */
2927   fmt = REAL_MODE_FORMAT (mode);
2928   if (fmt == NULL)
2929     return NULL_RTX;
2930
2931   bitpos = fmt->signbit_rw;
2932   if (bitpos < 0)
2933     return NULL_RTX;
2934
2935   /* Don't create negative zeros if the format doesn't support them.  */
2936   if (code == NEG && !fmt->has_signed_zero)
2937     return NULL_RTX;
2938
2939   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2940     {
2941       imode = int_mode_for_mode (mode);
2942       if (imode == BLKmode)
2943         return NULL_RTX;
2944       word = 0;
2945       nwords = 1;
2946     }
2947   else
2948     {
2949       imode = word_mode;
2950
2951       if (FLOAT_WORDS_BIG_ENDIAN)
2952         word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2953       else
2954         word = bitpos / BITS_PER_WORD;
2955       bitpos = bitpos % BITS_PER_WORD;
2956       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2957     }
2958
2959   if (bitpos < HOST_BITS_PER_WIDE_INT)
2960     {
2961       hi = 0;
2962       lo = (HOST_WIDE_INT) 1 << bitpos;
2963     }
2964   else
2965     {
2966       hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2967       lo = 0;
2968     }
2969   if (code == ABS)
2970     lo = ~lo, hi = ~hi;
2971
2972   if (target == 0 || target == op0)
2973     target = gen_reg_rtx (mode);
2974
2975   if (nwords > 1)
2976     {
2977       start_sequence ();
2978
2979       for (i = 0; i < nwords; ++i)
2980         {
2981           rtx targ_piece = operand_subword (target, i, 1, mode);
2982           rtx op0_piece = operand_subword_force (op0, i, mode);
2983
2984           if (i == word)
2985             {
2986               temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2987                                    op0_piece,
2988                                    immed_double_const (lo, hi, imode),
2989                                    targ_piece, 1, OPTAB_LIB_WIDEN);
2990               if (temp != targ_piece)
2991                 emit_move_insn (targ_piece, temp);
2992             }
2993           else
2994             emit_move_insn (targ_piece, op0_piece);
2995         }
2996
2997       insns = get_insns ();
2998       end_sequence ();
2999
3000       temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
3001       emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
3002     }
3003   else
3004     {
3005       temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3006                            gen_lowpart (imode, op0),
3007                            immed_double_const (lo, hi, imode),
3008                            gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3009       target = lowpart_subreg_maybe_copy (mode, temp, imode);
3010
3011       set_unique_reg_note (get_last_insn (), REG_EQUAL,
3012                            gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
3013     }
3014
3015   return target;
3016 }
3017
3018 /* As expand_unop, but will fail rather than attempt the operation in a
3019    different mode or with a libcall.  */
3020 static rtx
3021 expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
3022              int unsignedp)
3023 {
3024   if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
3025     {
3026       int icode = (int) optab_handler (unoptab, mode)->insn_code;
3027       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3028       rtx xop0 = op0;
3029       rtx last = get_last_insn ();
3030       rtx pat, temp;
3031
3032       if (target)
3033         temp = target;
3034       else
3035         temp = gen_reg_rtx (mode);
3036
3037       if (GET_MODE (xop0) != VOIDmode
3038           && GET_MODE (xop0) != mode0)
3039         xop0 = convert_to_mode (mode0, xop0, unsignedp);
3040
3041       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
3042
3043       if (!insn_data[icode].operand[1].predicate (xop0, mode0))
3044         xop0 = copy_to_mode_reg (mode0, xop0);
3045
3046       if (!insn_data[icode].operand[0].predicate (temp, mode))
3047         temp = gen_reg_rtx (mode);
3048
3049       pat = GEN_FCN (icode) (temp, xop0);
3050       if (pat)
3051         {
3052           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3053               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
3054             {
3055               delete_insns_since (last);
3056               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3057             }
3058
3059           emit_insn (pat);
3060
3061           return temp;
3062         }
3063       else
3064         delete_insns_since (last);
3065     }
3066   return 0;
3067 }
3068
3069 /* Generate code to perform an operation specified by UNOPTAB
3070    on operand OP0, with result having machine-mode MODE.
3071
3072    UNSIGNEDP is for the case where we have to widen the operands
3073    to perform the operation.  It says to use zero-extension.
3074
3075    If TARGET is nonzero, the value
3076    is generated there, if it is convenient to do so.
3077    In all cases an rtx is returned for the locus of the value;
3078    this may or may not be TARGET.  */
3079
3080 rtx
3081 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
3082              int unsignedp)
3083 {
3084   enum mode_class class = GET_MODE_CLASS (mode);
3085   enum machine_mode wider_mode;
3086   rtx temp;
3087   rtx libfunc;
3088
3089   temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3090   if (temp)
3091     return temp;
3092
3093   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
3094
3095   /* Widening (or narrowing) clz needs special treatment.  */
3096   if (unoptab == clz_optab)
3097     {
3098       temp = widen_clz (mode, op0, target);
3099       if (temp)
3100         return temp;
3101
3102       if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3103           && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3104         {
3105           temp = expand_doubleword_clz (mode, op0, target);
3106           if (temp)
3107             return temp;
3108         }
3109
3110         goto try_libcall;
3111     }
3112
3113   /* Widening (or narrowing) bswap needs special treatment.  */
3114   if (unoptab == bswap_optab)
3115     {
3116       temp = widen_bswap (mode, op0, target);
3117       if (temp)
3118         return temp;
3119
3120       if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3121           && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3122         {
3123           temp = expand_doubleword_bswap (mode, op0, target);
3124           if (temp)
3125             return temp;
3126         }
3127
3128       goto try_libcall;
3129     }
3130
3131   if (CLASS_HAS_WIDER_MODES_P (class))
3132     for (wider_mode = GET_MODE_WIDER_MODE (mode);
3133          wider_mode != VOIDmode;
3134          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3135       {
3136         if (optab_handler (unoptab, wider_mode)->insn_code != CODE_FOR_nothing)
3137           {
3138             rtx xop0 = op0;
3139             rtx last = get_last_insn ();
3140
3141             /* For certain operations, we need not actually extend
3142                the narrow operand, as long as we will truncate the
3143                results to the same narrowness.  */
3144
3145             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3146                                   (unoptab == neg_optab
3147                                    || unoptab == one_cmpl_optab)
3148                                   && class == MODE_INT);
3149
3150             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3151                                 unsignedp);
3152
3153             if (temp)
3154               {
3155                 if (class != MODE_INT
3156                     || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
3157                                                GET_MODE_BITSIZE (wider_mode)))
3158                   {
3159                     if (target == 0)
3160                       target = gen_reg_rtx (mode);
3161                     convert_move (target, temp, 0);
3162                     return target;
3163                   }
3164                 else
3165                   return gen_lowpart (mode, temp);
3166               }
3167             else
3168               delete_insns_since (last);
3169           }
3170       }
3171
3172   /* These can be done a word at a time.  */
3173   if (unoptab == one_cmpl_optab
3174       && class == MODE_INT
3175       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3176       && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3177     {
3178       int i;
3179       rtx insns;
3180
3181       if (target == 0 || target == op0)
3182         target = gen_reg_rtx (mode);
3183
3184       start_sequence ();
3185
3186       /* Do the actual arithmetic.  */
3187       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3188         {
3189           rtx target_piece = operand_subword (target, i, 1, mode);
3190           rtx x = expand_unop (word_mode, unoptab,
3191                                operand_subword_force (op0, i, mode),
3192                                target_piece, unsignedp);
3193
3194           if (target_piece != x)
3195             emit_move_insn (target_piece, x);
3196         }
3197
3198       insns = get_insns ();
3199       end_sequence ();
3200
3201       emit_no_conflict_block (insns, target, op0, NULL_RTX,
3202                               gen_rtx_fmt_e (unoptab->code, mode,
3203                                              copy_rtx (op0)));
3204       return target;
3205     }
3206
3207   if (unoptab->code == NEG)
3208     {
3209       /* Try negating floating point values by flipping the sign bit.  */
3210       if (SCALAR_FLOAT_MODE_P (mode))
3211         {
3212           temp = expand_absneg_bit (NEG, mode, op0, target);
3213           if (temp)
3214             return temp;
3215         }
3216
3217       /* If there is no negation pattern, and we have no negative zero,
3218          try subtracting from zero.  */
3219       if (!HONOR_SIGNED_ZEROS (mode))
3220         {
3221           temp = expand_binop (mode, (unoptab == negv_optab
3222                                       ? subv_optab : sub_optab),
3223                                CONST0_RTX (mode), op0, target,
3224                                unsignedp, OPTAB_DIRECT);
3225           if (temp)
3226             return temp;
3227         }
3228     }
3229
3230   /* Try calculating parity (x) as popcount (x) % 2.  */
3231   if (unoptab == parity_optab)
3232     {
3233       temp = expand_parity (mode, op0, target);
3234       if (temp)
3235         return temp;
3236     }
3237
3238   /* Try implementing ffs (x) in terms of clz (x).  */
3239   if (unoptab == ffs_optab)
3240     {
3241       temp = expand_ffs (mode, op0, target);
3242       if (temp)
3243         return temp;
3244     }
3245
3246   /* Try implementing ctz (x) in terms of clz (x).  */
3247   if (unoptab == ctz_optab)
3248     {
3249       temp = expand_ctz (mode, op0, target);
3250       if (temp)
3251         return temp;
3252     }
3253
3254  try_libcall:
3255   /* Now try a library call in this mode.  */
3256   libfunc = optab_libfunc (unoptab, mode);
3257   if (libfunc)
3258     {
3259       rtx insns;
3260       rtx value;
3261       enum machine_mode outmode = mode;
3262
3263       /* All of these functions return small values.  Thus we choose to
3264          have them return something that isn't a double-word.  */
3265       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3266           || unoptab == popcount_optab || unoptab == parity_optab)
3267         outmode
3268             = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
3269
3270       start_sequence ();
3271
3272       /* Pass 1 for NO_QUEUE so we don't lose any increments
3273          if the libcall is cse'd or moved.  */
3274       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3275                                        1, op0, mode);
3276       insns = get_insns ();
3277       end_sequence ();
3278
3279       target = gen_reg_rtx (outmode);
3280       emit_libcall_block (insns, target, value,
3281                           gen_rtx_fmt_e (unoptab->code, outmode, op0));
3282
3283       return target;
3284     }
3285
3286   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3287
3288   if (CLASS_HAS_WIDER_MODES_P (class))
3289     {
3290       for (wider_mode = GET_MODE_WIDER_MODE (mode);
3291            wider_mode != VOIDmode;
3292            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3293         {
3294           if ((optab_handler (unoptab, wider_mode)->insn_code
3295                != CODE_FOR_nothing)
3296               || optab_libfunc (unoptab, wider_mode))
3297             {
3298               rtx xop0 = op0;
3299               rtx last = get_last_insn ();
3300
3301               /* For certain operations, we need not actually extend
3302                  the narrow operand, as long as we will truncate the
3303                  results to the same narrowness.  */
3304
3305               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3306                                     (unoptab == neg_optab
3307                                      || unoptab == one_cmpl_optab)
3308                                     && class == MODE_INT);
3309
3310               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3311                                   unsignedp);
3312
3313               /* If we are generating clz using wider mode, adjust the
3314                  result.  */
3315               if (unoptab == clz_optab && temp != 0)
3316                 temp = expand_binop (wider_mode, sub_optab, temp,
3317                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
3318                                               - GET_MODE_BITSIZE (mode)),
3319                                      target, true, OPTAB_DIRECT);
3320
3321               if (temp)
3322                 {
3323                   if (class != MODE_INT)
3324                     {
3325                       if (target == 0)
3326                         target = gen_reg_rtx (mode);
3327                       convert_move (target, temp, 0);
3328                       return target;
3329                     }
3330                   else
3331                     return gen_lowpart (mode, temp);
3332                 }
3333               else
3334                 delete_insns_since (last);
3335             }
3336         }
3337     }
3338
3339   /* One final attempt at implementing negation via subtraction,
3340      this time allowing widening of the operand.  */
3341   if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
3342     {
3343       rtx temp;
3344       temp = expand_binop (mode,
3345                            unoptab == negv_optab ? subv_optab : sub_optab,
3346                            CONST0_RTX (mode), op0,
3347                            target, unsignedp, OPTAB_LIB_WIDEN);
3348       if (temp)
3349         return temp;
3350     }
3351
3352   return 0;
3353 }
3354 \f
3355 /* Emit code to compute the absolute value of OP0, with result to
3356    TARGET if convenient.  (TARGET may be 0.)  The return value says
3357    where the result actually is to be found.
3358
3359    MODE is the mode of the operand; the mode of the result is
3360    different but can be deduced from MODE.
3361
3362  */
3363
3364 rtx
3365 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3366                    int result_unsignedp)
3367 {
3368   rtx temp;
3369
3370   if (! flag_trapv)
3371     result_unsignedp = 1;
3372
3373   /* First try to do it with a special abs instruction.  */
3374   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3375                       op0, target, 0);
3376   if (temp != 0)
3377     return temp;
3378
3379   /* For floating point modes, try clearing the sign bit.  */
3380   if (SCALAR_FLOAT_MODE_P (mode))
3381     {
3382       temp = expand_absneg_bit (ABS, mode, op0, target);
3383       if (temp)
3384         return temp;
3385     }
3386
3387   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
3388   if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing
3389       && !HONOR_SIGNED_ZEROS (mode))
3390     {
3391       rtx last = get_last_insn ();
3392
3393       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3394       if (temp != 0)
3395         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3396                              OPTAB_WIDEN);
3397
3398       if (temp != 0)
3399         return temp;
3400
3401       delete_insns_since (last);
3402     }
3403
3404   /* If this machine has expensive jumps, we can do integer absolute
3405      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3406      where W is the width of MODE.  */
3407
3408   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
3409     {
3410       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3411                                    size_int (GET_MODE_BITSIZE (mode) - 1),
3412                                    NULL_RTX, 0);
3413
3414       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3415                            OPTAB_LIB_WIDEN);
3416       if (temp != 0)
3417         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3418                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
3419
3420       if (temp != 0)
3421         return temp;
3422     }
3423
3424   return NULL_RTX;
3425 }
3426
3427 rtx
3428 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3429             int result_unsignedp, int safe)
3430 {
3431   rtx temp, op1;
3432
3433   if (! flag_trapv)
3434     result_unsignedp = 1;
3435
3436   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3437   if (temp != 0)
3438     return temp;
3439
3440   /* If that does not win, use conditional jump and negate.  */
3441
3442   /* It is safe to use the target if it is the same
3443      as the source if this is also a pseudo register */
3444   if (op0 == target && REG_P (op0)
3445       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3446     safe = 1;
3447
3448   op1 = gen_label_rtx ();
3449   if (target == 0 || ! safe
3450       || GET_MODE (target) != mode
3451       || (MEM_P (target) && MEM_VOLATILE_P (target))
3452       || (REG_P (target)
3453           && REGNO (target) < FIRST_PSEUDO_REGISTER))
3454     target = gen_reg_rtx (mode);
3455
3456   emit_move_insn (target, op0);
3457   NO_DEFER_POP;
3458
3459   do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3460                            NULL_RTX, NULL_RTX, op1);
3461
3462   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3463                      target, target, 0);
3464   if (op0 != target)
3465     emit_move_insn (target, op0);
3466   emit_label (op1);
3467   OK_DEFER_POP;
3468   return target;
3469 }
3470
3471 /* A subroutine of expand_copysign, perform the copysign operation using the
3472    abs and neg primitives advertised to exist on the target.  The assumption
3473    is that we have a split register file, and leaving op0 in fp registers,
3474    and not playing with subregs so much, will help the register allocator.  */
3475
3476 static rtx
3477 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3478                         int bitpos, bool op0_is_abs)
3479 {
3480   enum machine_mode imode;
3481   int icode;
3482   rtx sign, label;
3483
3484   if (target == op1)
3485     target = NULL_RTX;
3486
3487   /* Check if the back end provides an insn that handles signbit for the
3488      argument's mode. */
3489   icode = (int) signbit_optab->handlers [(int) mode].insn_code;
3490   if (icode != CODE_FOR_nothing)
3491     {
3492       imode = insn_data[icode].operand[0].mode;
3493       sign = gen_reg_rtx (imode);
3494       emit_unop_insn (icode, sign, op1, UNKNOWN);
3495     }
3496   else
3497     {
3498       HOST_WIDE_INT hi, lo;
3499
3500       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3501         {
3502           imode = int_mode_for_mode (mode);
3503           if (imode == BLKmode)
3504             return NULL_RTX;
3505           op1 = gen_lowpart (imode, op1);
3506         }
3507       else
3508         {
3509           int word;
3510
3511           imode = word_mode;
3512           if (FLOAT_WORDS_BIG_ENDIAN)
3513             word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3514           else
3515             word = bitpos / BITS_PER_WORD;
3516           bitpos = bitpos % BITS_PER_WORD;
3517           op1 = operand_subword_force (op1, word, mode);
3518         }
3519
3520       if (bitpos < HOST_BITS_PER_WIDE_INT)
3521         {
3522           hi = 0;
3523           lo = (HOST_WIDE_INT) 1 << bitpos;
3524         }
3525       else
3526         {
3527           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3528           lo = 0;
3529         }
3530
3531       sign = gen_reg_rtx (imode);
3532       sign = expand_binop (imode, and_optab, op1,
3533                            immed_double_const (lo, hi, imode),
3534                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
3535     }
3536
3537   if (!op0_is_abs)
3538     {
3539       op0 = expand_unop (mode, abs_optab, op0, target, 0);
3540       if (op0 == NULL)
3541         return NULL_RTX;
3542       target = op0;
3543     }
3544   else
3545     {
3546       if (target == NULL_RTX)
3547         target = copy_to_reg (op0);
3548       else
3549         emit_move_insn (target, op0);
3550     }
3551
3552   label = gen_label_rtx ();
3553   emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3554
3555   if (GET_CODE (op0) == CONST_DOUBLE)
3556     op0 = simplify_unary_operation (NEG, mode, op0, mode);
3557   else
3558     op0 = expand_unop (mode, neg_optab, op0, target, 0);
3559   if (op0 != target)
3560     emit_move_insn (target, op0);
3561
3562   emit_label (label);
3563
3564   return target;
3565 }
3566
3567
3568 /* A subroutine of expand_copysign, perform the entire copysign operation
3569    with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
3570    is true if op0 is known to have its sign bit clear.  */
3571
3572 static rtx
3573 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3574                      int bitpos, bool op0_is_abs)
3575 {
3576   enum machine_mode imode;
3577   HOST_WIDE_INT hi, lo;
3578   int word, nwords, i;
3579   rtx temp, insns;
3580
3581   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3582     {
3583       imode = int_mode_for_mode (mode);
3584       if (imode == BLKmode)
3585         return NULL_RTX;
3586       word = 0;
3587       nwords = 1;
3588     }
3589   else
3590     {
3591       imode = word_mode;
3592
3593       if (FLOAT_WORDS_BIG_ENDIAN)
3594         word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3595       else
3596         word = bitpos / BITS_PER_WORD;
3597       bitpos = bitpos % BITS_PER_WORD;
3598       nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3599     }
3600
3601   if (bitpos < HOST_BITS_PER_WIDE_INT)
3602     {
3603       hi = 0;
3604       lo = (HOST_WIDE_INT) 1 << bitpos;
3605     }
3606   else
3607     {
3608       hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3609       lo = 0;
3610     }
3611
3612   if (target == 0 || target == op0 || target == op1)
3613     target = gen_reg_rtx (mode);
3614
3615   if (nwords > 1)
3616     {
3617       start_sequence ();
3618
3619       for (i = 0; i < nwords; ++i)
3620         {
3621           rtx targ_piece = operand_subword (target, i, 1, mode);
3622           rtx op0_piece = operand_subword_force (op0, i, mode);
3623
3624           if (i == word)
3625             {
3626               if (!op0_is_abs)
3627                 op0_piece = expand_binop (imode, and_optab, op0_piece,
3628                                           immed_double_const (~lo, ~hi, imode),
3629                                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
3630
3631               op1 = expand_binop (imode, and_optab,
3632                                   operand_subword_force (op1, i, mode),
3633                                   immed_double_const (lo, hi, imode),
3634                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
3635
3636               temp = expand_binop (imode, ior_optab, op0_piece, op1,
3637                                    targ_piece, 1, OPTAB_LIB_WIDEN);
3638               if (temp != targ_piece)
3639                 emit_move_insn (targ_piece, temp);
3640             }
3641           else
3642             emit_move_insn (targ_piece, op0_piece);
3643         }
3644
3645       insns = get_insns ();
3646       end_sequence ();
3647
3648       emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3649     }
3650   else
3651     {
3652       op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3653                           immed_double_const (lo, hi, imode),
3654                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
3655
3656       op0 = gen_lowpart (imode, op0);
3657       if (!op0_is_abs)
3658         op0 = expand_binop (imode, and_optab, op0,
3659                             immed_double_const (~lo, ~hi, imode),
3660                             NULL_RTX, 1, OPTAB_LIB_WIDEN);
3661
3662       temp = expand_binop (imode, ior_optab, op0, op1,
3663                            gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3664       target = lowpart_subreg_maybe_copy (mode, temp, imode);
3665     }
3666
3667   return target;
3668 }
3669
3670 /* Expand the C99 copysign operation.  OP0 and OP1 must be the same
3671    scalar floating point mode.  Return NULL if we do not know how to
3672    expand the operation inline.  */
3673
3674 rtx
3675 expand_copysign (rtx op0, rtx op1, rtx target)
3676 {
3677   enum machine_mode mode = GET_MODE (op0);
3678   const struct real_format *fmt;
3679   bool op0_is_abs;
3680   rtx temp;
3681
3682   gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3683   gcc_assert (GET_MODE (op1) == mode);
3684
3685   /* First try to do it with a special instruction.  */
3686   temp = expand_binop (mode, copysign_optab, op0, op1,
3687                        target, 0, OPTAB_DIRECT);
3688   if (temp)
3689     return temp;
3690
3691   fmt = REAL_MODE_FORMAT (mode);
3692   if (fmt == NULL || !fmt->has_signed_zero)
3693     return NULL_RTX;
3694
3695   op0_is_abs = false;
3696   if (GET_CODE (op0) == CONST_DOUBLE)
3697     {
3698       if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3699         op0 = simplify_unary_operation (ABS, mode, op0, mode);
3700       op0_is_abs = true;
3701     }
3702
3703   if (fmt->signbit_ro >= 0
3704       && (GET_CODE (op0) == CONST_DOUBLE
3705           || (optab_handler (neg_optab, mode)->insn_code != CODE_FOR_nothing
3706               && optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing)))
3707     {
3708       temp = expand_copysign_absneg (mode, op0, op1, target,
3709                                      fmt->signbit_ro, op0_is_abs);
3710       if (temp)
3711         return temp;
3712     }
3713
3714   if (fmt->signbit_rw < 0)
3715     return NULL_RTX;
3716   return expand_copysign_bit (mode, op0, op1, target,
3717                               fmt->signbit_rw, op0_is_abs);
3718 }
3719 \f
3720 /* Generate an instruction whose insn-code is INSN_CODE,
3721    with two operands: an output TARGET and an input OP0.
3722    TARGET *must* be nonzero, and the output is always stored there.
3723    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3724    the value that is stored into TARGET.  */
3725
3726 void
3727 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3728 {
3729   rtx temp;
3730   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3731   rtx pat;
3732
3733   temp = target;
3734
3735   /* Now, if insn does not accept our operands, put them into pseudos.  */
3736
3737   if (!insn_data[icode].operand[1].predicate (op0, mode0))
3738     op0 = copy_to_mode_reg (mode0, op0);
3739
3740   if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3741     temp = gen_reg_rtx (GET_MODE (temp));
3742
3743   pat = GEN_FCN (icode) (temp, op0);
3744
3745   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3746     add_equal_note (pat, temp, code, op0, NULL_RTX);
3747
3748   emit_insn (pat);
3749
3750   if (temp != target)
3751     emit_move_insn (target, temp);
3752 }
3753 \f
3754 struct no_conflict_data
3755 {
3756   rtx target, first, insn;
3757   bool must_stay;
3758 };
3759
3760 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3761    Set P->must_stay if the currently examined clobber / store has to stay
3762    in the list of insns that constitute the actual no_conflict block /
3763    libcall block.  */
3764 static void
3765 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3766 {
3767   struct no_conflict_data *p= p0;
3768
3769   /* If this inns directly contributes to setting the target, it must stay.  */
3770   if (reg_overlap_mentioned_p (p->target, dest))
3771     p->must_stay = true;
3772   /* If we haven't committed to keeping any other insns in the list yet,
3773      there is nothing more to check.  */
3774   else if (p->insn == p->first)
3775     return;
3776   /* If this insn sets / clobbers a register that feeds one of the insns
3777      already in the list, this insn has to stay too.  */
3778   else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3779            || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3780            || reg_used_between_p (dest, p->first, p->insn)
3781            /* Likewise if this insn depends on a register set by a previous
3782               insn in the list, or if it sets a result (presumably a hard
3783               register) that is set or clobbered by a previous insn.
3784               N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3785               SET_DEST perform the former check on the address, and the latter
3786               check on the MEM.  */
3787            || (GET_CODE (set) == SET
3788                && (modified_in_p (SET_SRC (set), p->first)
3789                    || modified_in_p (SET_DEST (set), p->first)
3790                    || modified_between_p (SET_SRC (set), p->first, p->insn)
3791                    || modified_between_p (SET_DEST (set), p->first, p->insn))))
3792     p->must_stay = true;
3793 }
3794
3795 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3796    logically equivalent to EQUIV, so it gets manipulated as a unit if it
3797    is possible to do so.  */
3798
3799 void
3800 maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3801 {
3802   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3803     {
3804       /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3805          encapsulated region would not be in one basic block, i.e. when
3806          there is a control_flow_insn_p insn between FIRST and LAST.  */
3807       bool attach_libcall_retval_notes = true;
3808       rtx insn, next = NEXT_INSN (last);
3809
3810       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3811         if (control_flow_insn_p (insn))
3812           {
3813             attach_libcall_retval_notes = false;
3814             break;
3815           }
3816
3817       if (attach_libcall_retval_notes)
3818         {
3819           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3820                                                  REG_NOTES (first));
3821           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3822                                                 REG_NOTES (last));
3823         }
3824     }
3825 }
3826
3827 /* Emit code to perform a series of operations on a multi-word quantity, one
3828    word at a time.
3829
3830    Such a block is preceded by a CLOBBER of the output, consists of multiple
3831    insns, each setting one word of the output, and followed by a SET copying
3832    the output to itself.
3833
3834    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3835    note indicating that it doesn't conflict with the (also multi-word)
3836    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3837    notes.
3838
3839    INSNS is a block of code generated to perform the operation, not including
3840    the CLOBBER and final copy.  All insns that compute intermediate values
3841    are first emitted, followed by the block as described above.
3842
3843    TARGET, OP0, and OP1 are the output and inputs of the operations,
3844    respectively.  OP1 may be zero for a unary operation.
3845
3846    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3847    on the last insn.
3848
3849    If TARGET is not a register, INSNS is simply emitted with no special
3850    processing.  Likewise if anything in INSNS is not an INSN or if
3851    there is a libcall block inside INSNS.
3852
3853    The final insn emitted is returned.  */
3854
3855 rtx
3856 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3857 {
3858   rtx prev, next, first, last, insn;
3859
3860   if (!REG_P (target) || reload_in_progress)
3861     return emit_insn (insns);
3862   else
3863     for (insn = insns; insn; insn = NEXT_INSN (insn))
3864       if (!NONJUMP_INSN_P (insn)
3865           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3866         return emit_insn (insns);
3867
3868   /* First emit all insns that do not store into words of the output and remove
3869      these from the list.  */
3870   for (insn = insns; insn; insn = next)
3871     {
3872       rtx note;
3873       struct no_conflict_data data;
3874
3875       next = NEXT_INSN (insn);
3876
3877       /* Some ports (cris) create a libcall regions at their own.  We must
3878          avoid any potential nesting of LIBCALLs.  */
3879       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3880         remove_note (insn, note);
3881       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3882         remove_note (insn, note);
3883
3884       data.target = target;
3885       data.first = insns;
3886       data.insn = insn;
3887       data.must_stay = 0;
3888       note_stores (PATTERN (insn), no_conflict_move_test, &data);
3889       if (! data.must_stay)
3890         {
3891           if (PREV_INSN (insn))
3892             NEXT_INSN (PREV_INSN (insn)) = next;
3893           else
3894             insns = next;
3895
3896           if (next)
3897             PREV_INSN (next) = PREV_INSN (insn);
3898
3899           add_insn (insn);
3900         }
3901     }
3902
3903   prev = get_last_insn ();
3904
3905   /* Now write the CLOBBER of the output, followed by the setting of each
3906      of the words, followed by the final copy.  */
3907   if (target != op0 && target != op1)
3908     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3909
3910   for (insn = insns; insn; insn = next)
3911     {
3912       next = NEXT_INSN (insn);
3913       add_insn (insn);
3914
3915       if (op1 && REG_P (op1))
3916         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3917                                               REG_NOTES (insn));
3918
3919       if (op0 && REG_P (op0))
3920         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3921                                               REG_NOTES (insn));
3922     }
3923
3924   if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3925       != CODE_FOR_nothing)
3926     {
3927       last = emit_move_insn (target, target);
3928       if (equiv)
3929         set_unique_reg_note (last, REG_EQUAL, equiv);
3930     }
3931   else
3932     {
3933       last = get_last_insn ();
3934
3935       /* Remove any existing REG_EQUAL note from "last", or else it will
3936          be mistaken for a note referring to the full contents of the
3937          alleged libcall value when found together with the REG_RETVAL
3938          note added below.  An existing note can come from an insn
3939          expansion at "last".  */
3940       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3941     }
3942
3943   if (prev == 0)
3944     first = get_insns ();
3945   else
3946     first = NEXT_INSN (prev);
3947
3948   maybe_encapsulate_block (first, last, equiv);
3949
3950   return last;
3951 }
3952 \f
3953 /* Emit code to make a call to a constant function or a library call.
3954
3955    INSNS is a list containing all insns emitted in the call.
3956    These insns leave the result in RESULT.  Our block is to copy RESULT
3957    to TARGET, which is logically equivalent to EQUIV.
3958
3959    We first emit any insns that set a pseudo on the assumption that these are
3960    loading constants into registers; doing so allows them to be safely cse'ed
3961    between blocks.  Then we emit all the other insns in the block, followed by
3962    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3963    note with an operand of EQUIV.
3964
3965    Moving assignments to pseudos outside of the block is done to improve
3966    the generated code, but is not required to generate correct code,
3967    hence being unable to move an assignment is not grounds for not making
3968    a libcall block.  There are two reasons why it is safe to leave these
3969    insns inside the block: First, we know that these pseudos cannot be
3970    used in generated RTL outside the block since they are created for
3971    temporary purposes within the block.  Second, CSE will not record the
3972    values of anything set inside a libcall block, so we know they must
3973    be dead at the end of the block.
3974
3975    Except for the first group of insns (the ones setting pseudos), the
3976    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3977 void
3978 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3979 {
3980   rtx final_dest = target;
3981   rtx prev, next, first, last, insn;
3982
3983   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3984      into a MEM later.  Protect the libcall block from this change.  */
3985   if (! REG_P (target) || REG_USERVAR_P (target))
3986     target = gen_reg_rtx (GET_MODE (target));
3987
3988   /* If we're using non-call exceptions, a libcall corresponding to an
3989      operation that may trap may also trap.  */
3990   if (flag_non_call_exceptions && may_trap_p (equiv))
3991     {
3992       for (insn = insns; insn; insn = NEXT_INSN (insn))
3993         if (CALL_P (insn))
3994           {
3995             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3996
3997             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3998               remove_note (insn, note);
3999           }
4000     }
4001   else
4002   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
4003      reg note to indicate that this call cannot throw or execute a nonlocal
4004      goto (unless there is already a REG_EH_REGION note, in which case
4005      we update it).  */
4006     for (insn = insns; insn; insn = NEXT_INSN (insn))
4007       if (CALL_P (insn))
4008         {
4009           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
4010
4011           if (note != 0)
4012             XEXP (note, 0) = constm1_rtx;
4013           else
4014             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
4015                                                   REG_NOTES (insn));
4016         }
4017
4018   /* First emit all insns that set pseudos.  Remove them from the list as
4019      we go.  Avoid insns that set pseudos which were referenced in previous
4020      insns.  These can be generated by move_by_pieces, for example,
4021      to update an address.  Similarly, avoid insns that reference things
4022      set in previous insns.  */
4023
4024   for (insn = insns; insn; insn = next)
4025     {
4026       rtx set = single_set (insn);
4027       rtx note;
4028
4029       /* Some ports (cris) create a libcall regions at their own.  We must
4030          avoid any potential nesting of LIBCALLs.  */
4031       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
4032         remove_note (insn, note);
4033       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
4034         remove_note (insn, note);
4035
4036       next = NEXT_INSN (insn);
4037
4038       if (set != 0 && REG_P (SET_DEST (set))
4039           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
4040         {
4041           struct no_conflict_data data;
4042
4043           data.target = const0_rtx;
4044           data.first = insns;
4045           data.insn = insn;
4046           data.must_stay = 0;
4047           note_stores (PATTERN (insn), no_conflict_move_test, &data);
4048           if (! data.must_stay)
4049             {
4050               if (PREV_INSN (insn))
4051                 NEXT_INSN (PREV_INSN (insn)) = next;
4052               else
4053                 insns = next;
4054
4055               if (next)
4056                 PREV_INSN (next) = PREV_INSN (insn);
4057
4058               add_insn (insn);
4059             }
4060         }
4061
4062       /* Some ports use a loop to copy large arguments onto the stack.
4063          Don't move anything outside such a loop.  */
4064       if (LABEL_P (insn))
4065         break;
4066     }
4067
4068   prev = get_last_insn ();
4069
4070   /* Write the remaining insns followed by the final copy.  */
4071
4072   for (insn = insns; insn; insn = next)
4073     {
4074       next = NEXT_INSN (insn);
4075
4076       add_insn (insn);
4077     }
4078
4079   last = emit_move_insn (target, result);
4080   if (optab_handler (mov_optab, GET_MODE (target))->insn_code
4081       != CODE_FOR_nothing)
4082     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
4083   else
4084     {
4085       /* Remove any existing REG_EQUAL note from "last", or else it will
4086          be mistaken for a note referring to the full contents of the
4087          libcall value when found together with the REG_RETVAL note added
4088          below.  An existing note can come from an insn expansion at
4089          "last".  */
4090       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
4091     }
4092
4093   if (final_dest != target)
4094     emit_move_insn (final_dest, target);
4095
4096   if (prev == 0)
4097     first = get_insns ();
4098   else
4099     first = NEXT_INSN (prev);
4100
4101   maybe_encapsulate_block (first, last, equiv);
4102 }
4103 \f
4104 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4105    PURPOSE describes how this comparison will be used.  CODE is the rtx
4106    comparison code we will be using.
4107
4108    ??? Actually, CODE is slightly weaker than that.  A target is still
4109    required to implement all of the normal bcc operations, but not
4110    required to implement all (or any) of the unordered bcc operations.  */
4111
4112 int
4113 can_compare_p (enum rtx_code code, enum machine_mode mode,
4114                enum can_compare_purpose purpose)
4115 {
4116   do
4117     {
4118       if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
4119         {
4120           if (purpose == ccp_jump)
4121             return bcc_gen_fctn[(int) code] != NULL;
4122           else if (purpose == ccp_store_flag)
4123             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
4124           else
4125             /* There's only one cmov entry point, and it's allowed to fail.  */
4126             return 1;
4127         }
4128       if (purpose == ccp_jump
4129           && optab_handler (cbranch_optab, mode)->insn_code != CODE_FOR_nothing)
4130         return 1;
4131       if (purpose == ccp_cmov
4132           && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
4133         return 1;
4134       if (purpose == ccp_store_flag
4135           && optab_handler (cstore_optab, mode)->insn_code != CODE_FOR_nothing)
4136         return 1;
4137       mode = GET_MODE_WIDER_MODE (mode);
4138     }
4139   while (mode != VOIDmode);
4140
4141   return 0;
4142 }
4143
4144 /* This function is called when we are going to emit a compare instruction that
4145    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4146
4147    *PMODE is the mode of the inputs (in case they are const_int).
4148    *PUNSIGNEDP nonzero says that the operands are unsigned;
4149    this matters if they need to be widened.
4150
4151    If they have mode BLKmode, then SIZE specifies the size of both operands.
4152
4153    This function performs all the setup necessary so that the caller only has
4154    to emit a single comparison insn.  This setup can involve doing a BLKmode
4155    comparison or emitting a library call to perform the comparison if no insn
4156    is available to handle it.
4157    The values which are passed in through pointers can be modified; the caller
4158    should perform the comparison on the modified values.  Constant
4159    comparisons must have already been folded.  */
4160
4161 static void
4162 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
4163                   enum machine_mode *pmode, int *punsignedp,
4164                   enum can_compare_purpose purpose)
4165 {
4166   enum machine_mode mode = *pmode;
4167   rtx x = *px, y = *py;
4168   int unsignedp = *punsignedp;
4169   rtx libfunc;
4170
4171   /* If we are inside an appropriately-short loop and we are optimizing,
4172      force expensive constants into a register.  */
4173   if (CONSTANT_P (x) && optimize
4174       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
4175     x = force_reg (mode, x);
4176
4177   if (CONSTANT_P (y) && optimize
4178       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
4179     y = force_reg (mode, y);
4180
4181 #ifdef HAVE_cc0
4182   /* Make sure if we have a canonical comparison.  The RTL
4183      documentation states that canonical comparisons are required only
4184      for targets which have cc0.  */
4185   gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4186 #endif
4187
4188   /* Don't let both operands fail to indicate the mode.  */
4189   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4190     x = force_reg (mode, x);
4191
4192   /* Handle all BLKmode compares.  */
4193
4194   if (mode == BLKmode)
4195     {
4196       enum machine_mode cmp_mode, result_mode;
4197       enum insn_code cmp_code;
4198       tree length_type;
4199       rtx libfunc;
4200       rtx result;
4201       rtx opalign
4202         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4203
4204       gcc_assert (size);
4205
4206       /* Try to use a memory block compare insn - either cmpstr
4207          or cmpmem will do.  */
4208       for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4209            cmp_mode != VOIDmode;
4210            cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4211         {
4212           cmp_code = cmpmem_optab[cmp_mode];
4213           if (cmp_code == CODE_FOR_nothing)
4214             cmp_code = cmpstr_optab[cmp_mode];
4215           if (cmp_code == CODE_FOR_nothing)
4216             cmp_code = cmpstrn_optab[cmp_mode];
4217           if (cmp_code == CODE_FOR_nothing)
4218             continue;
4219
4220           /* Must make sure the size fits the insn's mode.  */
4221           if ((GET_CODE (size) == CONST_INT
4222                && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4223               || (GET_MODE_BITSIZE (GET_MODE (size))
4224                   > GET_MODE_BITSIZE (cmp_mode)))
4225             continue;
4226
4227           result_mode = insn_data[cmp_code].operand[0].mode;
4228           result = gen_reg_rtx (result_mode);
4229           size = convert_to_mode (cmp_mode, size, 1);
4230           emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4231
4232           *px = result;
4233           *py = const0_rtx;
4234           *pmode = result_mode;
4235           return;
4236         }
4237
4238       /* Otherwise call a library function, memcmp.  */
4239       libfunc = memcmp_libfunc;
4240       length_type = sizetype;
4241       result_mode = TYPE_MODE (integer_type_node);
4242       cmp_mode = TYPE_MODE (length_type);
4243       size = convert_to_mode (TYPE_MODE (length_type), size,
4244                               TYPE_UNSIGNED (length_type));
4245
4246       result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
4247                                         result_mode, 3,
4248                                         XEXP (x, 0), Pmode,
4249                                         XEXP (y, 0), Pmode,
4250                                         size, cmp_mode);
4251       *px = result;
4252       *py = const0_rtx;
4253       *pmode = result_mode;
4254       return;
4255     }
4256
4257   /* Don't allow operands to the compare to trap, as that can put the
4258      compare and branch in different basic blocks.  */
4259   if (flag_non_call_exceptions)
4260     {
4261       if (may_trap_p (x))
4262         x = force_reg (mode, x);
4263       if (may_trap_p (y))
4264         y = force_reg (mode, y);
4265     }
4266
4267   *px = x;
4268   *py = y;
4269   if (can_compare_p (*pcomparison, mode, purpose))
4270     return;
4271
4272   /* Handle a lib call just for the mode we are using.  */
4273
4274   libfunc = optab_libfunc (cmp_optab, mode);
4275   if (libfunc && !SCALAR_FLOAT_MODE_P (mode))
4276     {
4277       rtx result;
4278
4279       /* If we want unsigned, and this mode has a distinct unsigned
4280          comparison routine, use that.  */
4281       if (unsignedp)
4282         {
4283           rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4284           if (ulibfunc)
4285             libfunc = ulibfunc;
4286         }
4287
4288       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4289                                         targetm.libgcc_cmp_return_mode (),
4290                                         2, x, mode, y, mode);
4291
4292       /* There are two kinds of comparison routines. Biased routines
4293          return 0/1/2, and unbiased routines return -1/0/1. Other parts
4294          of gcc expect that the comparison operation is equivalent
4295          to the modified comparison. For signed comparisons compare the 
4296          result against 1 in the biased case, and zero in the unbiased
4297          case. For unsigned comparisons always compare against 1 after
4298          biasing the unbiased result by adding 1. This gives us a way to
4299          represent LTU. */
4300       *px = result;
4301       *pmode = word_mode;
4302       *py = const1_rtx;
4303
4304       if (!TARGET_LIB_INT_CMP_BIASED)
4305         {
4306           if (*punsignedp)
4307             *px = plus_constant (result, 1);  
4308           else
4309             *py = const0_rtx;
4310         }
4311       return;
4312     }
4313
4314   gcc_assert (SCALAR_FLOAT_MODE_P (mode));
4315   prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4316 }
4317
4318 /* Before emitting an insn with code ICODE, make sure that X, which is going
4319    to be used for operand OPNUM of the insn, is converted from mode MODE to
4320    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4321    that it is accepted by the operand predicate.  Return the new value.  */
4322
4323 static rtx
4324 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
4325                  enum machine_mode wider_mode, int unsignedp)
4326 {
4327   if (mode != wider_mode)
4328     x = convert_modes (wider_mode, mode, x, unsignedp);
4329
4330   if (!insn_data[icode].operand[opnum].predicate
4331       (x, insn_data[icode].operand[opnum].mode))
4332     {
4333       if (reload_completed)
4334         return NULL_RTX;
4335       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
4336     }
4337
4338   return x;
4339 }
4340
4341 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4342    we can do the comparison.
4343    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
4344    be NULL_RTX which indicates that only a comparison is to be generated.  */
4345
4346 static void
4347 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
4348                           enum rtx_code comparison, int unsignedp, rtx label)
4349 {
4350   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
4351   enum mode_class class = GET_MODE_CLASS (mode);
4352   enum machine_mode wider_mode = mode;
4353
4354   /* Try combined insns first.  */
4355   do
4356     {
4357       enum insn_code icode;
4358       PUT_MODE (test, wider_mode);
4359
4360       if (label)
4361         {
4362           icode = optab_handler (cbranch_optab, wider_mode)->insn_code;
4363
4364           if (icode != CODE_FOR_nothing
4365               && insn_data[icode].operand[0].predicate (test, wider_mode))
4366             {
4367               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
4368               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
4369               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
4370               return;
4371             }
4372         }
4373
4374       /* Handle some compares against zero.  */
4375       icode = (int) optab_handler (tst_optab, wider_mode)->insn_code;
4376       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
4377         {
4378           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4379           emit_insn (GEN_FCN (icode) (x));
4380           if (label)
4381             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4382           return;
4383         }
4384
4385       /* Handle compares for which there is a directly suitable insn.  */
4386
4387       icode = (int) optab_handler (cmp_optab, wider_mode)->insn_code;
4388       if (icode != CODE_FOR_nothing)
4389         {
4390           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4391           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
4392           emit_insn (GEN_FCN (icode) (x, y));
4393           if (label)
4394             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4395           return;
4396         }
4397
4398       if (!CLASS_HAS_WIDER_MODES_P (class))
4399         break;
4400
4401       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
4402     }
4403   while (wider_mode != VOIDmode);
4404
4405   gcc_unreachable ();
4406 }
4407
4408 /* Generate code to compare X with Y so that the condition codes are
4409    set and to jump to LABEL if the condition is true.  If X is a
4410    constant and Y is not a constant, then the comparison is swapped to
4411    ensure that the comparison RTL has the canonical form.
4412
4413    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4414    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
4415    the proper branch condition code.
4416
4417    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4418
4419    MODE is the mode of the inputs (in case they are const_int).
4420
4421    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
4422    be passed unchanged to emit_cmp_insn, then potentially converted into an
4423    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
4424
4425 void
4426 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4427                          enum machine_mode mode, int unsignedp, rtx label)
4428 {
4429   rtx op0 = x, op1 = y;
4430
4431   /* Swap operands and condition to ensure canonical RTL.  */
4432   if (swap_commutative_operands_p (x, y))
4433     {
4434       /* If we're not emitting a branch, callers are required to pass
4435          operands in an order conforming to canonical RTL.  We relax this
4436          for commutative comparisons so callers using EQ don't need to do
4437          swapping by hand.  */
4438       gcc_assert (label || (comparison == swap_condition (comparison)));
4439
4440       op0 = y, op1 = x;
4441       comparison = swap_condition (comparison);
4442     }
4443
4444 #ifdef HAVE_cc0
4445   /* If OP0 is still a constant, then both X and Y must be constants.
4446      Force X into a register to create canonical RTL.  */
4447   if (CONSTANT_P (op0))
4448     op0 = force_reg (mode, op0);
4449 #endif
4450
4451   if (unsignedp)
4452     comparison = unsigned_condition (comparison);
4453
4454   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
4455                     ccp_jump);
4456   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
4457 }
4458
4459 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
4460
4461 void
4462 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4463                enum machine_mode mode, int unsignedp)
4464 {
4465   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
4466 }
4467 \f
4468 /* Emit a library call comparison between floating point X and Y.
4469    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4470
4471 static void
4472 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
4473                        enum machine_mode *pmode, int *punsignedp)
4474 {
4475   enum rtx_code comparison = *pcomparison;
4476   enum rtx_code swapped = swap_condition (comparison);
4477   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4478   rtx x = *px;
4479   rtx y = *py;
4480   enum machine_mode orig_mode = GET_MODE (x);
4481   enum machine_mode mode, cmp_mode;
4482   rtx value, target, insns, equiv;
4483   rtx libfunc = 0;
4484   bool reversed_p = false;
4485   cmp_mode = targetm.libgcc_cmp_return_mode ();
4486
4487   for (mode = orig_mode;
4488        mode != VOIDmode;
4489        mode = GET_MODE_WIDER_MODE (mode))
4490     {
4491       if ((libfunc = optab_libfunc (code_to_optab[comparison], mode)))
4492         break;
4493
4494       if ((libfunc = optab_libfunc (code_to_optab[swapped] , mode)))
4495         {
4496           rtx tmp;
4497           tmp = x; x = y; y = tmp;
4498           comparison = swapped;
4499           break;
4500         }
4501
4502       if ((libfunc = optab_libfunc (code_to_optab[reversed], mode))
4503           && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4504         {
4505           comparison = reversed;
4506           reversed_p = true;
4507           break;
4508         }
4509     }
4510
4511   gcc_assert (mode != VOIDmode);
4512
4513   if (mode != orig_mode)
4514     {
4515       x = convert_to_mode (mode, x, 0);
4516       y = convert_to_mode (mode, y, 0);
4517     }
4518
4519   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4520      the RTL.  The allows the RTL optimizers to delete the libcall if the
4521      condition can be determined at compile-time.  */
4522   if (comparison == UNORDERED)
4523     {
4524       rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4525       equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4526       equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4527                                     temp, const_true_rtx, equiv);
4528     }
4529   else
4530     {
4531       equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4532       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4533         {
4534           rtx true_rtx, false_rtx;
4535
4536           switch (comparison)
4537             {
4538             case EQ:
4539               true_rtx = const0_rtx;
4540               false_rtx = const_true_rtx;
4541               break;
4542
4543             case NE:
4544               true_rtx = const_true_rtx;
4545               false_rtx = const0_rtx;
4546               break;
4547
4548             case GT:
4549               true_rtx = const1_rtx;
4550               false_rtx = const0_rtx;
4551               break;
4552
4553             case GE:
4554               true_rtx = const0_rtx;
4555               false_rtx = constm1_rtx;
4556               break;
4557
4558             case LT:
4559               true_rtx = constm1_rtx;
4560               false_rtx = const0_rtx;
4561               break;
4562
4563             case LE:
4564               true_rtx = const0_rtx;
4565               false_rtx = const1_rtx;
4566               break;
4567
4568             default:
4569               gcc_unreachable ();
4570             }
4571           equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4572                                         equiv, true_rtx, false_rtx);
4573         }
4574     }
4575
4576   start_sequence ();
4577   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4578                                    cmp_mode, 2, x, mode, y, mode);
4579   insns = get_insns ();
4580   end_sequence ();
4581
4582   target = gen_reg_rtx (cmp_mode);
4583   emit_libcall_block (insns, target, value, equiv);
4584
4585   if (comparison == UNORDERED
4586       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4587     comparison = reversed_p ? EQ : NE;
4588
4589   *px = target;
4590   *py = const0_rtx;
4591   *pmode = cmp_mode;
4592   *pcomparison = comparison;
4593   *punsignedp = 0;
4594 }
4595 \f
4596 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4597
4598 void
4599 emit_indirect_jump (rtx loc)
4600 {
4601   if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4602       (loc, Pmode))
4603     loc = copy_to_mode_reg (Pmode, loc);
4604
4605   emit_jump_insn (gen_indirect_jump (loc));
4606   emit_barrier ();
4607 }
4608 \f
4609 #ifdef HAVE_conditional_move
4610
4611 /* Emit a conditional move instruction if the machine supports one for that
4612    condition and machine mode.
4613
4614    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4615    the mode to use should they be constants.  If it is VOIDmode, they cannot
4616    both be constants.
4617
4618    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4619    should be stored there.  MODE is the mode to use should they be constants.
4620    If it is VOIDmode, they cannot both be constants.
4621
4622    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4623    is not supported.  */
4624
4625 rtx
4626 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4627                        enum machine_mode cmode, rtx op2, rtx op3,
4628                        enum machine_mode mode, int unsignedp)
4629 {
4630   rtx tem, subtarget, comparison, insn;
4631   enum insn_code icode;
4632   enum rtx_code reversed;
4633
4634   /* If one operand is constant, make it the second one.  Only do this
4635      if the other operand is not constant as well.  */
4636
4637   if (swap_commutative_operands_p (op0, op1))
4638     {
4639       tem = op0;
4640       op0 = op1;
4641       op1 = tem;
4642       code = swap_condition (code);
4643     }
4644
4645   /* get_condition will prefer to generate LT and GT even if the old
4646      comparison was against zero, so undo that canonicalization here since
4647      comparisons against zero are cheaper.  */
4648   if (code == LT && op1 == const1_rtx)
4649     code = LE, op1 = const0_rtx;
4650   else if (code == GT && op1 == constm1_rtx)
4651     code = GE, op1 = const0_rtx;
4652
4653   if (cmode == VOIDmode)
4654     cmode = GET_MODE (op0);
4655
4656   if (swap_commutative_operands_p (op2, op3)
4657       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4658           != UNKNOWN))
4659     {
4660       tem = op2;
4661       op2 = op3;
4662       op3 = tem;
4663       code = reversed;
4664     }
4665
4666   if (mode == VOIDmode)
4667     mode = GET_MODE (op2);
4668
4669   icode = movcc_gen_code[mode];
4670
4671   if (icode == CODE_FOR_nothing)
4672     return 0;
4673
4674   if (!target)
4675     target = gen_reg_rtx (mode);
4676
4677   subtarget = target;
4678
4679   /* If the insn doesn't accept these operands, put them in pseudos.  */
4680
4681   if (!insn_data[icode].operand[0].predicate
4682       (subtarget, insn_data[icode].operand[0].mode))
4683     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4684
4685   if (!insn_data[icode].operand[2].predicate
4686       (op2, insn_data[icode].operand[2].mode))
4687     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4688
4689   if (!insn_data[icode].operand[3].predicate
4690       (op3, insn_data[icode].operand[3].mode))
4691     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4692
4693   /* Everything should now be in the suitable form, so emit the compare insn
4694      and then the conditional move.  */
4695
4696   comparison
4697     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4698
4699   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4700   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4701      return NULL and let the caller figure out how best to deal with this
4702      situation.  */
4703   if (GET_CODE (comparison) != code)
4704     return NULL_RTX;
4705
4706   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4707
4708   /* If that failed, then give up.  */
4709   if (insn == 0)
4710     return 0;
4711
4712   emit_insn (insn);
4713
4714   if (subtarget != target)
4715     convert_move (target, subtarget, 0);
4716
4717   return target;
4718 }
4719
4720 /* Return nonzero if a conditional move of mode MODE is supported.
4721
4722    This function is for combine so it can tell whether an insn that looks
4723    like a conditional move is actually supported by the hardware.  If we
4724    guess wrong we lose a bit on optimization, but that's it.  */
4725 /* ??? sparc64 supports conditionally moving integers values based on fp
4726    comparisons, and vice versa.  How do we handle them?  */
4727
4728 int
4729 can_conditionally_move_p (enum machine_mode mode)
4730 {
4731   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4732     return 1;
4733
4734   return 0;
4735 }
4736
4737 #endif /* HAVE_conditional_move */
4738
4739 /* Emit a conditional addition instruction if the machine supports one for that
4740    condition and machine mode.
4741
4742    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4743    the mode to use should they be constants.  If it is VOIDmode, they cannot
4744    both be constants.
4745
4746    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4747    should be stored there.  MODE is the mode to use should they be constants.
4748    If it is VOIDmode, they cannot both be constants.
4749
4750    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4751    is not supported.  */
4752
4753 rtx
4754 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4755                       enum machine_mode cmode, rtx op2, rtx op3,
4756                       enum machine_mode mode, int unsignedp)
4757 {
4758   rtx tem, subtarget, comparison, insn;
4759   enum insn_code icode;
4760   enum rtx_code reversed;
4761
4762   /* If one operand is constant, make it the second one.  Only do this
4763      if the other operand is not constant as well.  */
4764
4765   if (swap_commutative_operands_p (op0, op1))
4766     {
4767       tem = op0;
4768       op0 = op1;
4769       op1 = tem;
4770       code = swap_condition (code);
4771     }
4772
4773   /* get_condition will prefer to generate LT and GT even if the old
4774      comparison was against zero, so undo that canonicalization here since
4775      comparisons against zero are cheaper.  */
4776   if (code == LT && op1 == const1_rtx)
4777     code = LE, op1 = const0_rtx;
4778   else if (code == GT && op1 == constm1_rtx)
4779     code = GE, op1 = const0_rtx;
4780
4781   if (cmode == VOIDmode)
4782     cmode = GET_MODE (op0);
4783
4784   if (swap_commutative_operands_p (op2, op3)
4785       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4786           != UNKNOWN))
4787     {
4788       tem = op2;
4789       op2 = op3;
4790       op3 = tem;
4791       code = reversed;
4792     }
4793
4794   if (mode == VOIDmode)
4795     mode = GET_MODE (op2);
4796
4797   icode = optab_handler (addcc_optab, mode)->insn_code;
4798
4799   if (icode == CODE_FOR_nothing)
4800     return 0;
4801
4802   if (!target)
4803     target = gen_reg_rtx (mode);
4804
4805   /* If the insn doesn't accept these operands, put them in pseudos.  */
4806
4807   if (!insn_data[icode].operand[0].predicate
4808       (target, insn_data[icode].operand[0].mode))
4809     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4810   else
4811     subtarget = target;
4812
4813   if (!insn_data[icode].operand[2].predicate
4814       (op2, insn_data[icode].operand[2].mode))
4815     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4816
4817   if (!insn_data[icode].operand[3].predicate
4818       (op3, insn_data[icode].operand[3].mode))
4819     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4820
4821   /* Everything should now be in the suitable form, so emit the compare insn
4822      and then the conditional move.  */
4823
4824   comparison
4825     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4826
4827   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4828   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4829      return NULL and let the caller figure out how best to deal with this
4830      situation.  */
4831   if (GET_CODE (comparison) != code)
4832     return NULL_RTX;
4833
4834   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4835
4836   /* If that failed, then give up.  */
4837   if (insn == 0)
4838     return 0;
4839
4840   emit_insn (insn);
4841
4842   if (subtarget != target)
4843     convert_move (target, subtarget, 0);
4844
4845   return target;
4846 }
4847 \f
4848 /* These functions attempt to generate an insn body, rather than
4849    emitting the insn, but if the gen function already emits them, we
4850    make no attempt to turn them back into naked patterns.  */
4851
4852 /* Generate and return an insn body to add Y to X.  */
4853
4854 rtx
4855 gen_add2_insn (rtx x, rtx y)
4856 {
4857   int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4858
4859   gcc_assert (insn_data[icode].operand[0].predicate
4860               (x, insn_data[icode].operand[0].mode));
4861   gcc_assert (insn_data[icode].operand[1].predicate
4862               (x, insn_data[icode].operand[1].mode));
4863   gcc_assert (insn_data[icode].operand[2].predicate
4864               (y, insn_data[icode].operand[2].mode));
4865
4866   return GEN_FCN (icode) (x, x, y);
4867 }
4868
4869 /* Generate and return an insn body to add r1 and c,
4870    storing the result in r0.  */
4871
4872 rtx
4873 gen_add3_insn (rtx r0, rtx r1, rtx c)
4874 {
4875   int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code;
4876
4877   if (icode == CODE_FOR_nothing
4878       || !(insn_data[icode].operand[0].predicate
4879            (r0, insn_data[icode].operand[0].mode))
4880       || !(insn_data[icode].operand[1].predicate
4881            (r1, insn_data[icode].operand[1].mode))
4882       || !(insn_data[icode].operand[2].predicate
4883            (c, insn_data[icode].operand[2].mode)))
4884     return NULL_RTX;
4885
4886   return GEN_FCN (icode) (r0, r1, c);
4887 }
4888
4889 int
4890 have_add2_insn (rtx x, rtx y)
4891 {
4892   int icode;
4893
4894   gcc_assert (GET_MODE (x) != VOIDmode);
4895
4896   icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4897
4898   if (icode == CODE_FOR_nothing)
4899     return 0;
4900
4901   if (!(insn_data[icode].operand[0].predicate
4902         (x, insn_data[icode].operand[0].mode))
4903       || !(insn_data[icode].operand[1].predicate
4904            (x, insn_data[icode].operand[1].mode))
4905       || !(insn_data[icode].operand[2].predicate
4906            (y, insn_data[icode].operand[2].mode)))
4907     return 0;
4908
4909   return 1;
4910 }
4911
4912 /* Generate and return an insn body to subtract Y from X.  */
4913
4914 rtx
4915 gen_sub2_insn (rtx x, rtx y)
4916 {
4917   int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4918
4919   gcc_assert (insn_data[icode].operand[0].predicate
4920               (x, insn_data[icode].operand[0].mode));
4921   gcc_assert (insn_data[icode].operand[1].predicate
4922               (x, insn_data[icode].operand[1].mode));
4923   gcc_assert  (insn_data[icode].operand[2].predicate
4924                (y, insn_data[icode].operand[2].mode));
4925
4926   return GEN_FCN (icode) (x, x, y);
4927 }
4928
4929 /* Generate and return an insn body to subtract r1 and c,
4930    storing the result in r0.  */
4931
4932 rtx
4933 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4934 {
4935   int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code;
4936
4937   if (icode == CODE_FOR_nothing
4938       || !(insn_data[icode].operand[0].predicate
4939            (r0, insn_data[icode].operand[0].mode))
4940       || !(insn_data[icode].operand[1].predicate
4941            (r1, insn_data[icode].operand[1].mode))
4942       || !(insn_data[icode].operand[2].predicate
4943            (c, insn_data[icode].operand[2].mode)))
4944     return NULL_RTX;
4945
4946   return GEN_FCN (icode) (r0, r1, c);
4947 }
4948
4949 int
4950 have_sub2_insn (rtx x, rtx y)
4951 {
4952   int icode;
4953
4954   gcc_assert (GET_MODE (x) != VOIDmode);
4955
4956   icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4957
4958   if (icode == CODE_FOR_nothing)
4959     return 0;
4960
4961   if (!(insn_data[icode].operand[0].predicate
4962         (x, insn_data[icode].operand[0].mode))
4963       || !(insn_data[icode].operand[1].predicate
4964            (x, insn_data[icode].operand[1].mode))
4965       || !(insn_data[icode].operand[2].predicate
4966            (y, insn_data[icode].operand[2].mode)))
4967     return 0;
4968
4969   return 1;
4970 }
4971
4972 /* Generate the body of an instruction to copy Y into X.
4973    It may be a list of insns, if one insn isn't enough.  */
4974
4975 rtx
4976 gen_move_insn (rtx x, rtx y)
4977 {
4978   rtx seq;
4979
4980   start_sequence ();
4981   emit_move_insn_1 (x, y);
4982   seq = get_insns ();
4983   end_sequence ();
4984   return seq;
4985 }
4986 \f
4987 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4988    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4989    no such operation exists, CODE_FOR_nothing will be returned.  */
4990
4991 enum insn_code
4992 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4993               int unsignedp)
4994 {
4995   convert_optab tab;
4996 #ifdef HAVE_ptr_extend
4997   if (unsignedp < 0)
4998     return CODE_FOR_ptr_extend;
4999 #endif
5000
5001   tab = unsignedp ? zext_optab : sext_optab;
5002   return convert_optab_handler (tab, to_mode, from_mode)->insn_code;
5003 }
5004
5005 /* Generate the body of an insn to extend Y (with mode MFROM)
5006    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
5007
5008 rtx
5009 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
5010                  enum machine_mode mfrom, int unsignedp)
5011 {
5012   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
5013   return GEN_FCN (icode) (x, y);
5014 }
5015 \f
5016 /* can_fix_p and can_float_p say whether the target machine
5017    can directly convert a given fixed point type to
5018    a given floating point type, or vice versa.
5019    The returned value is the CODE_FOR_... value to use,
5020    or CODE_FOR_nothing if these modes cannot be directly converted.
5021
5022    *TRUNCP_PTR is set to 1 if it is necessary to output
5023    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
5024
5025 static enum insn_code
5026 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
5027            int unsignedp, int *truncp_ptr)
5028 {
5029   convert_optab tab;
5030   enum insn_code icode;
5031
5032   tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
5033   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
5034   if (icode != CODE_FOR_nothing)
5035     {
5036       *truncp_ptr = 0;
5037       return icode;
5038     }
5039
5040   /* FIXME: This requires a port to define both FIX and FTRUNC pattern
5041      for this to work. We need to rework the fix* and ftrunc* patterns
5042      and documentation.  */
5043   tab = unsignedp ? ufix_optab : sfix_optab;
5044   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
5045   if (icode != CODE_FOR_nothing
5046       && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing)
5047     {
5048       *truncp_ptr = 1;
5049       return icode;
5050     }
5051
5052   *truncp_ptr = 0;
5053   return CODE_FOR_nothing;
5054 }
5055
5056 static enum insn_code
5057 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
5058              int unsignedp)
5059 {
5060   convert_optab tab;
5061
5062   tab = unsignedp ? ufloat_optab : sfloat_optab;
5063   return convert_optab_handler (tab, fltmode, fixmode)->insn_code;
5064 }
5065 \f
5066 /* Generate code to convert FROM to floating point
5067    and store in TO.  FROM must be fixed point and not VOIDmode.
5068    UNSIGNEDP nonzero means regard FROM as unsigned.
5069    Normally this is done by correcting the final value
5070    if it is negative.  */
5071
5072 void
5073 expand_float (rtx to, rtx from, int unsignedp)
5074 {
5075   enum insn_code icode;
5076   rtx target = to;
5077   enum machine_mode fmode, imode;
5078   bool can_do_signed = false;
5079
5080   /* Crash now, because we won't be able to decide which mode to use.  */
5081   gcc_assert (GET_MODE (from) != VOIDmode);
5082
5083   /* Look for an insn to do the conversion.  Do it in the specified
5084      modes if possible; otherwise convert either input, output or both to
5085      wider mode.  If the integer mode is wider than the mode of FROM,
5086      we can do the conversion signed even if the input is unsigned.  */
5087
5088   for (fmode = GET_MODE (to); fmode != VOIDmode;
5089        fmode = GET_MODE_WIDER_MODE (fmode))
5090     for (imode = GET_MODE (from); imode != VOIDmode;
5091          imode = GET_MODE_WIDER_MODE (imode))
5092       {
5093         int doing_unsigned = unsignedp;
5094
5095         if (fmode != GET_MODE (to)
5096             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
5097           continue;
5098
5099         icode = can_float_p (fmode, imode, unsignedp);
5100         if (icode == CODE_FOR_nothing && unsignedp)
5101           {
5102             enum insn_code scode = can_float_p (fmode, imode, 0);
5103             if (scode != CODE_FOR_nothing)
5104               can_do_signed = true;
5105             if (imode != GET_MODE (from))
5106               icode = scode, doing_unsigned = 0;
5107           }
5108
5109         if (icode != CODE_FOR_nothing)
5110           {
5111             if (imode != GET_MODE (from))
5112               from = convert_to_mode (imode, from, unsignedp);
5113
5114             if (fmode != GET_MODE (to))
5115               target = gen_reg_rtx (fmode);
5116
5117             emit_unop_insn (icode, target, from,
5118                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5119
5120             if (target != to)
5121               convert_move (to, target, 0);
5122             return;
5123           }
5124       }
5125
5126   /* Unsigned integer, and no way to convert directly.  Convert as signed,
5127      then unconditionally adjust the result.  For decimal float values we
5128      do this only if we have already determined that a signed conversion
5129      provides sufficient accuracy.  */
5130   if (unsignedp && (can_do_signed || !DECIMAL_FLOAT_MODE_P (GET_MODE (to))))
5131     {
5132       rtx label = gen_label_rtx ();
5133       rtx temp;
5134       REAL_VALUE_TYPE offset;
5135
5136       /* Look for a usable floating mode FMODE wider than the source and at
5137          least as wide as the target.  Using FMODE will avoid rounding woes
5138          with unsigned values greater than the signed maximum value.  */
5139
5140       for (fmode = GET_MODE (to);  fmode != VOIDmode;
5141            fmode = GET_MODE_WIDER_MODE (fmode))
5142         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5143             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5144           break;
5145
5146       if (fmode == VOIDmode)
5147         {
5148           /* There is no such mode.  Pretend the target is wide enough.  */
5149           fmode = GET_MODE (to);
5150
5151           /* Avoid double-rounding when TO is narrower than FROM.  */
5152           if ((significand_size (fmode) + 1)
5153               < GET_MODE_BITSIZE (GET_MODE (from)))
5154             {
5155               rtx temp1;
5156               rtx neglabel = gen_label_rtx ();
5157
5158               /* Don't use TARGET if it isn't a register, is a hard register,
5159                  or is the wrong mode.  */
5160               if (!REG_P (target)
5161                   || REGNO (target) < FIRST_PSEUDO_REGISTER
5162                   || GET_MODE (target) != fmode)
5163                 target = gen_reg_rtx (fmode);
5164
5165               imode = GET_MODE (from);
5166               do_pending_stack_adjust ();
5167
5168               /* Test whether the sign bit is set.  */
5169               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5170                                        0, neglabel);
5171
5172               /* The sign bit is not set.  Convert as signed.  */
5173               expand_float (target, from, 0);
5174               emit_jump_insn (gen_jump (label));
5175               emit_barrier ();
5176
5177               /* The sign bit is set.
5178                  Convert to a usable (positive signed) value by shifting right
5179                  one bit, while remembering if a nonzero bit was shifted
5180                  out; i.e., compute  (from & 1) | (from >> 1).  */
5181
5182               emit_label (neglabel);
5183               temp = expand_binop (imode, and_optab, from, const1_rtx,
5184                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
5185               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
5186                                     NULL_RTX, 1);
5187               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5188                                    OPTAB_LIB_WIDEN);
5189               expand_float (target, temp, 0);
5190
5191               /* Multiply by 2 to undo the shift above.  */
5192               temp = expand_binop (fmode, add_optab, target, target,
5193                                    target, 0, OPTAB_LIB_WIDEN);
5194               if (temp != target)
5195                 emit_move_insn (target, temp);
5196
5197               do_pending_stack_adjust ();
5198               emit_label (label);
5199               goto done;
5200             }
5201         }
5202
5203       /* If we are about to do some arithmetic to correct for an
5204          unsigned operand, do it in a pseudo-register.  */
5205
5206       if (GET_MODE (to) != fmode
5207           || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5208         target = gen_reg_rtx (fmode);
5209
5210       /* Convert as signed integer to floating.  */
5211       expand_float (target, from, 0);
5212
5213       /* If FROM is negative (and therefore TO is negative),
5214          correct its value by 2**bitwidth.  */
5215
5216       do_pending_stack_adjust ();
5217       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5218                                0, label);
5219
5220
5221       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)), fmode);
5222       temp = expand_binop (fmode, add_optab, target,
5223                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5224                            target, 0, OPTAB_LIB_WIDEN);
5225       if (temp != target)
5226         emit_move_insn (target, temp);
5227
5228       do_pending_stack_adjust ();
5229       emit_label (label);
5230       goto done;
5231     }
5232
5233   /* No hardware instruction available; call a library routine.  */
5234     {
5235       rtx libfunc;
5236       rtx insns;
5237       rtx value;
5238       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5239
5240       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5241         from = convert_to_mode (SImode, from, unsignedp);
5242
5243       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5244       gcc_assert (libfunc);
5245
5246       start_sequence ();
5247
5248       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5249                                        GET_MODE (to), 1, from,
5250                                        GET_MODE (from));
5251       insns = get_insns ();
5252       end_sequence ();
5253
5254       emit_libcall_block (insns, target, value,
5255                           gen_rtx_FLOAT (GET_MODE (to), from));
5256     }
5257
5258  done:
5259
5260   /* Copy result to requested destination
5261      if we have been computing in a temp location.  */
5262
5263   if (target != to)
5264     {
5265       if (GET_MODE (target) == GET_MODE (to))
5266         emit_move_insn (to, target);
5267       else
5268         convert_move (to, target, 0);
5269     }
5270 }
5271 \f
5272 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5273    must be floating point.  */
5274
5275 void
5276 expand_fix (rtx to, rtx from, int unsignedp)
5277 {
5278   enum insn_code icode;
5279   rtx target = to;
5280   enum machine_mode fmode, imode;
5281   int must_trunc = 0;
5282
5283   /* We first try to find a pair of modes, one real and one integer, at
5284      least as wide as FROM and TO, respectively, in which we can open-code
5285      this conversion.  If the integer mode is wider than the mode of TO,
5286      we can do the conversion either signed or unsigned.  */
5287
5288   for (fmode = GET_MODE (from); fmode != VOIDmode;
5289        fmode = GET_MODE_WIDER_MODE (fmode))
5290     for (imode = GET_MODE (to); imode != VOIDmode;
5291          imode = GET_MODE_WIDER_MODE (imode))
5292       {
5293         int doing_unsigned = unsignedp;
5294
5295         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5296         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5297           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5298
5299         if (icode != CODE_FOR_nothing)
5300           {
5301             if (fmode != GET_MODE (from))
5302               from = convert_to_mode (fmode, from, 0);
5303
5304             if (must_trunc)
5305               {
5306                 rtx temp = gen_reg_rtx (GET_MODE (from));
5307                 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5308                                     temp, 0);
5309               }
5310
5311             if (imode != GET_MODE (to))
5312               target = gen_reg_rtx (imode);
5313
5314             emit_unop_insn (icode, target, from,
5315                             doing_unsigned ? UNSIGNED_FIX : FIX);
5316             if (target != to)
5317               convert_move (to, target, unsignedp);
5318             return;
5319           }
5320       }
5321
5322   /* For an unsigned conversion, there is one more way to do it.
5323      If we have a signed conversion, we generate code that compares
5324      the real value to the largest representable positive number.  If if
5325      is smaller, the conversion is done normally.  Otherwise, subtract
5326      one plus the highest signed number, convert, and add it back.
5327
5328      We only need to check all real modes, since we know we didn't find
5329      anything with a wider integer mode.
5330
5331      This code used to extend FP value into mode wider than the destination.
5332      This is needed for decimal float modes which cannot accurately
5333      represent one plus the highest signed number of the same size, but
5334      not for binary modes.  Consider, for instance conversion from SFmode
5335      into DImode.
5336
5337      The hot path through the code is dealing with inputs smaller than 2^63
5338      and doing just the conversion, so there is no bits to lose.
5339
5340      In the other path we know the value is positive in the range 2^63..2^64-1
5341      inclusive.  (as for other input overflow happens and result is undefined)
5342      So we know that the most important bit set in mantissa corresponds to
5343      2^63.  The subtraction of 2^63 should not generate any rounding as it
5344      simply clears out that bit.  The rest is trivial.  */
5345
5346   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5347     for (fmode = GET_MODE (from); fmode != VOIDmode;
5348          fmode = GET_MODE_WIDER_MODE (fmode))
5349       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5350           && (!DECIMAL_FLOAT_MODE_P (fmode)
5351               || GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))))
5352         {
5353           int bitsize;
5354           REAL_VALUE_TYPE offset;
5355           rtx limit, lab1, lab2, insn;
5356
5357           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5358           real_2expN (&offset, bitsize - 1, fmode);
5359           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5360           lab1 = gen_label_rtx ();
5361           lab2 = gen_label_rtx ();
5362
5363           if (fmode != GET_MODE (from))
5364             from = convert_to_mode (fmode, from, 0);
5365
5366           /* See if we need to do the subtraction.  */
5367           do_pending_stack_adjust ();
5368           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5369                                    0, lab1);
5370
5371           /* If not, do the signed "fix" and branch around fixup code.  */
5372           expand_fix (to, from, 0);
5373           emit_jump_insn (gen_jump (lab2));
5374           emit_barrier ();
5375
5376           /* Otherwise, subtract 2**(N-1), convert to signed number,
5377              then add 2**(N-1).  Do the addition using XOR since this
5378              will often generate better code.  */
5379           emit_label (lab1);
5380           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5381                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
5382           expand_fix (to, target, 0);
5383           target = expand_binop (GET_MODE (to), xor_optab, to,
5384                                  gen_int_mode
5385                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
5386                                   GET_MODE (to)),
5387                                  to, 1, OPTAB_LIB_WIDEN);
5388
5389           if (target != to)
5390             emit_move_insn (to, target);
5391
5392           emit_label (lab2);
5393
5394           if (optab_handler (mov_optab, GET_MODE (to))->insn_code
5395               != CODE_FOR_nothing)
5396             {
5397               /* Make a place for a REG_NOTE and add it.  */
5398               insn = emit_move_insn (to, to);
5399               set_unique_reg_note (insn,
5400                                    REG_EQUAL,
5401                                    gen_rtx_fmt_e (UNSIGNED_FIX,
5402                                                   GET_MODE (to),
5403                                                   copy_rtx (from)));
5404             }
5405
5406           return;
5407         }
5408
5409   /* We can't do it with an insn, so use a library call.  But first ensure
5410      that the mode of TO is at least as wide as SImode, since those are the
5411      only library calls we know about.  */
5412
5413   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5414     {
5415       target = gen_reg_rtx (SImode);
5416
5417       expand_fix (target, from, unsignedp);
5418     }
5419   else
5420     {
5421       rtx insns;
5422       rtx value;
5423       rtx libfunc;
5424
5425       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5426       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5427       gcc_assert (libfunc);
5428
5429       start_sequence ();
5430
5431       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5432                                        GET_MODE (to), 1, from,
5433                                        GET_MODE (from));
5434       insns = get_insns ();
5435       end_sequence ();
5436
5437       emit_libcall_block (insns, target, value,
5438                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5439                                          GET_MODE (to), from));
5440     }
5441
5442   if (target != to)
5443     {
5444       if (GET_MODE (to) == GET_MODE (target))
5445         emit_move_insn (to, target);
5446       else
5447         convert_move (to, target, 0);
5448     }
5449 }
5450
5451 /* Generate code to convert FROM or TO a fixed-point.
5452    If UINTP is true, either TO or FROM is an unsigned integer.
5453    If SATP is true, we need to saturate the result.  */
5454
5455 void
5456 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5457 {
5458   enum machine_mode to_mode = GET_MODE (to);
5459   enum machine_mode from_mode = GET_MODE (from);
5460   convert_optab tab;
5461   enum rtx_code this_code;
5462   enum insn_code code;
5463   rtx insns, value;
5464   rtx libfunc;
5465
5466   if (to_mode == from_mode)
5467     {
5468       emit_move_insn (to, from);
5469       return;
5470     }
5471
5472   if (uintp)
5473     {
5474       tab = satp ? satfractuns_optab : fractuns_optab;
5475       this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5476     }
5477   else
5478     {
5479       tab = satp ? satfract_optab : fract_optab;
5480       this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5481     }
5482   code = tab->handlers[to_mode][from_mode].insn_code;
5483   if (code != CODE_FOR_nothing)
5484     {
5485       emit_unop_insn (code, to, from, this_code);
5486       return;
5487     }
5488
5489   libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5490   gcc_assert (libfunc);
5491
5492   start_sequence ();
5493   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5494                                    1, from, from_mode);
5495   insns = get_insns ();
5496   end_sequence ();
5497
5498   emit_libcall_block (insns, to, value,
5499                       gen_rtx_fmt_e (tab->code, to_mode, from));
5500 }
5501
5502 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5503    must be floating point, TO must be signed.  Use the conversion optab
5504    TAB to do the conversion.  */
5505
5506 bool
5507 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5508 {
5509   enum insn_code icode;
5510   rtx target = to;
5511   enum machine_mode fmode, imode;
5512
5513   /* We first try to find a pair of modes, one real and one integer, at
5514      least as wide as FROM and TO, respectively, in which we can open-code
5515      this conversion.  If the integer mode is wider than the mode of TO,
5516      we can do the conversion either signed or unsigned.  */
5517
5518   for (fmode = GET_MODE (from); fmode != VOIDmode;
5519        fmode = GET_MODE_WIDER_MODE (fmode))
5520     for (imode = GET_MODE (to); imode != VOIDmode;
5521          imode = GET_MODE_WIDER_MODE (imode))
5522       {
5523         icode = convert_optab_handler (tab, imode, fmode)->insn_code;
5524         if (icode != CODE_FOR_nothing)
5525           {
5526             if (fmode != GET_MODE (from))
5527               from = convert_to_mode (fmode, from, 0);
5528
5529             if (imode != GET_MODE (to))
5530               target = gen_reg_rtx (imode);
5531
5532             emit_unop_insn (icode, target, from, UNKNOWN);
5533             if (target != to)
5534               convert_move (to, target, 0);
5535             return true;
5536           }
5537       }
5538
5539   return false;
5540 }
5541 \f
5542 /* Report whether we have an instruction to perform the operation
5543    specified by CODE on operands of mode MODE.  */
5544 int
5545 have_insn_for (enum rtx_code code, enum machine_mode mode)
5546 {
5547   return (code_to_optab[(int) code] != 0
5548           && (optab_handler (code_to_optab[(int) code], mode)->insn_code
5549               != CODE_FOR_nothing));
5550 }
5551
5552 /* Create a blank optab.  */
5553 static optab
5554 new_optab (void)
5555 {
5556   int i;
5557   optab op = xcalloc (sizeof (struct optab), 1);
5558
5559   for (i = 0; i < NUM_MACHINE_MODES; i++)
5560     optab_handler (op, i)->insn_code = CODE_FOR_nothing;
5561
5562   return op;
5563 }
5564
5565 static convert_optab
5566 new_convert_optab (void)
5567 {
5568   int i, j;
5569   convert_optab op = xcalloc (sizeof (struct convert_optab), 1);
5570
5571   for (i = 0; i < NUM_MACHINE_MODES; i++)
5572     for (j = 0; j < NUM_MACHINE_MODES; j++)
5573       convert_optab_handler (op, i, j)->insn_code = CODE_FOR_nothing;
5574
5575   return op;
5576 }
5577
5578 /* Same, but fill in its code as CODE, and write it into the
5579    code_to_optab table.  */
5580 static inline optab
5581 init_optab (enum rtx_code code)
5582 {
5583   optab op = new_optab ();
5584   op->code = code;
5585   code_to_optab[(int) code] = op;
5586   return op;
5587 }
5588
5589 /* Same, but fill in its code as CODE, and do _not_ write it into
5590    the code_to_optab table.  */
5591 static inline optab
5592 init_optabv (enum rtx_code code)
5593 {
5594   optab op = new_optab ();
5595   op->code = code;
5596   return op;
5597 }
5598
5599 /* Conversion optabs never go in the code_to_optab table.  */
5600 static inline convert_optab
5601 init_convert_optab (enum rtx_code code)
5602 {
5603   convert_optab op = new_convert_optab ();
5604   op->code = code;
5605   return op;
5606 }
5607
5608 /* Initialize the libfunc fields of an entire group of entries in some
5609    optab.  Each entry is set equal to a string consisting of a leading
5610    pair of underscores followed by a generic operation name followed by
5611    a mode name (downshifted to lowercase) followed by a single character
5612    representing the number of operands for the given operation (which is
5613    usually one of the characters '2', '3', or '4').
5614
5615    OPTABLE is the table in which libfunc fields are to be initialized.
5616    OPNAME is the generic (string) name of the operation.
5617    SUFFIX is the character which specifies the number of operands for
5618      the given generic operation.
5619    MODE is the mode to generate for.
5620 */
5621
5622 static void
5623 gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mode)
5624 {
5625   unsigned opname_len = strlen (opname);
5626   const char *mname = GET_MODE_NAME (mode);
5627   unsigned mname_len = strlen (mname);
5628   char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5629   char *p;
5630   const char *q;
5631
5632   p = libfunc_name;
5633   *p++ = '_';
5634   *p++ = '_';
5635   for (q = opname; *q; )
5636     *p++ = *q++;
5637   for (q = mname; *q; q++)
5638     *p++ = TOLOWER (*q);
5639   *p++ = suffix;
5640   *p = '\0';
5641
5642   set_optab_libfunc (optable, mode,
5643                      ggc_alloc_string (libfunc_name, p - libfunc_name));
5644 }
5645
5646 /* Like gen_libfunc, but verify that integer operation is involved.  */
5647
5648 static void
5649 gen_int_libfunc (optab optable, const char *opname, char suffix,
5650                  enum machine_mode mode)
5651 {
5652   int maxsize = 2 * BITS_PER_WORD;
5653
5654   if (GET_MODE_CLASS (mode) != MODE_INT)
5655     return;
5656   if (maxsize < LONG_LONG_TYPE_SIZE)
5657     maxsize = LONG_LONG_TYPE_SIZE;
5658   if (GET_MODE_CLASS (mode) != MODE_INT
5659       || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5660     return;
5661   gen_libfunc (optable, opname, suffix, mode);
5662 }
5663
5664 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed.  */
5665
5666 static void
5667 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5668                 enum machine_mode mode)
5669 {
5670   char *dec_opname;
5671
5672   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5673     gen_libfunc (optable, opname, suffix, mode);
5674   if (DECIMAL_FLOAT_MODE_P (mode))
5675     {
5676       dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
5677       /* For BID support, change the name to have either a bid_ or dpd_ prefix
5678          depending on the low level floating format used.  */
5679       memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5680       strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5681       gen_libfunc (optable, dec_opname, suffix, mode);
5682     }
5683 }
5684
5685 /* Like gen_libfunc, but verify that fixed-point operation is involved.  */
5686
5687 static void
5688 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5689                    enum machine_mode mode)
5690 {
5691   if (!ALL_FIXED_POINT_MODE_P (mode))
5692     return;
5693   gen_libfunc (optable, opname, suffix, mode);
5694 }
5695
5696 /* Like gen_libfunc, but verify that signed fixed-point operation is
5697    involved.  */
5698
5699 static void
5700 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5701                           enum machine_mode mode)
5702 {
5703   if (!SIGNED_FIXED_POINT_MODE_P (mode))
5704     return;
5705   gen_libfunc (optable, opname, suffix, mode);
5706 }
5707
5708 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5709    involved.  */
5710
5711 static void
5712 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5713                             enum machine_mode mode)
5714 {
5715   if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5716     return;
5717   gen_libfunc (optable, opname, suffix, mode);
5718 }
5719
5720 /* Like gen_libfunc, but verify that FP or INT operation is involved.  */
5721
5722 static void
5723 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5724                     enum machine_mode mode)
5725 {
5726   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5727     gen_fp_libfunc (optable, name, suffix, mode);
5728   if (INTEGRAL_MODE_P (mode))
5729     gen_int_libfunc (optable, name, suffix, mode);
5730 }
5731
5732 /* Like gen_libfunc, but verify that FP or INT operation is involved
5733    and add 'v' suffix for integer operation.  */
5734
5735 static void
5736 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5737                      enum machine_mode mode)
5738 {
5739   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5740     gen_fp_libfunc (optable, name, suffix, mode);
5741   if (GET_MODE_CLASS (mode) == MODE_INT)
5742     {
5743       int len = strlen (name);
5744       char *v_name = alloca (len + 2);
5745       strcpy (v_name, name);
5746       v_name[len] = 'v';
5747       v_name[len + 1] = 0;
5748       gen_int_libfunc (optable, v_name, suffix, mode);
5749     }
5750 }
5751
5752 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5753    involved.  */
5754
5755 static void
5756 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5757                           enum machine_mode mode)
5758 {
5759   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5760     gen_fp_libfunc (optable, name, suffix, mode);
5761   if (INTEGRAL_MODE_P (mode))
5762     gen_int_libfunc (optable, name, suffix, mode);
5763   if (ALL_FIXED_POINT_MODE_P (mode))
5764     gen_fixed_libfunc (optable, name, suffix, mode);
5765 }
5766
5767 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5768    involved.  */
5769
5770 static void
5771 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5772                                  enum machine_mode mode)
5773 {
5774   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5775     gen_fp_libfunc (optable, name, suffix, mode);
5776   if (INTEGRAL_MODE_P (mode))
5777     gen_int_libfunc (optable, name, suffix, mode);
5778   if (SIGNED_FIXED_POINT_MODE_P (mode))
5779     gen_signed_fixed_libfunc (optable, name, suffix, mode);
5780 }
5781
5782 /* Like gen_libfunc, but verify that INT or FIXED operation is
5783    involved.  */
5784
5785 static void
5786 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5787                        enum machine_mode mode)
5788 {
5789   if (INTEGRAL_MODE_P (mode))
5790     gen_int_libfunc (optable, name, suffix, mode);
5791   if (ALL_FIXED_POINT_MODE_P (mode))
5792     gen_fixed_libfunc (optable, name, suffix, mode);
5793 }
5794
5795 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5796    involved.  */
5797
5798 static void
5799 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5800                               enum machine_mode mode)
5801 {
5802   if (INTEGRAL_MODE_P (mode))
5803     gen_int_libfunc (optable, name, suffix, mode);
5804   if (SIGNED_FIXED_POINT_MODE_P (mode))
5805     gen_signed_fixed_libfunc (optable, name, suffix, mode);
5806 }
5807
5808 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5809    involved.  */
5810
5811 static void
5812 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5813                                 enum machine_mode mode)
5814 {
5815   if (INTEGRAL_MODE_P (mode))
5816     gen_int_libfunc (optable, name, suffix, mode);
5817   if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5818     gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5819 }
5820
5821 /* Initialize the libfunc fields of an entire group of entries of an
5822    inter-mode-class conversion optab.  The string formation rules are
5823    similar to the ones for init_libfuncs, above, but instead of having
5824    a mode name and an operand count these functions have two mode names
5825    and no operand count.  */
5826
5827 static void
5828 gen_interclass_conv_libfunc (convert_optab tab,
5829                              const char *opname,
5830                              enum machine_mode tmode,
5831                              enum machine_mode fmode)
5832 {
5833   size_t opname_len = strlen (opname);
5834   size_t mname_len = 0;
5835
5836   const char *fname, *tname;
5837   const char *q;
5838   char *libfunc_name, *suffix;
5839   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5840   char *p;
5841
5842   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5843      depends on which underlying decimal floating point format is used.  */
5844   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5845
5846   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5847
5848   nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
5849   nondec_name[0] = '_';
5850   nondec_name[1] = '_';
5851   memcpy (&nondec_name[2], opname, opname_len);
5852   nondec_suffix = nondec_name + opname_len + 2;
5853
5854   dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
5855   dec_name[0] = '_';
5856   dec_name[1] = '_';
5857   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5858   memcpy (&dec_name[2+dec_len], opname, opname_len);
5859   dec_suffix = dec_name + dec_len + opname_len + 2;
5860
5861   fname = GET_MODE_NAME (fmode);
5862   tname = GET_MODE_NAME (tmode);
5863
5864   if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5865     {
5866       libfunc_name = dec_name;
5867       suffix = dec_suffix;
5868     }
5869   else
5870     {
5871       libfunc_name = nondec_name;
5872       suffix = nondec_suffix;
5873     }
5874
5875   p = suffix;
5876   for (q = fname; *q; p++, q++)
5877     *p = TOLOWER (*q);
5878   for (q = tname; *q; p++, q++)
5879     *p = TOLOWER (*q);
5880
5881   *p = '\0';
5882
5883   set_conv_libfunc (tab, tmode, fmode,
5884                     ggc_alloc_string (libfunc_name, p - libfunc_name));
5885 }
5886
5887 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5888    int->fp conversion.  */
5889
5890 static void
5891 gen_int_to_fp_conv_libfunc (convert_optab tab,
5892                             const char *opname,
5893                             enum machine_mode tmode,
5894                             enum machine_mode fmode)
5895 {
5896   if (GET_MODE_CLASS (fmode) != MODE_INT)
5897     return;
5898   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5899     return;
5900   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5901 }
5902
5903 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5904    naming scheme.  */
5905
5906 static void
5907 gen_ufloat_conv_libfunc (convert_optab tab,
5908                          const char *opname ATTRIBUTE_UNUSED,
5909                          enum machine_mode tmode,
5910                          enum machine_mode fmode)
5911 {
5912   if (DECIMAL_FLOAT_MODE_P (tmode))
5913     gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5914   else
5915     gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5916 }
5917
5918 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5919    fp->int conversion.  */
5920
5921 static void
5922 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5923                                        const char *opname,
5924                                        enum machine_mode tmode,
5925                                        enum machine_mode fmode)
5926 {
5927   if (GET_MODE_CLASS (fmode) != MODE_INT)
5928     return;
5929   if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5930     return;
5931   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5932 }
5933
5934 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5935    fp->int conversion with no decimal floating point involved.  */
5936
5937 static void
5938 gen_fp_to_int_conv_libfunc (convert_optab tab,
5939                             const char *opname,
5940                             enum machine_mode tmode,
5941                             enum machine_mode fmode)
5942 {
5943   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5944     return;
5945   if (GET_MODE_CLASS (tmode) != MODE_INT)
5946     return;
5947   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5948 }
5949
5950 /* Initialize the libfunc fiels of an of an intra-mode-class conversion optab.
5951    The string formation rules are
5952    similar to the ones for init_libfunc, above.  */
5953
5954 static void
5955 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5956                              enum machine_mode tmode, enum machine_mode fmode)
5957 {
5958   size_t opname_len = strlen (opname);
5959   size_t mname_len = 0;
5960
5961   const char *fname, *tname;
5962   const char *q;
5963   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5964   char *libfunc_name, *suffix;
5965   char *p;
5966
5967   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5968      depends on which underlying decimal floating point format is used.  */
5969   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5970
5971   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5972
5973   nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
5974   nondec_name[0] = '_';
5975   nondec_name[1] = '_';
5976   memcpy (&nondec_name[2], opname, opname_len);
5977   nondec_suffix = nondec_name + opname_len + 2;
5978
5979   dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
5980   dec_name[0] = '_';
5981   dec_name[1] = '_';
5982   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5983   memcpy (&dec_name[2 + dec_len], opname, opname_len);
5984   dec_suffix = dec_name + dec_len + opname_len + 2;
5985
5986   fname = GET_MODE_NAME (fmode);
5987   tname = GET_MODE_NAME (tmode);
5988
5989   if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5990     {
5991       libfunc_name = dec_name;
5992       suffix = dec_suffix;
5993     }
5994   else
5995     {
5996       libfunc_name = nondec_name;
5997       suffix = nondec_suffix;
5998     }
5999
6000   p = suffix;
6001   for (q = fname; *q; p++, q++)
6002     *p = TOLOWER (*q);
6003   for (q = tname; *q; p++, q++)
6004     *p = TOLOWER (*q);
6005
6006   *p++ = '2';
6007   *p = '\0';
6008
6009   set_conv_libfunc (tab, tmode, fmode,
6010                     ggc_alloc_string (libfunc_name, p - libfunc_name));
6011 }
6012
6013 /* Pick proper libcall for trunc_optab.  We need to chose if we do
6014    truncation or extension and interclass or intraclass.  */
6015
6016 static void
6017 gen_trunc_conv_libfunc (convert_optab tab,
6018                          const char *opname,
6019                          enum machine_mode tmode,
6020                          enum machine_mode fmode)
6021 {
6022   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
6023     return;
6024   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
6025     return;
6026   if (tmode == fmode)
6027     return;
6028
6029   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
6030       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
6031      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6032   
6033   if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
6034     return;
6035
6036   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
6037        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
6038       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
6039     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6040 }
6041
6042 /* Pick proper libcall for extend_optab.  We need to chose if we do
6043    truncation or extension and interclass or intraclass.  */
6044
6045 static void
6046 gen_extend_conv_libfunc (convert_optab tab,
6047                          const char *opname ATTRIBUTE_UNUSED,
6048                          enum machine_mode tmode,
6049                          enum machine_mode fmode)
6050 {
6051   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
6052     return;
6053   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
6054     return;
6055   if (tmode == fmode)
6056     return;
6057
6058   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
6059       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
6060      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6061   
6062   if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
6063     return;
6064
6065   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
6066        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
6067       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
6068     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6069 }
6070
6071 /* Pick proper libcall for fract_optab.  We need to chose if we do
6072    interclass or intraclass.  */
6073
6074 static void
6075 gen_fract_conv_libfunc (convert_optab tab,
6076                         const char *opname,
6077                         enum machine_mode tmode,
6078                         enum machine_mode fmode)
6079 {
6080   if (tmode == fmode)
6081     return;
6082   if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
6083     return;
6084
6085   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6086     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6087   else
6088     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6089 }
6090
6091 /* Pick proper libcall for fractuns_optab.  */
6092
6093 static void
6094 gen_fractuns_conv_libfunc (convert_optab tab,
6095                            const char *opname,
6096                            enum machine_mode tmode,
6097                            enum machine_mode fmode)
6098 {
6099   if (tmode == fmode)
6100     return;
6101   /* One mode must be a fixed-point mode, and the other must be an integer
6102      mode. */
6103   if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
6104         || (ALL_FIXED_POINT_MODE_P (fmode)
6105             && GET_MODE_CLASS (tmode) == MODE_INT)))
6106     return;
6107
6108   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6109 }
6110
6111 /* Pick proper libcall for satfract_optab.  We need to chose if we do
6112    interclass or intraclass.  */
6113
6114 static void
6115 gen_satfract_conv_libfunc (convert_optab tab,
6116                            const char *opname,
6117                            enum machine_mode tmode,
6118                            enum machine_mode fmode)
6119 {
6120   if (tmode == fmode)
6121     return;
6122   /* TMODE must be a fixed-point mode.  */
6123   if (!ALL_FIXED_POINT_MODE_P (tmode))
6124     return;
6125
6126   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6127     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6128   else
6129     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6130 }
6131
6132 /* Pick proper libcall for satfractuns_optab.  */
6133
6134 static void
6135 gen_satfractuns_conv_libfunc (convert_optab tab,
6136                               const char *opname,
6137                               enum machine_mode tmode,
6138                               enum machine_mode fmode)
6139 {
6140   if (tmode == fmode)
6141     return;
6142   /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6143   if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
6144     return;
6145
6146   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6147 }
6148
6149 rtx
6150 init_one_libfunc (const char *name)
6151 {
6152   rtx symbol;
6153
6154   /* Create a FUNCTION_DECL that can be passed to
6155      targetm.encode_section_info.  */
6156   /* ??? We don't have any type information except for this is
6157      a function.  Pretend this is "int foo()".  */
6158   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
6159                           build_function_type (integer_type_node, NULL_TREE));
6160   DECL_ARTIFICIAL (decl) = 1;
6161   DECL_EXTERNAL (decl) = 1;
6162   TREE_PUBLIC (decl) = 1;
6163
6164   symbol = XEXP (DECL_RTL (decl), 0);
6165
6166   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
6167      are the flags assigned by targetm.encode_section_info.  */
6168   SET_SYMBOL_REF_DECL (symbol, 0);
6169
6170   return symbol;
6171 }
6172
6173 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6174    MODE to NAME, which should be either 0 or a string constant.  */
6175 void
6176 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
6177 {
6178   rtx val;
6179   struct libfunc_entry e;
6180   struct libfunc_entry **slot;
6181   e.optab = (size_t) (optab_table[0] - optable);
6182   e.mode1 = mode;
6183   e.mode2 = VOIDmode;
6184
6185   if (name)
6186     val = init_one_libfunc (name);
6187   else
6188     val = 0;
6189   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6190   if (*slot == NULL)
6191     *slot = ggc_alloc (sizeof (struct libfunc_entry));
6192   (*slot)->optab = (size_t) (optab_table[0] - optable);
6193   (*slot)->mode1 = mode;
6194   (*slot)->mode2 = VOIDmode;
6195   (*slot)->libfunc = val;
6196 }
6197
6198 /* Call this to reset the function entry for one conversion optab
6199    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6200    either 0 or a string constant.  */
6201 void
6202 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
6203                   enum machine_mode fmode, const char *name)
6204 {
6205   rtx val;
6206   struct libfunc_entry e;
6207   struct libfunc_entry **slot;
6208   e.optab = (size_t) (convert_optab_table[0] - optable);
6209   e.mode1 = tmode;
6210   e.mode2 = fmode;
6211
6212   if (name)
6213     val = init_one_libfunc (name);
6214   else
6215     val = 0;
6216   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6217   if (*slot == NULL)
6218     *slot = ggc_alloc (sizeof (struct libfunc_entry));
6219   (*slot)->optab = (size_t) (convert_optab_table[0] - optable);
6220   (*slot)->mode1 = tmode;
6221   (*slot)->mode2 = fmode;
6222   (*slot)->libfunc = val;
6223 }
6224
6225 /* Call this to initialize the contents of the optabs
6226    appropriately for the current target machine.  */
6227
6228 void
6229 init_optabs (void)
6230 {
6231   unsigned int i;
6232   enum machine_mode int_mode;
6233
6234   libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
6235   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
6236
6237   for (i = 0; i < NUM_RTX_CODE; i++)
6238     setcc_gen_code[i] = CODE_FOR_nothing;
6239
6240 #ifdef HAVE_conditional_move
6241   for (i = 0; i < NUM_MACHINE_MODES; i++)
6242     movcc_gen_code[i] = CODE_FOR_nothing;
6243 #endif
6244
6245   for (i = 0; i < NUM_MACHINE_MODES; i++)
6246     {
6247       vcond_gen_code[i] = CODE_FOR_nothing;
6248       vcondu_gen_code[i] = CODE_FOR_nothing;
6249     }
6250
6251   add_optab = init_optab (PLUS);
6252   addv_optab = init_optabv (PLUS);
6253   sub_optab = init_optab (MINUS);
6254   subv_optab = init_optabv (MINUS);
6255   ssadd_optab = init_optab (SS_PLUS);
6256   usadd_optab = init_optab (US_PLUS);
6257   sssub_optab = init_optab (SS_MINUS);
6258   ussub_optab = init_optab (US_MINUS);
6259   smul_optab = init_optab (MULT);
6260   ssmul_optab = init_optab (SS_MULT);
6261   usmul_optab = init_optab (US_MULT);
6262   smulv_optab = init_optabv (MULT);
6263   smul_highpart_optab = init_optab (UNKNOWN);
6264   umul_highpart_optab = init_optab (UNKNOWN);
6265   smul_widen_optab = init_optab (UNKNOWN);
6266   umul_widen_optab = init_optab (UNKNOWN);
6267   usmul_widen_optab = init_optab (UNKNOWN);
6268   smadd_widen_optab = init_optab (UNKNOWN);
6269   umadd_widen_optab = init_optab (UNKNOWN);
6270   ssmadd_widen_optab = init_optab (UNKNOWN);
6271   usmadd_widen_optab = init_optab (UNKNOWN);
6272   smsub_widen_optab = init_optab (UNKNOWN);
6273   umsub_widen_optab = init_optab (UNKNOWN);
6274   ssmsub_widen_optab = init_optab (UNKNOWN);
6275   usmsub_widen_optab = init_optab (UNKNOWN);
6276   sdiv_optab = init_optab (DIV);
6277   ssdiv_optab = init_optab (SS_DIV);
6278   usdiv_optab = init_optab (US_DIV);
6279   sdivv_optab = init_optabv (DIV);
6280   sdivmod_optab = init_optab (UNKNOWN);
6281   udiv_optab = init_optab (UDIV);
6282   udivmod_optab = init_optab (UNKNOWN);
6283   smod_optab = init_optab (MOD);
6284   umod_optab = init_optab (UMOD);
6285   fmod_optab = init_optab (UNKNOWN);
6286   remainder_optab = init_optab (UNKNOWN);
6287   ftrunc_optab = init_optab (UNKNOWN);
6288   and_optab = init_optab (AND);
6289   ior_optab = init_optab (IOR);
6290   xor_optab = init_optab (XOR);
6291   ashl_optab = init_optab (ASHIFT);
6292   ssashl_optab = init_optab (SS_ASHIFT);
6293   usashl_optab = init_optab (US_ASHIFT);
6294   ashr_optab = init_optab (ASHIFTRT);
6295   lshr_optab = init_optab (LSHIFTRT);
6296   rotl_optab = init_optab (ROTATE);
6297   rotr_optab = init_optab (ROTATERT);
6298   smin_optab = init_optab (SMIN);
6299   smax_optab = init_optab (SMAX);
6300   umin_optab = init_optab (UMIN);
6301   umax_optab = init_optab (UMAX);
6302   pow_optab = init_optab (UNKNOWN);
6303   atan2_optab = init_optab (UNKNOWN);
6304
6305   /* These three have codes assigned exclusively for the sake of
6306      have_insn_for.  */
6307   mov_optab = init_optab (SET);
6308   movstrict_optab = init_optab (STRICT_LOW_PART);
6309   cmp_optab = init_optab (COMPARE);
6310
6311   storent_optab = init_optab (UNKNOWN);
6312
6313   ucmp_optab = init_optab (UNKNOWN);
6314   tst_optab = init_optab (UNKNOWN);
6315
6316   eq_optab = init_optab (EQ);
6317   ne_optab = init_optab (NE);
6318   gt_optab = init_optab (GT);
6319   ge_optab = init_optab (GE);
6320   lt_optab = init_optab (LT);
6321   le_optab = init_optab (LE);
6322   unord_optab = init_optab (UNORDERED);
6323
6324   neg_optab = init_optab (NEG);
6325   ssneg_optab = init_optab (SS_NEG);
6326   usneg_optab = init_optab (US_NEG);
6327   negv_optab = init_optabv (NEG);
6328   abs_optab = init_optab (ABS);
6329   absv_optab = init_optabv (ABS);
6330   addcc_optab = init_optab (UNKNOWN);
6331   one_cmpl_optab = init_optab (NOT);
6332   bswap_optab = init_optab (BSWAP);
6333   ffs_optab = init_optab (FFS);
6334   clz_optab = init_optab (CLZ);
6335   ctz_optab = init_optab (CTZ);
6336   popcount_optab = init_optab (POPCOUNT);
6337   parity_optab = init_optab (PARITY);
6338   sqrt_optab = init_optab (SQRT);
6339   floor_optab = init_optab (UNKNOWN);
6340   ceil_optab = init_optab (UNKNOWN);
6341   round_optab = init_optab (UNKNOWN);
6342   btrunc_optab = init_optab (UNKNOWN);
6343   nearbyint_optab = init_optab (UNKNOWN);
6344   rint_optab = init_optab (UNKNOWN);
6345   sincos_optab = init_optab (UNKNOWN);
6346   sin_optab = init_optab (UNKNOWN);
6347   asin_optab = init_optab (UNKNOWN);
6348   cos_optab = init_optab (UNKNOWN);
6349   acos_optab = init_optab (UNKNOWN);
6350   exp_optab = init_optab (UNKNOWN);
6351   exp10_optab = init_optab (UNKNOWN);
6352   exp2_optab = init_optab (UNKNOWN);
6353   expm1_optab = init_optab (UNKNOWN);
6354   ldexp_optab = init_optab (UNKNOWN);
6355   scalb_optab = init_optab (UNKNOWN);
6356   logb_optab = init_optab (UNKNOWN);
6357   ilogb_optab = init_optab (UNKNOWN);
6358   log_optab = init_optab (UNKNOWN);
6359   log10_optab = init_optab (UNKNOWN);
6360   log2_optab = init_optab (UNKNOWN);
6361   log1p_optab = init_optab (UNKNOWN);
6362   tan_optab = init_optab (UNKNOWN);
6363   atan_optab = init_optab (UNKNOWN);
6364   copysign_optab = init_optab (UNKNOWN);
6365   signbit_optab = init_optab (UNKNOWN);
6366
6367   isinf_optab = init_optab (UNKNOWN);
6368
6369   strlen_optab = init_optab (UNKNOWN);
6370   cbranch_optab = init_optab (UNKNOWN);
6371   cmov_optab = init_optab (UNKNOWN);
6372   cstore_optab = init_optab (UNKNOWN);
6373   push_optab = init_optab (UNKNOWN);
6374
6375   reduc_smax_optab = init_optab (UNKNOWN);
6376   reduc_umax_optab = init_optab (UNKNOWN);
6377   reduc_smin_optab = init_optab (UNKNOWN);
6378   reduc_umin_optab = init_optab (UNKNOWN);
6379   reduc_splus_optab = init_optab (UNKNOWN);
6380   reduc_uplus_optab = init_optab (UNKNOWN);
6381
6382   ssum_widen_optab = init_optab (UNKNOWN);
6383   usum_widen_optab = init_optab (UNKNOWN);
6384   sdot_prod_optab = init_optab (UNKNOWN); 
6385   udot_prod_optab = init_optab (UNKNOWN);
6386
6387   vec_extract_optab = init_optab (UNKNOWN);
6388   vec_extract_even_optab = init_optab (UNKNOWN);
6389   vec_extract_odd_optab = init_optab (UNKNOWN);
6390   vec_interleave_high_optab = init_optab (UNKNOWN);
6391   vec_interleave_low_optab = init_optab (UNKNOWN);
6392   vec_set_optab = init_optab (UNKNOWN);
6393   vec_init_optab = init_optab (UNKNOWN);
6394   vec_shl_optab = init_optab (UNKNOWN);
6395   vec_shr_optab = init_optab (UNKNOWN);
6396   vec_realign_load_optab = init_optab (UNKNOWN);
6397   movmisalign_optab = init_optab (UNKNOWN);
6398   vec_widen_umult_hi_optab = init_optab (UNKNOWN);
6399   vec_widen_umult_lo_optab = init_optab (UNKNOWN);
6400   vec_widen_smult_hi_optab = init_optab (UNKNOWN);
6401   vec_widen_smult_lo_optab = init_optab (UNKNOWN);
6402   vec_unpacks_hi_optab = init_optab (UNKNOWN);
6403   vec_unpacks_lo_optab = init_optab (UNKNOWN);
6404   vec_unpacku_hi_optab = init_optab (UNKNOWN);
6405   vec_unpacku_lo_optab = init_optab (UNKNOWN);
6406   vec_unpacks_float_hi_optab = init_optab (UNKNOWN);
6407   vec_unpacks_float_lo_optab = init_optab (UNKNOWN);
6408   vec_unpacku_float_hi_optab = init_optab (UNKNOWN);
6409   vec_unpacku_float_lo_optab = init_optab (UNKNOWN);
6410   vec_pack_trunc_optab = init_optab (UNKNOWN);
6411   vec_pack_usat_optab = init_optab (UNKNOWN);
6412   vec_pack_ssat_optab = init_optab (UNKNOWN);
6413   vec_pack_ufix_trunc_optab = init_optab (UNKNOWN);
6414   vec_pack_sfix_trunc_optab = init_optab (UNKNOWN);
6415
6416   powi_optab = init_optab (UNKNOWN);
6417
6418   /* Conversions.  */
6419   sext_optab = init_convert_optab (SIGN_EXTEND);
6420   zext_optab = init_convert_optab (ZERO_EXTEND);
6421   trunc_optab = init_convert_optab (TRUNCATE);
6422   sfix_optab = init_convert_optab (FIX);
6423   ufix_optab = init_convert_optab (UNSIGNED_FIX);
6424   sfixtrunc_optab = init_convert_optab (UNKNOWN);
6425   ufixtrunc_optab = init_convert_optab (UNKNOWN);
6426   sfloat_optab = init_convert_optab (FLOAT);
6427   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
6428   lrint_optab = init_convert_optab (UNKNOWN);
6429   lround_optab = init_convert_optab (UNKNOWN);
6430   lfloor_optab = init_convert_optab (UNKNOWN);
6431   lceil_optab = init_convert_optab (UNKNOWN);
6432
6433   fract_optab = init_convert_optab (FRACT_CONVERT);
6434   fractuns_optab = init_convert_optab (UNSIGNED_FRACT_CONVERT);
6435   satfract_optab = init_convert_optab (SAT_FRACT);
6436   satfractuns_optab = init_convert_optab (UNSIGNED_SAT_FRACT);
6437
6438   for (i = 0; i < NUM_MACHINE_MODES; i++)
6439     {
6440       movmem_optab[i] = CODE_FOR_nothing;
6441       cmpstr_optab[i] = CODE_FOR_nothing;
6442       cmpstrn_optab[i] = CODE_FOR_nothing;
6443       cmpmem_optab[i] = CODE_FOR_nothing;
6444       setmem_optab[i] = CODE_FOR_nothing;
6445
6446       sync_add_optab[i] = CODE_FOR_nothing;
6447       sync_sub_optab[i] = CODE_FOR_nothing;
6448       sync_ior_optab[i] = CODE_FOR_nothing;
6449       sync_and_optab[i] = CODE_FOR_nothing;
6450       sync_xor_optab[i] = CODE_FOR_nothing;
6451       sync_nand_optab[i] = CODE_FOR_nothing;
6452       sync_old_add_optab[i] = CODE_FOR_nothing;
6453       sync_old_sub_optab[i] = CODE_FOR_nothing;
6454       sync_old_ior_optab[i] = CODE_FOR_nothing;
6455       sync_old_and_optab[i] = CODE_FOR_nothing;
6456       sync_old_xor_optab[i] = CODE_FOR_nothing;
6457       sync_old_nand_optab[i] = CODE_FOR_nothing;
6458       sync_new_add_optab[i] = CODE_FOR_nothing;
6459       sync_new_sub_optab[i] = CODE_FOR_nothing;
6460       sync_new_ior_optab[i] = CODE_FOR_nothing;
6461       sync_new_and_optab[i] = CODE_FOR_nothing;
6462       sync_new_xor_optab[i] = CODE_FOR_nothing;
6463       sync_new_nand_optab[i] = CODE_FOR_nothing;
6464       sync_compare_and_swap[i] = CODE_FOR_nothing;
6465       sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
6466       sync_lock_test_and_set[i] = CODE_FOR_nothing;
6467       sync_lock_release[i] = CODE_FOR_nothing;
6468
6469       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
6470     }
6471
6472   /* Fill in the optabs with the insns we support.  */
6473   init_all_optabs ();
6474
6475   /* Initialize the optabs with the names of the library functions.  */
6476   add_optab->libcall_basename = "add";
6477   add_optab->libcall_suffix = '3';
6478   add_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6479   addv_optab->libcall_basename = "add";
6480   addv_optab->libcall_suffix = '3';
6481   addv_optab->libcall_gen = gen_intv_fp_libfunc;
6482   ssadd_optab->libcall_basename = "ssadd";
6483   ssadd_optab->libcall_suffix = '3';
6484   ssadd_optab->libcall_gen = gen_signed_fixed_libfunc;
6485   usadd_optab->libcall_basename = "usadd";
6486   usadd_optab->libcall_suffix = '3';
6487   usadd_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6488   sub_optab->libcall_basename = "sub";
6489   sub_optab->libcall_suffix = '3';
6490   sub_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6491   subv_optab->libcall_basename = "sub";
6492   subv_optab->libcall_suffix = '3';
6493   subv_optab->libcall_gen = gen_intv_fp_libfunc;
6494   sssub_optab->libcall_basename = "sssub";
6495   sssub_optab->libcall_suffix = '3';
6496   sssub_optab->libcall_gen = gen_signed_fixed_libfunc;
6497   ussub_optab->libcall_basename = "ussub";
6498   ussub_optab->libcall_suffix = '3';
6499   ussub_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6500   smul_optab->libcall_basename = "mul";
6501   smul_optab->libcall_suffix = '3';
6502   smul_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6503   smulv_optab->libcall_basename = "mul";
6504   smulv_optab->libcall_suffix = '3';
6505   smulv_optab->libcall_gen = gen_intv_fp_libfunc;
6506   ssmul_optab->libcall_basename = "ssmul";
6507   ssmul_optab->libcall_suffix = '3';
6508   ssmul_optab->libcall_gen = gen_signed_fixed_libfunc;
6509   usmul_optab->libcall_basename = "usmul";
6510   usmul_optab->libcall_suffix = '3';
6511   usmul_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6512   sdiv_optab->libcall_basename = "div";
6513   sdiv_optab->libcall_suffix = '3';
6514   sdiv_optab->libcall_gen = gen_int_fp_signed_fixed_libfunc;
6515   sdivv_optab->libcall_basename = "divv";
6516   sdivv_optab->libcall_suffix = '3';
6517   sdivv_optab->libcall_gen = gen_int_libfunc;
6518   ssdiv_optab->libcall_basename = "ssdiv";
6519   ssdiv_optab->libcall_suffix = '3';
6520   ssdiv_optab->libcall_gen = gen_signed_fixed_libfunc;
6521   udiv_optab->libcall_basename = "udiv";
6522   udiv_optab->libcall_suffix = '3';
6523   udiv_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6524   usdiv_optab->libcall_basename = "usdiv";
6525   usdiv_optab->libcall_suffix = '3';
6526   usdiv_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6527   sdivmod_optab->libcall_basename = "divmod";
6528   sdivmod_optab->libcall_suffix = '4';
6529   sdivmod_optab->libcall_gen = gen_int_libfunc;
6530   udivmod_optab->libcall_basename = "udivmod";
6531   udivmod_optab->libcall_suffix = '4';
6532   udivmod_optab->libcall_gen = gen_int_libfunc;
6533   smod_optab->libcall_basename = "mod";
6534   smod_optab->libcall_suffix = '3';
6535   smod_optab->libcall_gen = gen_int_libfunc;
6536   umod_optab->libcall_basename = "umod";
6537   umod_optab->libcall_suffix = '3';
6538   umod_optab->libcall_gen = gen_int_libfunc;
6539   ftrunc_optab->libcall_basename = "ftrunc";
6540   ftrunc_optab->libcall_suffix = '2';
6541   ftrunc_optab->libcall_gen = gen_fp_libfunc;
6542   and_optab->libcall_basename = "and";
6543   and_optab->libcall_suffix = '3';
6544   and_optab->libcall_gen = gen_int_libfunc;
6545   ior_optab->libcall_basename = "ior";
6546   ior_optab->libcall_suffix = '3';
6547   ior_optab->libcall_gen = gen_int_libfunc;
6548   xor_optab->libcall_basename = "xor";
6549   xor_optab->libcall_suffix = '3';
6550   xor_optab->libcall_gen = gen_int_libfunc;
6551   ashl_optab->libcall_basename = "ashl";
6552   ashl_optab->libcall_suffix = '3';
6553   ashl_optab->libcall_gen = gen_int_fixed_libfunc;
6554   ssashl_optab->libcall_basename = "ssashl";
6555   ssashl_optab->libcall_suffix = '3';
6556   ssashl_optab->libcall_gen = gen_signed_fixed_libfunc;
6557   usashl_optab->libcall_basename = "usashl";
6558   usashl_optab->libcall_suffix = '3';
6559   usashl_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6560   ashr_optab->libcall_basename = "ashr";
6561   ashr_optab->libcall_suffix = '3';
6562   ashr_optab->libcall_gen = gen_int_signed_fixed_libfunc;
6563   lshr_optab->libcall_basename = "lshr";
6564   lshr_optab->libcall_suffix = '3';
6565   lshr_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6566   smin_optab->libcall_basename = "min";
6567   smin_optab->libcall_suffix = '3';
6568   smin_optab->libcall_gen = gen_int_fp_libfunc;
6569   smax_optab->libcall_basename = "max";
6570   smax_optab->libcall_suffix = '3';
6571   smax_optab->libcall_gen = gen_int_fp_libfunc;
6572   umin_optab->libcall_basename = "umin";
6573   umin_optab->libcall_suffix = '3';
6574   umin_optab->libcall_gen = gen_int_libfunc;
6575   umax_optab->libcall_basename = "umax";
6576   umax_optab->libcall_suffix = '3';
6577   umax_optab->libcall_gen = gen_int_libfunc;
6578   neg_optab->libcall_basename = "neg";
6579   neg_optab->libcall_suffix = '2';
6580   neg_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6581   ssneg_optab->libcall_basename = "ssneg";
6582   ssneg_optab->libcall_suffix = '2';
6583   ssneg_optab->libcall_gen = gen_signed_fixed_libfunc;
6584   usneg_optab->libcall_basename = "usneg";
6585   usneg_optab->libcall_suffix = '2';
6586   usneg_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6587   negv_optab->libcall_basename = "neg";
6588   negv_optab->libcall_suffix = '2';
6589   negv_optab->libcall_gen = gen_intv_fp_libfunc;
6590   one_cmpl_optab->libcall_basename = "one_cmpl";
6591   one_cmpl_optab->libcall_suffix = '2';
6592   one_cmpl_optab->libcall_gen = gen_int_libfunc;
6593   ffs_optab->libcall_basename = "ffs";
6594   ffs_optab->libcall_suffix = '2';
6595   ffs_optab->libcall_gen = gen_int_libfunc;
6596   clz_optab->libcall_basename = "clz";
6597   clz_optab->libcall_suffix = '2';
6598   clz_optab->libcall_gen = gen_int_libfunc;
6599   ctz_optab->libcall_basename = "ctz";
6600   ctz_optab->libcall_suffix = '2';
6601   ctz_optab->libcall_gen = gen_int_libfunc;
6602   popcount_optab->libcall_basename = "popcount";
6603   popcount_optab->libcall_suffix = '2';
6604   popcount_optab->libcall_gen = gen_int_libfunc;
6605   parity_optab->libcall_basename = "parity";
6606   parity_optab->libcall_suffix = '2';
6607   parity_optab->libcall_gen = gen_int_libfunc;
6608
6609   /* Comparison libcalls for integers MUST come in pairs,
6610      signed/unsigned.  */
6611   cmp_optab->libcall_basename = "cmp";
6612   cmp_optab->libcall_suffix = '2';
6613   cmp_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6614   ucmp_optab->libcall_basename = "ucmp";
6615   ucmp_optab->libcall_suffix = '2';
6616   ucmp_optab->libcall_gen = gen_int_libfunc;
6617
6618   /* EQ etc are floating point only.  */
6619   eq_optab->libcall_basename = "eq";
6620   eq_optab->libcall_suffix = '2';
6621   eq_optab->libcall_gen = gen_fp_libfunc;
6622   ne_optab->libcall_basename = "ne";
6623   ne_optab->libcall_suffix = '2';
6624   ne_optab->libcall_gen = gen_fp_libfunc;
6625   gt_optab->libcall_basename = "gt";
6626   gt_optab->libcall_suffix = '2';
6627   gt_optab->libcall_gen = gen_fp_libfunc;
6628   ge_optab->libcall_basename = "ge";
6629   ge_optab->libcall_suffix = '2';
6630   ge_optab->libcall_gen = gen_fp_libfunc;
6631   lt_optab->libcall_basename = "lt";
6632   lt_optab->libcall_suffix = '2';
6633   lt_optab->libcall_gen = gen_fp_libfunc;
6634   le_optab->libcall_basename = "le";
6635   le_optab->libcall_suffix = '2';
6636   le_optab->libcall_gen = gen_fp_libfunc;
6637   unord_optab->libcall_basename = "unord";
6638   unord_optab->libcall_suffix = '2';
6639   unord_optab->libcall_gen = gen_fp_libfunc;
6640
6641   powi_optab->libcall_basename = "powi";
6642   powi_optab->libcall_suffix = '2';
6643   powi_optab->libcall_gen = gen_fp_libfunc;
6644
6645   /* Conversions.  */
6646   sfloat_optab->libcall_basename = "float";
6647   sfloat_optab->libcall_gen = gen_int_to_fp_conv_libfunc;
6648   ufloat_optab->libcall_gen = gen_ufloat_conv_libfunc;
6649   sfix_optab->libcall_basename = "fix";
6650   sfix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6651   ufix_optab->libcall_basename = "fixuns";
6652   ufix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6653   lrint_optab->libcall_basename = "lrint";
6654   lrint_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6655   lround_optab->libcall_basename = "lround";
6656   lround_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6657   lfloor_optab->libcall_basename = "lfloor";
6658   lfloor_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6659   lceil_optab->libcall_basename = "lceil";
6660   lceil_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6661
6662   /* trunc_optab is also used for FLOAT_EXTEND.  */
6663   sext_optab->libcall_basename = "extend";
6664   sext_optab->libcall_gen = gen_extend_conv_libfunc;
6665   trunc_optab->libcall_basename = "trunc";
6666   trunc_optab->libcall_gen = gen_trunc_conv_libfunc;
6667
6668   /* Conversions for fixed-point modes and other modes.  */
6669   fract_optab->libcall_basename = "fract";
6670   fract_optab->libcall_gen = gen_fract_conv_libfunc;
6671   satfract_optab->libcall_basename = "satfract";
6672   satfract_optab->libcall_gen = gen_satfract_conv_libfunc;
6673   fractuns_optab->libcall_basename = "fractuns";
6674   fractuns_optab->libcall_gen = gen_fractuns_conv_libfunc;
6675   satfractuns_optab->libcall_basename = "satfractuns";
6676   satfractuns_optab->libcall_gen = gen_satfractuns_conv_libfunc;
6677
6678   /* The ffs function operates on `int'.  Fall back on it if we do not
6679      have a libgcc2 function for that width.  */
6680   if (INT_TYPE_SIZE < BITS_PER_WORD)
6681     {
6682       int_mode = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
6683       set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6684                          "ffs");
6685     }
6686
6687   /* Explicitly initialize the bswap libfuncs since we need them to be
6688      valid for things other than word_mode.  */
6689   set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6690   set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6691
6692   /* Use cabs for double complex abs, since systems generally have cabs.
6693      Don't define any libcall for float complex, so that cabs will be used.  */
6694   if (complex_double_type_node)
6695     set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), "cabs");
6696
6697   abort_libfunc = init_one_libfunc ("abort");
6698   memcpy_libfunc = init_one_libfunc ("memcpy");
6699   memmove_libfunc = init_one_libfunc ("memmove");
6700   memcmp_libfunc = init_one_libfunc ("memcmp");
6701   memset_libfunc = init_one_libfunc ("memset");
6702   setbits_libfunc = init_one_libfunc ("__setbits");
6703
6704 #ifndef DONT_USE_BUILTIN_SETJMP
6705   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6706   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6707 #else
6708   setjmp_libfunc = init_one_libfunc ("setjmp");
6709   longjmp_libfunc = init_one_libfunc ("longjmp");
6710 #endif
6711   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6712   unwind_sjlj_unregister_libfunc
6713     = init_one_libfunc ("_Unwind_SjLj_Unregister");
6714
6715   /* For function entry/exit instrumentation.  */
6716   profile_function_entry_libfunc
6717     = init_one_libfunc ("__cyg_profile_func_enter");
6718   profile_function_exit_libfunc
6719     = init_one_libfunc ("__cyg_profile_func_exit");
6720
6721   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6722
6723   if (HAVE_conditional_trap)
6724     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
6725
6726   /* Allow the target to add more libcalls or rename some, etc.  */
6727   targetm.init_libfuncs ();
6728 }
6729
6730 /* Print information about the current contents of the optabs on
6731    STDERR.  */
6732
6733 void
6734 debug_optab_libfuncs (void)
6735 {
6736   int i;
6737   int j;
6738   int k;
6739
6740   /* Dump the arithmetic optabs.  */
6741   for (i = 0; i != (int) OTI_MAX; i++)
6742     for (j = 0; j < NUM_MACHINE_MODES; ++j)
6743       {
6744         optab o;
6745         rtx l;
6746
6747         o = optab_table[i];
6748         l = optab_libfunc (optab_table[i], j);
6749         if (l)
6750           {
6751             gcc_assert (GET_CODE (l) == SYMBOL_REF);
6752             fprintf (stderr, "%s\t%s:\t%s\n",
6753                      GET_RTX_NAME (o->code),
6754                      GET_MODE_NAME (j),
6755                      XSTR (l, 0));
6756           }
6757       }
6758
6759   /* Dump the conversion optabs.  */
6760   for (i = 0; i < (int) COI_MAX; ++i)
6761     for (j = 0; j < NUM_MACHINE_MODES; ++j)
6762       for (k = 0; k < NUM_MACHINE_MODES; ++k)
6763         {
6764           convert_optab o;
6765           rtx l;
6766
6767           o = convert_optab_table[i];
6768           l = convert_optab_libfunc (o, j, k);
6769           if (l)
6770             {
6771               gcc_assert (GET_CODE (l) == SYMBOL_REF);
6772               fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6773                        GET_RTX_NAME (o->code),
6774                        GET_MODE_NAME (j),
6775                        GET_MODE_NAME (k),
6776                        XSTR (l, 0));
6777             }
6778         }
6779 }
6780
6781 \f
6782 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6783    CODE.  Return 0 on failure.  */
6784
6785 rtx
6786 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
6787                rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
6788 {
6789   enum machine_mode mode = GET_MODE (op1);
6790   enum insn_code icode;
6791   rtx insn;
6792
6793   if (!HAVE_conditional_trap)
6794     return 0;
6795
6796   if (mode == VOIDmode)
6797     return 0;
6798
6799   icode = optab_handler (cmp_optab, mode)->insn_code;
6800   if (icode == CODE_FOR_nothing)
6801     return 0;
6802
6803   start_sequence ();
6804   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
6805   op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
6806   if (!op1 || !op2)
6807     {
6808       end_sequence ();
6809       return 0;
6810     }
6811   emit_insn (GEN_FCN (icode) (op1, op2));
6812
6813   PUT_CODE (trap_rtx, code);
6814   gcc_assert (HAVE_conditional_trap);
6815   insn = gen_conditional_trap (trap_rtx, tcode);
6816   if (insn)
6817     {
6818       emit_insn (insn);
6819       insn = get_insns ();
6820     }
6821   end_sequence ();
6822
6823   return insn;
6824 }
6825
6826 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6827    or unsigned operation code.  */
6828
6829 static enum rtx_code
6830 get_rtx_code (enum tree_code tcode, bool unsignedp)
6831 {
6832   enum rtx_code code;
6833   switch (tcode)
6834     {
6835     case EQ_EXPR:
6836       code = EQ;
6837       break;
6838     case NE_EXPR:
6839       code = NE;
6840       break;
6841     case LT_EXPR:
6842       code = unsignedp ? LTU : LT;
6843       break;
6844     case LE_EXPR:
6845       code = unsignedp ? LEU : LE;
6846       break;
6847     case GT_EXPR:
6848       code = unsignedp ? GTU : GT;
6849       break;
6850     case GE_EXPR:
6851       code = unsignedp ? GEU : GE;
6852       break;
6853
6854     case UNORDERED_EXPR:
6855       code = UNORDERED;
6856       break;
6857     case ORDERED_EXPR:
6858       code = ORDERED;
6859       break;
6860     case UNLT_EXPR:
6861       code = UNLT;
6862       break;
6863     case UNLE_EXPR:
6864       code = UNLE;
6865       break;
6866     case UNGT_EXPR:
6867       code = UNGT;
6868       break;
6869     case UNGE_EXPR:
6870       code = UNGE;
6871       break;
6872     case UNEQ_EXPR:
6873       code = UNEQ;
6874       break;
6875     case LTGT_EXPR:
6876       code = LTGT;
6877       break;
6878
6879     default:
6880       gcc_unreachable ();
6881     }
6882   return code;
6883 }
6884
6885 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6886    unsigned operators. Do not generate compare instruction.  */
6887
6888 static rtx
6889 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6890 {
6891   enum rtx_code rcode;
6892   tree t_op0, t_op1;
6893   rtx rtx_op0, rtx_op1;
6894
6895   /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6896      ensures that condition is a relational operation.  */
6897   gcc_assert (COMPARISON_CLASS_P (cond));
6898
6899   rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6900   t_op0 = TREE_OPERAND (cond, 0);
6901   t_op1 = TREE_OPERAND (cond, 1);
6902
6903   /* Expand operands.  */
6904   rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6905                          EXPAND_STACK_PARM);
6906   rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6907                          EXPAND_STACK_PARM);
6908
6909   if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
6910       && GET_MODE (rtx_op0) != VOIDmode)
6911     rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
6912
6913   if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
6914       && GET_MODE (rtx_op1) != VOIDmode)
6915     rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
6916
6917   return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
6918 }
6919
6920 /* Return insn code for VEC_COND_EXPR EXPR.  */
6921
6922 static inline enum insn_code
6923 get_vcond_icode (tree expr, enum machine_mode mode)
6924 {
6925   enum insn_code icode = CODE_FOR_nothing;
6926
6927   if (TYPE_UNSIGNED (TREE_TYPE (expr)))
6928     icode = vcondu_gen_code[mode];
6929   else
6930     icode = vcond_gen_code[mode];
6931   return icode;
6932 }
6933
6934 /* Return TRUE iff, appropriate vector insns are available
6935    for vector cond expr expr in VMODE mode.  */
6936
6937 bool
6938 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
6939 {
6940   if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
6941     return false;
6942   return true;
6943 }
6944
6945 /* Generate insns for VEC_COND_EXPR.  */
6946
6947 rtx
6948 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
6949 {
6950   enum insn_code icode;
6951   rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
6952   enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
6953   bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
6954
6955   icode = get_vcond_icode (vec_cond_expr, mode);
6956   if (icode == CODE_FOR_nothing)
6957     return 0;
6958
6959   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6960     target = gen_reg_rtx (mode);
6961
6962   /* Get comparison rtx.  First expand both cond expr operands.  */
6963   comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
6964                                    unsignedp, icode);
6965   cc_op0 = XEXP (comparison, 0);
6966   cc_op1 = XEXP (comparison, 1);
6967   /* Expand both operands and force them in reg, if required.  */
6968   rtx_op1 = expand_normal (TREE_OPERAND (vec_cond_expr, 1));
6969   if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
6970       && mode != VOIDmode)
6971     rtx_op1 = force_reg (mode, rtx_op1);
6972
6973   rtx_op2 = expand_normal (TREE_OPERAND (vec_cond_expr, 2));
6974   if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
6975       && mode != VOIDmode)
6976     rtx_op2 = force_reg (mode, rtx_op2);
6977
6978   /* Emit instruction! */
6979   emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
6980                               comparison, cc_op0,  cc_op1));
6981
6982   return target;
6983 }
6984
6985 \f
6986 /* This is an internal subroutine of the other compare_and_swap expanders.
6987    MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6988    operation.  TARGET is an optional place to store the value result of
6989    the operation.  ICODE is the particular instruction to expand.  Return
6990    the result of the operation.  */
6991
6992 static rtx
6993 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6994                                rtx target, enum insn_code icode)
6995 {
6996   enum machine_mode mode = GET_MODE (mem);
6997   rtx insn;
6998
6999   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7000     target = gen_reg_rtx (mode);
7001
7002   if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
7003     old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
7004   if (!insn_data[icode].operand[2].predicate (old_val, mode))
7005     old_val = force_reg (mode, old_val);
7006
7007   if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
7008     new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
7009   if (!insn_data[icode].operand[3].predicate (new_val, mode))
7010     new_val = force_reg (mode, new_val);
7011
7012   insn = GEN_FCN (icode) (target, mem, old_val, new_val);
7013   if (insn == NULL_RTX)
7014     return NULL_RTX;
7015   emit_insn (insn);
7016
7017   return target;
7018 }
7019
7020 /* Expand a compare-and-swap operation and return its value.  */
7021
7022 rtx
7023 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
7024 {
7025   enum machine_mode mode = GET_MODE (mem);
7026   enum insn_code icode = sync_compare_and_swap[mode];
7027
7028   if (icode == CODE_FOR_nothing)
7029     return NULL_RTX;
7030
7031   return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
7032 }
7033
7034 /* Expand a compare-and-swap operation and store true into the result if
7035    the operation was successful and false otherwise.  Return the result.
7036    Unlike other routines, TARGET is not optional.  */
7037
7038 rtx
7039 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
7040 {
7041   enum machine_mode mode = GET_MODE (mem);
7042   enum insn_code icode;
7043   rtx subtarget, label0, label1;
7044
7045   /* If the target supports a compare-and-swap pattern that simultaneously
7046      sets some flag for success, then use it.  Otherwise use the regular
7047      compare-and-swap and follow that immediately with a compare insn.  */
7048   icode = sync_compare_and_swap_cc[mode];
7049   switch (icode)
7050     {
7051     default:
7052       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
7053                                                  NULL_RTX, icode);
7054       if (subtarget != NULL_RTX)
7055         break;
7056
7057       /* FALLTHRU */
7058     case CODE_FOR_nothing:
7059       icode = sync_compare_and_swap[mode];
7060       if (icode == CODE_FOR_nothing)
7061         return NULL_RTX;
7062
7063       /* Ensure that if old_val == mem, that we're not comparing
7064          against an old value.  */
7065       if (MEM_P (old_val))
7066         old_val = force_reg (mode, old_val);
7067
7068       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
7069                                                  NULL_RTX, icode);
7070       if (subtarget == NULL_RTX)
7071         return NULL_RTX;
7072
7073       emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
7074     }
7075
7076   /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
7077      setcc instruction from the beginning.  We don't work too hard here,
7078      but it's nice to not be stupid about initial code gen either.  */
7079   if (STORE_FLAG_VALUE == 1)
7080     {
7081       icode = setcc_gen_code[EQ];
7082       if (icode != CODE_FOR_nothing)
7083         {
7084           enum machine_mode cmode = insn_data[icode].operand[0].mode;
7085           rtx insn;
7086
7087           subtarget = target;
7088           if (!insn_data[icode].operand[0].predicate (target, cmode))
7089             subtarget = gen_reg_rtx (cmode);
7090
7091           insn = GEN_FCN (icode) (subtarget);
7092           if (insn)
7093             {
7094               emit_insn (insn);
7095               if (GET_MODE (target) != GET_MODE (subtarget))
7096                 {
7097                   convert_move (target, subtarget, 1);
7098                   subtarget = target;
7099                 }
7100               return subtarget;
7101             }
7102         }
7103     }
7104
7105   /* Without an appropriate setcc instruction, use a set of branches to
7106      get 1 and 0 stored into target.  Presumably if the target has a
7107      STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt.  */
7108
7109   label0 = gen_label_rtx ();
7110   label1 = gen_label_rtx ();
7111
7112   emit_jump_insn (bcc_gen_fctn[EQ] (label0));
7113   emit_move_insn (target, const0_rtx);
7114   emit_jump_insn (gen_jump (label1));
7115   emit_barrier ();
7116   emit_label (label0);
7117   emit_move_insn (target, const1_rtx);
7118   emit_label (label1);
7119
7120   return target;
7121 }
7122
7123 /* This is a helper function for the other atomic operations.  This function
7124    emits a loop that contains SEQ that iterates until a compare-and-swap
7125    operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
7126    a set of instructions that takes a value from OLD_REG as an input and
7127    produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
7128    set to the current contents of MEM.  After SEQ, a compare-and-swap will
7129    attempt to update MEM with NEW_REG.  The function returns true when the
7130    loop was generated successfully.  */
7131
7132 static bool
7133 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
7134 {
7135   enum machine_mode mode = GET_MODE (mem);
7136   enum insn_code icode;
7137   rtx label, cmp_reg, subtarget;
7138
7139   /* The loop we want to generate looks like
7140
7141         cmp_reg = mem;
7142       label:
7143         old_reg = cmp_reg;
7144         seq;
7145         cmp_reg = compare-and-swap(mem, old_reg, new_reg)
7146         if (cmp_reg != old_reg)
7147           goto label;
7148
7149      Note that we only do the plain load from memory once.  Subsequent
7150      iterations use the value loaded by the compare-and-swap pattern.  */
7151
7152   label = gen_label_rtx ();
7153   cmp_reg = gen_reg_rtx (mode);
7154
7155   emit_move_insn (cmp_reg, mem);
7156   emit_label (label);
7157   emit_move_insn (old_reg, cmp_reg);
7158   if (seq)
7159     emit_insn (seq);
7160
7161   /* If the target supports a compare-and-swap pattern that simultaneously
7162      sets some flag for success, then use it.  Otherwise use the regular
7163      compare-and-swap and follow that immediately with a compare insn.  */
7164   icode = sync_compare_and_swap_cc[mode];
7165   switch (icode)
7166     {
7167     default:
7168       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
7169                                                  cmp_reg, icode);
7170       if (subtarget != NULL_RTX)
7171         {
7172           gcc_assert (subtarget == cmp_reg);
7173           break;
7174         }
7175
7176       /* FALLTHRU */
7177     case CODE_FOR_nothing:
7178       icode = sync_compare_and_swap[mode];
7179       if (icode == CODE_FOR_nothing)
7180         return false;
7181
7182       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
7183                                                  cmp_reg, icode);
7184       if (subtarget == NULL_RTX)
7185         return false;
7186       if (subtarget != cmp_reg)
7187         emit_move_insn (cmp_reg, subtarget);
7188
7189       emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
7190     }
7191
7192   /* ??? Mark this jump predicted not taken?  */
7193   emit_jump_insn (bcc_gen_fctn[NE] (label));
7194
7195   return true;
7196 }
7197
7198 /* This function generates the atomic operation MEM CODE= VAL.  In this
7199    case, we do not care about any resulting value.  Returns NULL if we
7200    cannot generate the operation.  */
7201
7202 rtx
7203 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
7204 {
7205   enum machine_mode mode = GET_MODE (mem);
7206   enum insn_code icode;
7207   rtx insn;
7208
7209   /* Look to see if the target supports the operation directly.  */
7210   switch (code)
7211     {
7212     case PLUS:
7213       icode = sync_add_optab[mode];
7214       break;
7215     case IOR:
7216       icode = sync_ior_optab[mode];
7217       break;
7218     case XOR:
7219       icode = sync_xor_optab[mode];
7220       break;
7221     case AND:
7222       icode = sync_and_optab[mode];
7223       break;
7224     case NOT:
7225       icode = sync_nand_optab[mode];
7226       break;
7227
7228     case MINUS:
7229       icode = sync_sub_optab[mode];
7230       if (icode == CODE_FOR_nothing || CONST_INT_P (val))
7231         {
7232           icode = sync_add_optab[mode];
7233           if (icode != CODE_FOR_nothing)
7234             {
7235               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7236               code = PLUS;
7237             }
7238         }
7239       break;
7240
7241     default:
7242       gcc_unreachable ();
7243     }
7244
7245   /* Generate the direct operation, if present.  */
7246   if (icode != CODE_FOR_nothing)
7247     {
7248       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7249         val = convert_modes (mode, GET_MODE (val), val, 1);
7250       if (!insn_data[icode].operand[1].predicate (val, mode))
7251         val = force_reg (mode, val);
7252
7253       insn = GEN_FCN (icode) (mem, val);
7254       if (insn)
7255         {
7256           emit_insn (insn);
7257           return const0_rtx;
7258         }
7259     }
7260
7261   /* Failing that, generate a compare-and-swap loop in which we perform the
7262      operation with normal arithmetic instructions.  */
7263   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7264     {
7265       rtx t0 = gen_reg_rtx (mode), t1;
7266
7267       start_sequence ();
7268
7269       t1 = t0;
7270       if (code == NOT)
7271         {
7272           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
7273           code = AND;
7274         }
7275       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7276                                 true, OPTAB_LIB_WIDEN);
7277
7278       insn = get_insns ();
7279       end_sequence ();
7280
7281       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7282         return const0_rtx;
7283     }
7284
7285   return NULL_RTX;
7286 }
7287
7288 /* This function generates the atomic operation MEM CODE= VAL.  In this
7289    case, we do care about the resulting value: if AFTER is true then
7290    return the value MEM holds after the operation, if AFTER is false
7291    then return the value MEM holds before the operation.  TARGET is an
7292    optional place for the result value to be stored.  */
7293
7294 rtx
7295 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
7296                              bool after, rtx target)
7297 {
7298   enum machine_mode mode = GET_MODE (mem);
7299   enum insn_code old_code, new_code, icode;
7300   bool compensate;
7301   rtx insn;
7302
7303   /* Look to see if the target supports the operation directly.  */
7304   switch (code)
7305     {
7306     case PLUS:
7307       old_code = sync_old_add_optab[mode];
7308       new_code = sync_new_add_optab[mode];
7309       break;
7310     case IOR:
7311       old_code = sync_old_ior_optab[mode];
7312       new_code = sync_new_ior_optab[mode];
7313       break;
7314     case XOR:
7315       old_code = sync_old_xor_optab[mode];
7316       new_code = sync_new_xor_optab[mode];
7317       break;
7318     case AND:
7319       old_code = sync_old_and_optab[mode];
7320       new_code = sync_new_and_optab[mode];
7321       break;
7322     case NOT:
7323       old_code = sync_old_nand_optab[mode];
7324       new_code = sync_new_nand_optab[mode];
7325       break;
7326
7327     case MINUS:
7328       old_code = sync_old_sub_optab[mode];
7329       new_code = sync_new_sub_optab[mode];
7330       if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
7331           || CONST_INT_P (val))
7332         {
7333           old_code = sync_old_add_optab[mode];
7334           new_code = sync_new_add_optab[mode];
7335           if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
7336             {
7337               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7338               code = PLUS;
7339             }
7340         }
7341       break;
7342
7343     default:
7344       gcc_unreachable ();
7345     }
7346
7347   /* If the target does supports the proper new/old operation, great.  But
7348      if we only support the opposite old/new operation, check to see if we
7349      can compensate.  In the case in which the old value is supported, then
7350      we can always perform the operation again with normal arithmetic.  In
7351      the case in which the new value is supported, then we can only handle
7352      this in the case the operation is reversible.  */
7353   compensate = false;
7354   if (after)
7355     {
7356       icode = new_code;
7357       if (icode == CODE_FOR_nothing)
7358         {
7359           icode = old_code;
7360           if (icode != CODE_FOR_nothing)
7361             compensate = true;
7362         }
7363     }
7364   else
7365     {
7366       icode = old_code;
7367       if (icode == CODE_FOR_nothing
7368           && (code == PLUS || code == MINUS || code == XOR))
7369         {
7370           icode = new_code;
7371           if (icode != CODE_FOR_nothing)
7372             compensate = true;
7373         }
7374     }
7375
7376   /* If we found something supported, great.  */
7377   if (icode != CODE_FOR_nothing)
7378     {
7379       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7380         target = gen_reg_rtx (mode);
7381
7382       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7383         val = convert_modes (mode, GET_MODE (val), val, 1);
7384       if (!insn_data[icode].operand[2].predicate (val, mode))
7385         val = force_reg (mode, val);
7386
7387       insn = GEN_FCN (icode) (target, mem, val);
7388       if (insn)
7389         {
7390           emit_insn (insn);
7391
7392           /* If we need to compensate for using an operation with the
7393              wrong return value, do so now.  */
7394           if (compensate)
7395             {
7396               if (!after)
7397                 {
7398                   if (code == PLUS)
7399                     code = MINUS;
7400                   else if (code == MINUS)
7401                     code = PLUS;
7402                 }
7403
7404               if (code == NOT)
7405                 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
7406               target = expand_simple_binop (mode, code, target, val, NULL_RTX,
7407                                             true, OPTAB_LIB_WIDEN);
7408             }
7409
7410           return target;
7411         }
7412     }
7413
7414   /* Failing that, generate a compare-and-swap loop in which we perform the
7415      operation with normal arithmetic instructions.  */
7416   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7417     {
7418       rtx t0 = gen_reg_rtx (mode), t1;
7419
7420       if (!target || !register_operand (target, mode))
7421         target = gen_reg_rtx (mode);
7422
7423       start_sequence ();
7424
7425       if (!after)
7426         emit_move_insn (target, t0);
7427       t1 = t0;
7428       if (code == NOT)
7429         {
7430           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
7431           code = AND;
7432         }
7433       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7434                                 true, OPTAB_LIB_WIDEN);
7435       if (after)
7436         emit_move_insn (target, t1);
7437
7438       insn = get_insns ();
7439       end_sequence ();
7440
7441       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7442         return target;
7443     }
7444
7445   return NULL_RTX;
7446 }
7447
7448 /* This function expands a test-and-set operation.  Ideally we atomically
7449    store VAL in MEM and return the previous value in MEM.  Some targets
7450    may not support this operation and only support VAL with the constant 1;
7451    in this case while the return value will be 0/1, but the exact value
7452    stored in MEM is target defined.  TARGET is an option place to stick
7453    the return value.  */
7454
7455 rtx
7456 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
7457 {
7458   enum machine_mode mode = GET_MODE (mem);
7459   enum insn_code icode;
7460   rtx insn;
7461
7462   /* If the target supports the test-and-set directly, great.  */
7463   icode = sync_lock_test_and_set[mode];
7464   if (icode != CODE_FOR_nothing)
7465     {
7466       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7467         target = gen_reg_rtx (mode);
7468
7469       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7470         val = convert_modes (mode, GET_MODE (val), val, 1);
7471       if (!insn_data[icode].operand[2].predicate (val, mode))
7472         val = force_reg (mode, val);
7473
7474       insn = GEN_FCN (icode) (target, mem, val);
7475       if (insn)
7476         {
7477           emit_insn (insn);
7478           return target;
7479         }
7480     }
7481
7482   /* Otherwise, use a compare-and-swap loop for the exchange.  */
7483   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7484     {
7485       if (!target || !register_operand (target, mode))
7486         target = gen_reg_rtx (mode);
7487       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7488         val = convert_modes (mode, GET_MODE (val), val, 1);
7489       if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7490         return target;
7491     }
7492
7493   return NULL_RTX;
7494 }
7495
7496 #include "gt-optabs.h"