OSDN Git Service

* config/rs6000/rs6000.c (rs6000_override_options): Set
[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       rtx ulibfunc;
4279
4280       /* If we want unsigned, and this mode has a distinct unsigned
4281          comparison routine, use that.  */
4282       if (unsignedp)
4283         {
4284           ulibfunc = optab_libfunc (ucmp_optab, mode);
4285         }
4286       if (unsignedp && ulibfunc)
4287         libfunc = ulibfunc;
4288
4289       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4290                                         targetm.libgcc_cmp_return_mode (),
4291                                         2, x, mode, y, mode);
4292
4293       /* There are two kinds of comparison routines. Biased routines
4294          return 0/1/2, and unbiased routines return -1/0/1. Other parts
4295          of gcc expect that the comparison operation is equivalent
4296          to the modified comparison. For signed comparisons compare the 
4297          result against 1 in the biased case, and zero in the unbiased
4298          case. For unsigned comparisons always compare against 1 after
4299          biasing the unbiased result by adding 1. This gives us a way to
4300          represent LTU. */
4301       *px = result;
4302       *pmode = word_mode;
4303       *py = const1_rtx;
4304
4305       if (!TARGET_LIB_INT_CMP_BIASED)
4306         {
4307           if (*punsignedp)
4308             *px = plus_constant (result, 1);  
4309           else
4310             *py = const0_rtx;
4311         }
4312       return;
4313     }
4314
4315   gcc_assert (SCALAR_FLOAT_MODE_P (mode));
4316   prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4317 }
4318
4319 /* Before emitting an insn with code ICODE, make sure that X, which is going
4320    to be used for operand OPNUM of the insn, is converted from mode MODE to
4321    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4322    that it is accepted by the operand predicate.  Return the new value.  */
4323
4324 static rtx
4325 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
4326                  enum machine_mode wider_mode, int unsignedp)
4327 {
4328   if (mode != wider_mode)
4329     x = convert_modes (wider_mode, mode, x, unsignedp);
4330
4331   if (!insn_data[icode].operand[opnum].predicate
4332       (x, insn_data[icode].operand[opnum].mode))
4333     {
4334       if (reload_completed)
4335         return NULL_RTX;
4336       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
4337     }
4338
4339   return x;
4340 }
4341
4342 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4343    we can do the comparison.
4344    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
4345    be NULL_RTX which indicates that only a comparison is to be generated.  */
4346
4347 static void
4348 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
4349                           enum rtx_code comparison, int unsignedp, rtx label)
4350 {
4351   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
4352   enum mode_class class = GET_MODE_CLASS (mode);
4353   enum machine_mode wider_mode = mode;
4354
4355   /* Try combined insns first.  */
4356   do
4357     {
4358       enum insn_code icode;
4359       PUT_MODE (test, wider_mode);
4360
4361       if (label)
4362         {
4363           icode = optab_handler (cbranch_optab, wider_mode)->insn_code;
4364
4365           if (icode != CODE_FOR_nothing
4366               && insn_data[icode].operand[0].predicate (test, wider_mode))
4367             {
4368               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
4369               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
4370               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
4371               return;
4372             }
4373         }
4374
4375       /* Handle some compares against zero.  */
4376       icode = (int) optab_handler (tst_optab, wider_mode)->insn_code;
4377       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
4378         {
4379           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4380           emit_insn (GEN_FCN (icode) (x));
4381           if (label)
4382             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4383           return;
4384         }
4385
4386       /* Handle compares for which there is a directly suitable insn.  */
4387
4388       icode = (int) optab_handler (cmp_optab, wider_mode)->insn_code;
4389       if (icode != CODE_FOR_nothing)
4390         {
4391           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4392           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
4393           emit_insn (GEN_FCN (icode) (x, y));
4394           if (label)
4395             emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4396           return;
4397         }
4398
4399       if (!CLASS_HAS_WIDER_MODES_P (class))
4400         break;
4401
4402       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
4403     }
4404   while (wider_mode != VOIDmode);
4405
4406   gcc_unreachable ();
4407 }
4408
4409 /* Generate code to compare X with Y so that the condition codes are
4410    set and to jump to LABEL if the condition is true.  If X is a
4411    constant and Y is not a constant, then the comparison is swapped to
4412    ensure that the comparison RTL has the canonical form.
4413
4414    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4415    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
4416    the proper branch condition code.
4417
4418    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4419
4420    MODE is the mode of the inputs (in case they are const_int).
4421
4422    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
4423    be passed unchanged to emit_cmp_insn, then potentially converted into an
4424    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
4425
4426 void
4427 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4428                          enum machine_mode mode, int unsignedp, rtx label)
4429 {
4430   rtx op0 = x, op1 = y;
4431
4432   /* Swap operands and condition to ensure canonical RTL.  */
4433   if (swap_commutative_operands_p (x, y))
4434     {
4435       /* If we're not emitting a branch, callers are required to pass
4436          operands in an order conforming to canonical RTL.  We relax this
4437          for commutative comparisons so callers using EQ don't need to do
4438          swapping by hand.  */
4439       gcc_assert (label || (comparison == swap_condition (comparison)));
4440
4441       op0 = y, op1 = x;
4442       comparison = swap_condition (comparison);
4443     }
4444
4445 #ifdef HAVE_cc0
4446   /* If OP0 is still a constant, then both X and Y must be constants.
4447      Force X into a register to create canonical RTL.  */
4448   if (CONSTANT_P (op0))
4449     op0 = force_reg (mode, op0);
4450 #endif
4451
4452   if (unsignedp)
4453     comparison = unsigned_condition (comparison);
4454
4455   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
4456                     ccp_jump);
4457   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
4458 }
4459
4460 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
4461
4462 void
4463 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4464                enum machine_mode mode, int unsignedp)
4465 {
4466   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
4467 }
4468 \f
4469 /* Emit a library call comparison between floating point X and Y.
4470    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4471
4472 static void
4473 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
4474                        enum machine_mode *pmode, int *punsignedp)
4475 {
4476   enum rtx_code comparison = *pcomparison;
4477   enum rtx_code swapped = swap_condition (comparison);
4478   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4479   rtx x = *px;
4480   rtx y = *py;
4481   enum machine_mode orig_mode = GET_MODE (x);
4482   enum machine_mode mode, cmp_mode;
4483   rtx value, target, insns, equiv;
4484   rtx libfunc = 0;
4485   bool reversed_p = false;
4486   cmp_mode = targetm.libgcc_cmp_return_mode ();
4487
4488   for (mode = orig_mode;
4489        mode != VOIDmode;
4490        mode = GET_MODE_WIDER_MODE (mode))
4491     {
4492       if ((libfunc = optab_libfunc (code_to_optab[comparison], mode)))
4493         break;
4494
4495       if ((libfunc = optab_libfunc (code_to_optab[swapped] , mode)))
4496         {
4497           rtx tmp;
4498           tmp = x; x = y; y = tmp;
4499           comparison = swapped;
4500           break;
4501         }
4502
4503       if ((libfunc = optab_libfunc (code_to_optab[reversed], mode))
4504           && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4505         {
4506           comparison = reversed;
4507           reversed_p = true;
4508           break;
4509         }
4510     }
4511
4512   gcc_assert (mode != VOIDmode);
4513
4514   if (mode != orig_mode)
4515     {
4516       x = convert_to_mode (mode, x, 0);
4517       y = convert_to_mode (mode, y, 0);
4518     }
4519
4520   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4521      the RTL.  The allows the RTL optimizers to delete the libcall if the
4522      condition can be determined at compile-time.  */
4523   if (comparison == UNORDERED)
4524     {
4525       rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4526       equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4527       equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4528                                     temp, const_true_rtx, equiv);
4529     }
4530   else
4531     {
4532       equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4533       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4534         {
4535           rtx true_rtx, false_rtx;
4536
4537           switch (comparison)
4538             {
4539             case EQ:
4540               true_rtx = const0_rtx;
4541               false_rtx = const_true_rtx;
4542               break;
4543
4544             case NE:
4545               true_rtx = const_true_rtx;
4546               false_rtx = const0_rtx;
4547               break;
4548
4549             case GT:
4550               true_rtx = const1_rtx;
4551               false_rtx = const0_rtx;
4552               break;
4553
4554             case GE:
4555               true_rtx = const0_rtx;
4556               false_rtx = constm1_rtx;
4557               break;
4558
4559             case LT:
4560               true_rtx = constm1_rtx;
4561               false_rtx = const0_rtx;
4562               break;
4563
4564             case LE:
4565               true_rtx = const0_rtx;
4566               false_rtx = const1_rtx;
4567               break;
4568
4569             default:
4570               gcc_unreachable ();
4571             }
4572           equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4573                                         equiv, true_rtx, false_rtx);
4574         }
4575     }
4576
4577   start_sequence ();
4578   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4579                                    cmp_mode, 2, x, mode, y, mode);
4580   insns = get_insns ();
4581   end_sequence ();
4582
4583   target = gen_reg_rtx (cmp_mode);
4584   emit_libcall_block (insns, target, value, equiv);
4585
4586   if (comparison == UNORDERED
4587       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4588     comparison = reversed_p ? EQ : NE;
4589
4590   *px = target;
4591   *py = const0_rtx;
4592   *pmode = cmp_mode;
4593   *pcomparison = comparison;
4594   *punsignedp = 0;
4595 }
4596 \f
4597 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4598
4599 void
4600 emit_indirect_jump (rtx loc)
4601 {
4602   if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4603       (loc, Pmode))
4604     loc = copy_to_mode_reg (Pmode, loc);
4605
4606   emit_jump_insn (gen_indirect_jump (loc));
4607   emit_barrier ();
4608 }
4609 \f
4610 #ifdef HAVE_conditional_move
4611
4612 /* Emit a conditional move instruction if the machine supports one for that
4613    condition and machine mode.
4614
4615    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4616    the mode to use should they be constants.  If it is VOIDmode, they cannot
4617    both be constants.
4618
4619    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4620    should be stored there.  MODE is the mode to use should they be constants.
4621    If it is VOIDmode, they cannot both be constants.
4622
4623    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4624    is not supported.  */
4625
4626 rtx
4627 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4628                        enum machine_mode cmode, rtx op2, rtx op3,
4629                        enum machine_mode mode, int unsignedp)
4630 {
4631   rtx tem, subtarget, comparison, insn;
4632   enum insn_code icode;
4633   enum rtx_code reversed;
4634
4635   /* If one operand is constant, make it the second one.  Only do this
4636      if the other operand is not constant as well.  */
4637
4638   if (swap_commutative_operands_p (op0, op1))
4639     {
4640       tem = op0;
4641       op0 = op1;
4642       op1 = tem;
4643       code = swap_condition (code);
4644     }
4645
4646   /* get_condition will prefer to generate LT and GT even if the old
4647      comparison was against zero, so undo that canonicalization here since
4648      comparisons against zero are cheaper.  */
4649   if (code == LT && op1 == const1_rtx)
4650     code = LE, op1 = const0_rtx;
4651   else if (code == GT && op1 == constm1_rtx)
4652     code = GE, op1 = const0_rtx;
4653
4654   if (cmode == VOIDmode)
4655     cmode = GET_MODE (op0);
4656
4657   if (swap_commutative_operands_p (op2, op3)
4658       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4659           != UNKNOWN))
4660     {
4661       tem = op2;
4662       op2 = op3;
4663       op3 = tem;
4664       code = reversed;
4665     }
4666
4667   if (mode == VOIDmode)
4668     mode = GET_MODE (op2);
4669
4670   icode = movcc_gen_code[mode];
4671
4672   if (icode == CODE_FOR_nothing)
4673     return 0;
4674
4675   if (!target)
4676     target = gen_reg_rtx (mode);
4677
4678   subtarget = target;
4679
4680   /* If the insn doesn't accept these operands, put them in pseudos.  */
4681
4682   if (!insn_data[icode].operand[0].predicate
4683       (subtarget, insn_data[icode].operand[0].mode))
4684     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4685
4686   if (!insn_data[icode].operand[2].predicate
4687       (op2, insn_data[icode].operand[2].mode))
4688     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4689
4690   if (!insn_data[icode].operand[3].predicate
4691       (op3, insn_data[icode].operand[3].mode))
4692     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4693
4694   /* Everything should now be in the suitable form, so emit the compare insn
4695      and then the conditional move.  */
4696
4697   comparison
4698     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4699
4700   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4701   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4702      return NULL and let the caller figure out how best to deal with this
4703      situation.  */
4704   if (GET_CODE (comparison) != code)
4705     return NULL_RTX;
4706
4707   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4708
4709   /* If that failed, then give up.  */
4710   if (insn == 0)
4711     return 0;
4712
4713   emit_insn (insn);
4714
4715   if (subtarget != target)
4716     convert_move (target, subtarget, 0);
4717
4718   return target;
4719 }
4720
4721 /* Return nonzero if a conditional move of mode MODE is supported.
4722
4723    This function is for combine so it can tell whether an insn that looks
4724    like a conditional move is actually supported by the hardware.  If we
4725    guess wrong we lose a bit on optimization, but that's it.  */
4726 /* ??? sparc64 supports conditionally moving integers values based on fp
4727    comparisons, and vice versa.  How do we handle them?  */
4728
4729 int
4730 can_conditionally_move_p (enum machine_mode mode)
4731 {
4732   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4733     return 1;
4734
4735   return 0;
4736 }
4737
4738 #endif /* HAVE_conditional_move */
4739
4740 /* Emit a conditional addition instruction if the machine supports one for that
4741    condition and machine mode.
4742
4743    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4744    the mode to use should they be constants.  If it is VOIDmode, they cannot
4745    both be constants.
4746
4747    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4748    should be stored there.  MODE is the mode to use should they be constants.
4749    If it is VOIDmode, they cannot both be constants.
4750
4751    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4752    is not supported.  */
4753
4754 rtx
4755 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4756                       enum machine_mode cmode, rtx op2, rtx op3,
4757                       enum machine_mode mode, int unsignedp)
4758 {
4759   rtx tem, subtarget, comparison, insn;
4760   enum insn_code icode;
4761   enum rtx_code reversed;
4762
4763   /* If one operand is constant, make it the second one.  Only do this
4764      if the other operand is not constant as well.  */
4765
4766   if (swap_commutative_operands_p (op0, op1))
4767     {
4768       tem = op0;
4769       op0 = op1;
4770       op1 = tem;
4771       code = swap_condition (code);
4772     }
4773
4774   /* get_condition will prefer to generate LT and GT even if the old
4775      comparison was against zero, so undo that canonicalization here since
4776      comparisons against zero are cheaper.  */
4777   if (code == LT && op1 == const1_rtx)
4778     code = LE, op1 = const0_rtx;
4779   else if (code == GT && op1 == constm1_rtx)
4780     code = GE, op1 = const0_rtx;
4781
4782   if (cmode == VOIDmode)
4783     cmode = GET_MODE (op0);
4784
4785   if (swap_commutative_operands_p (op2, op3)
4786       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4787           != UNKNOWN))
4788     {
4789       tem = op2;
4790       op2 = op3;
4791       op3 = tem;
4792       code = reversed;
4793     }
4794
4795   if (mode == VOIDmode)
4796     mode = GET_MODE (op2);
4797
4798   icode = optab_handler (addcc_optab, mode)->insn_code;
4799
4800   if (icode == CODE_FOR_nothing)
4801     return 0;
4802
4803   if (!target)
4804     target = gen_reg_rtx (mode);
4805
4806   /* If the insn doesn't accept these operands, put them in pseudos.  */
4807
4808   if (!insn_data[icode].operand[0].predicate
4809       (target, insn_data[icode].operand[0].mode))
4810     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4811   else
4812     subtarget = target;
4813
4814   if (!insn_data[icode].operand[2].predicate
4815       (op2, insn_data[icode].operand[2].mode))
4816     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4817
4818   if (!insn_data[icode].operand[3].predicate
4819       (op3, insn_data[icode].operand[3].mode))
4820     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4821
4822   /* Everything should now be in the suitable form, so emit the compare insn
4823      and then the conditional move.  */
4824
4825   comparison
4826     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4827
4828   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4829   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4830      return NULL and let the caller figure out how best to deal with this
4831      situation.  */
4832   if (GET_CODE (comparison) != code)
4833     return NULL_RTX;
4834
4835   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4836
4837   /* If that failed, then give up.  */
4838   if (insn == 0)
4839     return 0;
4840
4841   emit_insn (insn);
4842
4843   if (subtarget != target)
4844     convert_move (target, subtarget, 0);
4845
4846   return target;
4847 }
4848 \f
4849 /* These functions attempt to generate an insn body, rather than
4850    emitting the insn, but if the gen function already emits them, we
4851    make no attempt to turn them back into naked patterns.  */
4852
4853 /* Generate and return an insn body to add Y to X.  */
4854
4855 rtx
4856 gen_add2_insn (rtx x, rtx y)
4857 {
4858   int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4859
4860   gcc_assert (insn_data[icode].operand[0].predicate
4861               (x, insn_data[icode].operand[0].mode));
4862   gcc_assert (insn_data[icode].operand[1].predicate
4863               (x, insn_data[icode].operand[1].mode));
4864   gcc_assert (insn_data[icode].operand[2].predicate
4865               (y, insn_data[icode].operand[2].mode));
4866
4867   return GEN_FCN (icode) (x, x, y);
4868 }
4869
4870 /* Generate and return an insn body to add r1 and c,
4871    storing the result in r0.  */
4872
4873 rtx
4874 gen_add3_insn (rtx r0, rtx r1, rtx c)
4875 {
4876   int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code;
4877
4878   if (icode == CODE_FOR_nothing
4879       || !(insn_data[icode].operand[0].predicate
4880            (r0, insn_data[icode].operand[0].mode))
4881       || !(insn_data[icode].operand[1].predicate
4882            (r1, insn_data[icode].operand[1].mode))
4883       || !(insn_data[icode].operand[2].predicate
4884            (c, insn_data[icode].operand[2].mode)))
4885     return NULL_RTX;
4886
4887   return GEN_FCN (icode) (r0, r1, c);
4888 }
4889
4890 int
4891 have_add2_insn (rtx x, rtx y)
4892 {
4893   int icode;
4894
4895   gcc_assert (GET_MODE (x) != VOIDmode);
4896
4897   icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4898
4899   if (icode == CODE_FOR_nothing)
4900     return 0;
4901
4902   if (!(insn_data[icode].operand[0].predicate
4903         (x, insn_data[icode].operand[0].mode))
4904       || !(insn_data[icode].operand[1].predicate
4905            (x, insn_data[icode].operand[1].mode))
4906       || !(insn_data[icode].operand[2].predicate
4907            (y, insn_data[icode].operand[2].mode)))
4908     return 0;
4909
4910   return 1;
4911 }
4912
4913 /* Generate and return an insn body to subtract Y from X.  */
4914
4915 rtx
4916 gen_sub2_insn (rtx x, rtx y)
4917 {
4918   int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4919
4920   gcc_assert (insn_data[icode].operand[0].predicate
4921               (x, insn_data[icode].operand[0].mode));
4922   gcc_assert (insn_data[icode].operand[1].predicate
4923               (x, insn_data[icode].operand[1].mode));
4924   gcc_assert  (insn_data[icode].operand[2].predicate
4925                (y, insn_data[icode].operand[2].mode));
4926
4927   return GEN_FCN (icode) (x, x, y);
4928 }
4929
4930 /* Generate and return an insn body to subtract r1 and c,
4931    storing the result in r0.  */
4932
4933 rtx
4934 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4935 {
4936   int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code;
4937
4938   if (icode == CODE_FOR_nothing
4939       || !(insn_data[icode].operand[0].predicate
4940            (r0, insn_data[icode].operand[0].mode))
4941       || !(insn_data[icode].operand[1].predicate
4942            (r1, insn_data[icode].operand[1].mode))
4943       || !(insn_data[icode].operand[2].predicate
4944            (c, insn_data[icode].operand[2].mode)))
4945     return NULL_RTX;
4946
4947   return GEN_FCN (icode) (r0, r1, c);
4948 }
4949
4950 int
4951 have_sub2_insn (rtx x, rtx y)
4952 {
4953   int icode;
4954
4955   gcc_assert (GET_MODE (x) != VOIDmode);
4956
4957   icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4958
4959   if (icode == CODE_FOR_nothing)
4960     return 0;
4961
4962   if (!(insn_data[icode].operand[0].predicate
4963         (x, insn_data[icode].operand[0].mode))
4964       || !(insn_data[icode].operand[1].predicate
4965            (x, insn_data[icode].operand[1].mode))
4966       || !(insn_data[icode].operand[2].predicate
4967            (y, insn_data[icode].operand[2].mode)))
4968     return 0;
4969
4970   return 1;
4971 }
4972
4973 /* Generate the body of an instruction to copy Y into X.
4974    It may be a list of insns, if one insn isn't enough.  */
4975
4976 rtx
4977 gen_move_insn (rtx x, rtx y)
4978 {
4979   rtx seq;
4980
4981   start_sequence ();
4982   emit_move_insn_1 (x, y);
4983   seq = get_insns ();
4984   end_sequence ();
4985   return seq;
4986 }
4987 \f
4988 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4989    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4990    no such operation exists, CODE_FOR_nothing will be returned.  */
4991
4992 enum insn_code
4993 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4994               int unsignedp)
4995 {
4996   convert_optab tab;
4997 #ifdef HAVE_ptr_extend
4998   if (unsignedp < 0)
4999     return CODE_FOR_ptr_extend;
5000 #endif
5001
5002   tab = unsignedp ? zext_optab : sext_optab;
5003   return convert_optab_handler (tab, to_mode, from_mode)->insn_code;
5004 }
5005
5006 /* Generate the body of an insn to extend Y (with mode MFROM)
5007    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
5008
5009 rtx
5010 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
5011                  enum machine_mode mfrom, int unsignedp)
5012 {
5013   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
5014   return GEN_FCN (icode) (x, y);
5015 }
5016 \f
5017 /* can_fix_p and can_float_p say whether the target machine
5018    can directly convert a given fixed point type to
5019    a given floating point type, or vice versa.
5020    The returned value is the CODE_FOR_... value to use,
5021    or CODE_FOR_nothing if these modes cannot be directly converted.
5022
5023    *TRUNCP_PTR is set to 1 if it is necessary to output
5024    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
5025
5026 static enum insn_code
5027 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
5028            int unsignedp, int *truncp_ptr)
5029 {
5030   convert_optab tab;
5031   enum insn_code icode;
5032
5033   tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
5034   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
5035   if (icode != CODE_FOR_nothing)
5036     {
5037       *truncp_ptr = 0;
5038       return icode;
5039     }
5040
5041   /* FIXME: This requires a port to define both FIX and FTRUNC pattern
5042      for this to work. We need to rework the fix* and ftrunc* patterns
5043      and documentation.  */
5044   tab = unsignedp ? ufix_optab : sfix_optab;
5045   icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
5046   if (icode != CODE_FOR_nothing
5047       && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing)
5048     {
5049       *truncp_ptr = 1;
5050       return icode;
5051     }
5052
5053   *truncp_ptr = 0;
5054   return CODE_FOR_nothing;
5055 }
5056
5057 static enum insn_code
5058 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
5059              int unsignedp)
5060 {
5061   convert_optab tab;
5062
5063   tab = unsignedp ? ufloat_optab : sfloat_optab;
5064   return convert_optab_handler (tab, fltmode, fixmode)->insn_code;
5065 }
5066 \f
5067 /* Generate code to convert FROM to floating point
5068    and store in TO.  FROM must be fixed point and not VOIDmode.
5069    UNSIGNEDP nonzero means regard FROM as unsigned.
5070    Normally this is done by correcting the final value
5071    if it is negative.  */
5072
5073 void
5074 expand_float (rtx to, rtx from, int unsignedp)
5075 {
5076   enum insn_code icode;
5077   rtx target = to;
5078   enum machine_mode fmode, imode;
5079   bool can_do_signed = false;
5080
5081   /* Crash now, because we won't be able to decide which mode to use.  */
5082   gcc_assert (GET_MODE (from) != VOIDmode);
5083
5084   /* Look for an insn to do the conversion.  Do it in the specified
5085      modes if possible; otherwise convert either input, output or both to
5086      wider mode.  If the integer mode is wider than the mode of FROM,
5087      we can do the conversion signed even if the input is unsigned.  */
5088
5089   for (fmode = GET_MODE (to); fmode != VOIDmode;
5090        fmode = GET_MODE_WIDER_MODE (fmode))
5091     for (imode = GET_MODE (from); imode != VOIDmode;
5092          imode = GET_MODE_WIDER_MODE (imode))
5093       {
5094         int doing_unsigned = unsignedp;
5095
5096         if (fmode != GET_MODE (to)
5097             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
5098           continue;
5099
5100         icode = can_float_p (fmode, imode, unsignedp);
5101         if (icode == CODE_FOR_nothing && unsignedp)
5102           {
5103             enum insn_code scode = can_float_p (fmode, imode, 0);
5104             if (scode != CODE_FOR_nothing)
5105               can_do_signed = true;
5106             if (imode != GET_MODE (from))
5107               icode = scode, doing_unsigned = 0;
5108           }
5109
5110         if (icode != CODE_FOR_nothing)
5111           {
5112             if (imode != GET_MODE (from))
5113               from = convert_to_mode (imode, from, unsignedp);
5114
5115             if (fmode != GET_MODE (to))
5116               target = gen_reg_rtx (fmode);
5117
5118             emit_unop_insn (icode, target, from,
5119                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5120
5121             if (target != to)
5122               convert_move (to, target, 0);
5123             return;
5124           }
5125       }
5126
5127   /* Unsigned integer, and no way to convert directly.  Convert as signed,
5128      then unconditionally adjust the result.  For decimal float values we
5129      do this only if we have already determined that a signed conversion
5130      provides sufficient accuracy.  */
5131   if (unsignedp && (can_do_signed || !DECIMAL_FLOAT_MODE_P (GET_MODE (to))))
5132     {
5133       rtx label = gen_label_rtx ();
5134       rtx temp;
5135       REAL_VALUE_TYPE offset;
5136
5137       /* Look for a usable floating mode FMODE wider than the source and at
5138          least as wide as the target.  Using FMODE will avoid rounding woes
5139          with unsigned values greater than the signed maximum value.  */
5140
5141       for (fmode = GET_MODE (to);  fmode != VOIDmode;
5142            fmode = GET_MODE_WIDER_MODE (fmode))
5143         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5144             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5145           break;
5146
5147       if (fmode == VOIDmode)
5148         {
5149           /* There is no such mode.  Pretend the target is wide enough.  */
5150           fmode = GET_MODE (to);
5151
5152           /* Avoid double-rounding when TO is narrower than FROM.  */
5153           if ((significand_size (fmode) + 1)
5154               < GET_MODE_BITSIZE (GET_MODE (from)))
5155             {
5156               rtx temp1;
5157               rtx neglabel = gen_label_rtx ();
5158
5159               /* Don't use TARGET if it isn't a register, is a hard register,
5160                  or is the wrong mode.  */
5161               if (!REG_P (target)
5162                   || REGNO (target) < FIRST_PSEUDO_REGISTER
5163                   || GET_MODE (target) != fmode)
5164                 target = gen_reg_rtx (fmode);
5165
5166               imode = GET_MODE (from);
5167               do_pending_stack_adjust ();
5168
5169               /* Test whether the sign bit is set.  */
5170               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5171                                        0, neglabel);
5172
5173               /* The sign bit is not set.  Convert as signed.  */
5174               expand_float (target, from, 0);
5175               emit_jump_insn (gen_jump (label));
5176               emit_barrier ();
5177
5178               /* The sign bit is set.
5179                  Convert to a usable (positive signed) value by shifting right
5180                  one bit, while remembering if a nonzero bit was shifted
5181                  out; i.e., compute  (from & 1) | (from >> 1).  */
5182
5183               emit_label (neglabel);
5184               temp = expand_binop (imode, and_optab, from, const1_rtx,
5185                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
5186               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
5187                                     NULL_RTX, 1);
5188               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5189                                    OPTAB_LIB_WIDEN);
5190               expand_float (target, temp, 0);
5191
5192               /* Multiply by 2 to undo the shift above.  */
5193               temp = expand_binop (fmode, add_optab, target, target,
5194                                    target, 0, OPTAB_LIB_WIDEN);
5195               if (temp != target)
5196                 emit_move_insn (target, temp);
5197
5198               do_pending_stack_adjust ();
5199               emit_label (label);
5200               goto done;
5201             }
5202         }
5203
5204       /* If we are about to do some arithmetic to correct for an
5205          unsigned operand, do it in a pseudo-register.  */
5206
5207       if (GET_MODE (to) != fmode
5208           || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5209         target = gen_reg_rtx (fmode);
5210
5211       /* Convert as signed integer to floating.  */
5212       expand_float (target, from, 0);
5213
5214       /* If FROM is negative (and therefore TO is negative),
5215          correct its value by 2**bitwidth.  */
5216
5217       do_pending_stack_adjust ();
5218       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5219                                0, label);
5220
5221
5222       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)), fmode);
5223       temp = expand_binop (fmode, add_optab, target,
5224                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5225                            target, 0, OPTAB_LIB_WIDEN);
5226       if (temp != target)
5227         emit_move_insn (target, temp);
5228
5229       do_pending_stack_adjust ();
5230       emit_label (label);
5231       goto done;
5232     }
5233
5234   /* No hardware instruction available; call a library routine.  */
5235     {
5236       rtx libfunc;
5237       rtx insns;
5238       rtx value;
5239       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5240
5241       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5242         from = convert_to_mode (SImode, from, unsignedp);
5243
5244       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5245       gcc_assert (libfunc);
5246
5247       start_sequence ();
5248
5249       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5250                                        GET_MODE (to), 1, from,
5251                                        GET_MODE (from));
5252       insns = get_insns ();
5253       end_sequence ();
5254
5255       emit_libcall_block (insns, target, value,
5256                           gen_rtx_FLOAT (GET_MODE (to), from));
5257     }
5258
5259  done:
5260
5261   /* Copy result to requested destination
5262      if we have been computing in a temp location.  */
5263
5264   if (target != to)
5265     {
5266       if (GET_MODE (target) == GET_MODE (to))
5267         emit_move_insn (to, target);
5268       else
5269         convert_move (to, target, 0);
5270     }
5271 }
5272 \f
5273 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5274    must be floating point.  */
5275
5276 void
5277 expand_fix (rtx to, rtx from, int unsignedp)
5278 {
5279   enum insn_code icode;
5280   rtx target = to;
5281   enum machine_mode fmode, imode;
5282   int must_trunc = 0;
5283
5284   /* We first try to find a pair of modes, one real and one integer, at
5285      least as wide as FROM and TO, respectively, in which we can open-code
5286      this conversion.  If the integer mode is wider than the mode of TO,
5287      we can do the conversion either signed or unsigned.  */
5288
5289   for (fmode = GET_MODE (from); fmode != VOIDmode;
5290        fmode = GET_MODE_WIDER_MODE (fmode))
5291     for (imode = GET_MODE (to); imode != VOIDmode;
5292          imode = GET_MODE_WIDER_MODE (imode))
5293       {
5294         int doing_unsigned = unsignedp;
5295
5296         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5297         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5298           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5299
5300         if (icode != CODE_FOR_nothing)
5301           {
5302             if (fmode != GET_MODE (from))
5303               from = convert_to_mode (fmode, from, 0);
5304
5305             if (must_trunc)
5306               {
5307                 rtx temp = gen_reg_rtx (GET_MODE (from));
5308                 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5309                                     temp, 0);
5310               }
5311
5312             if (imode != GET_MODE (to))
5313               target = gen_reg_rtx (imode);
5314
5315             emit_unop_insn (icode, target, from,
5316                             doing_unsigned ? UNSIGNED_FIX : FIX);
5317             if (target != to)
5318               convert_move (to, target, unsignedp);
5319             return;
5320           }
5321       }
5322
5323   /* For an unsigned conversion, there is one more way to do it.
5324      If we have a signed conversion, we generate code that compares
5325      the real value to the largest representable positive number.  If if
5326      is smaller, the conversion is done normally.  Otherwise, subtract
5327      one plus the highest signed number, convert, and add it back.
5328
5329      We only need to check all real modes, since we know we didn't find
5330      anything with a wider integer mode.
5331
5332      This code used to extend FP value into mode wider than the destination.
5333      This is needed for decimal float modes which cannot accurately
5334      represent one plus the highest signed number of the same size, but
5335      not for binary modes.  Consider, for instance conversion from SFmode
5336      into DImode.
5337
5338      The hot path through the code is dealing with inputs smaller than 2^63
5339      and doing just the conversion, so there is no bits to lose.
5340
5341      In the other path we know the value is positive in the range 2^63..2^64-1
5342      inclusive.  (as for other input overflow happens and result is undefined)
5343      So we know that the most important bit set in mantissa corresponds to
5344      2^63.  The subtraction of 2^63 should not generate any rounding as it
5345      simply clears out that bit.  The rest is trivial.  */
5346
5347   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5348     for (fmode = GET_MODE (from); fmode != VOIDmode;
5349          fmode = GET_MODE_WIDER_MODE (fmode))
5350       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5351           && (!DECIMAL_FLOAT_MODE_P (fmode)
5352               || GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))))
5353         {
5354           int bitsize;
5355           REAL_VALUE_TYPE offset;
5356           rtx limit, lab1, lab2, insn;
5357
5358           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5359           real_2expN (&offset, bitsize - 1, fmode);
5360           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5361           lab1 = gen_label_rtx ();
5362           lab2 = gen_label_rtx ();
5363
5364           if (fmode != GET_MODE (from))
5365             from = convert_to_mode (fmode, from, 0);
5366
5367           /* See if we need to do the subtraction.  */
5368           do_pending_stack_adjust ();
5369           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5370                                    0, lab1);
5371
5372           /* If not, do the signed "fix" and branch around fixup code.  */
5373           expand_fix (to, from, 0);
5374           emit_jump_insn (gen_jump (lab2));
5375           emit_barrier ();
5376
5377           /* Otherwise, subtract 2**(N-1), convert to signed number,
5378              then add 2**(N-1).  Do the addition using XOR since this
5379              will often generate better code.  */
5380           emit_label (lab1);
5381           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5382                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
5383           expand_fix (to, target, 0);
5384           target = expand_binop (GET_MODE (to), xor_optab, to,
5385                                  gen_int_mode
5386                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
5387                                   GET_MODE (to)),
5388                                  to, 1, OPTAB_LIB_WIDEN);
5389
5390           if (target != to)
5391             emit_move_insn (to, target);
5392
5393           emit_label (lab2);
5394
5395           if (optab_handler (mov_optab, GET_MODE (to))->insn_code
5396               != CODE_FOR_nothing)
5397             {
5398               /* Make a place for a REG_NOTE and add it.  */
5399               insn = emit_move_insn (to, to);
5400               set_unique_reg_note (insn,
5401                                    REG_EQUAL,
5402                                    gen_rtx_fmt_e (UNSIGNED_FIX,
5403                                                   GET_MODE (to),
5404                                                   copy_rtx (from)));
5405             }
5406
5407           return;
5408         }
5409
5410   /* We can't do it with an insn, so use a library call.  But first ensure
5411      that the mode of TO is at least as wide as SImode, since those are the
5412      only library calls we know about.  */
5413
5414   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5415     {
5416       target = gen_reg_rtx (SImode);
5417
5418       expand_fix (target, from, unsignedp);
5419     }
5420   else
5421     {
5422       rtx insns;
5423       rtx value;
5424       rtx libfunc;
5425
5426       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5427       libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5428       gcc_assert (libfunc);
5429
5430       start_sequence ();
5431
5432       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5433                                        GET_MODE (to), 1, from,
5434                                        GET_MODE (from));
5435       insns = get_insns ();
5436       end_sequence ();
5437
5438       emit_libcall_block (insns, target, value,
5439                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5440                                          GET_MODE (to), from));
5441     }
5442
5443   if (target != to)
5444     {
5445       if (GET_MODE (to) == GET_MODE (target))
5446         emit_move_insn (to, target);
5447       else
5448         convert_move (to, target, 0);
5449     }
5450 }
5451
5452 /* Generate code to convert FROM or TO a fixed-point.
5453    If UINTP is true, either TO or FROM is an unsigned integer.
5454    If SATP is true, we need to saturate the result.  */
5455
5456 void
5457 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5458 {
5459   enum machine_mode to_mode = GET_MODE (to);
5460   enum machine_mode from_mode = GET_MODE (from);
5461   convert_optab tab;
5462   enum rtx_code this_code;
5463   enum insn_code code;
5464   rtx insns, value;
5465   rtx libfunc;
5466
5467   if (to_mode == from_mode)
5468     {
5469       emit_move_insn (to, from);
5470       return;
5471     }
5472
5473   if (uintp)
5474     {
5475       tab = satp ? satfractuns_optab : fractuns_optab;
5476       this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5477     }
5478   else
5479     {
5480       tab = satp ? satfract_optab : fract_optab;
5481       this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5482     }
5483   code = tab->handlers[to_mode][from_mode].insn_code;
5484   if (code != CODE_FOR_nothing)
5485     {
5486       emit_unop_insn (code, to, from, this_code);
5487       return;
5488     }
5489
5490   libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5491   gcc_assert (libfunc);
5492
5493   start_sequence ();
5494   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5495                                    1, from, from_mode);
5496   insns = get_insns ();
5497   end_sequence ();
5498
5499   emit_libcall_block (insns, to, value,
5500                       gen_rtx_fmt_e (tab->code, to_mode, from));
5501 }
5502
5503 /* Generate code to convert FROM to fixed point and store in TO.  FROM
5504    must be floating point, TO must be signed.  Use the conversion optab
5505    TAB to do the conversion.  */
5506
5507 bool
5508 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5509 {
5510   enum insn_code icode;
5511   rtx target = to;
5512   enum machine_mode fmode, imode;
5513
5514   /* We first try to find a pair of modes, one real and one integer, at
5515      least as wide as FROM and TO, respectively, in which we can open-code
5516      this conversion.  If the integer mode is wider than the mode of TO,
5517      we can do the conversion either signed or unsigned.  */
5518
5519   for (fmode = GET_MODE (from); fmode != VOIDmode;
5520        fmode = GET_MODE_WIDER_MODE (fmode))
5521     for (imode = GET_MODE (to); imode != VOIDmode;
5522          imode = GET_MODE_WIDER_MODE (imode))
5523       {
5524         icode = convert_optab_handler (tab, imode, fmode)->insn_code;
5525         if (icode != CODE_FOR_nothing)
5526           {
5527             if (fmode != GET_MODE (from))
5528               from = convert_to_mode (fmode, from, 0);
5529
5530             if (imode != GET_MODE (to))
5531               target = gen_reg_rtx (imode);
5532
5533             emit_unop_insn (icode, target, from, UNKNOWN);
5534             if (target != to)
5535               convert_move (to, target, 0);
5536             return true;
5537           }
5538       }
5539
5540   return false;
5541 }
5542 \f
5543 /* Report whether we have an instruction to perform the operation
5544    specified by CODE on operands of mode MODE.  */
5545 int
5546 have_insn_for (enum rtx_code code, enum machine_mode mode)
5547 {
5548   return (code_to_optab[(int) code] != 0
5549           && (optab_handler (code_to_optab[(int) code], mode)->insn_code
5550               != CODE_FOR_nothing));
5551 }
5552
5553 /* Create a blank optab.  */
5554 static optab
5555 new_optab (void)
5556 {
5557   int i;
5558   optab op = xcalloc (sizeof (struct optab), 1);
5559
5560   for (i = 0; i < NUM_MACHINE_MODES; i++)
5561     optab_handler (op, i)->insn_code = CODE_FOR_nothing;
5562
5563   return op;
5564 }
5565
5566 static convert_optab
5567 new_convert_optab (void)
5568 {
5569   int i, j;
5570   convert_optab op = xcalloc (sizeof (struct convert_optab), 1);
5571
5572   for (i = 0; i < NUM_MACHINE_MODES; i++)
5573     for (j = 0; j < NUM_MACHINE_MODES; j++)
5574       convert_optab_handler (op, i, j)->insn_code = CODE_FOR_nothing;
5575
5576   return op;
5577 }
5578
5579 /* Same, but fill in its code as CODE, and write it into the
5580    code_to_optab table.  */
5581 static inline optab
5582 init_optab (enum rtx_code code)
5583 {
5584   optab op = new_optab ();
5585   op->code = code;
5586   code_to_optab[(int) code] = op;
5587   return op;
5588 }
5589
5590 /* Same, but fill in its code as CODE, and do _not_ write it into
5591    the code_to_optab table.  */
5592 static inline optab
5593 init_optabv (enum rtx_code code)
5594 {
5595   optab op = new_optab ();
5596   op->code = code;
5597   return op;
5598 }
5599
5600 /* Conversion optabs never go in the code_to_optab table.  */
5601 static inline convert_optab
5602 init_convert_optab (enum rtx_code code)
5603 {
5604   convert_optab op = new_convert_optab ();
5605   op->code = code;
5606   return op;
5607 }
5608
5609 /* Initialize the libfunc fields of an entire group of entries in some
5610    optab.  Each entry is set equal to a string consisting of a leading
5611    pair of underscores followed by a generic operation name followed by
5612    a mode name (downshifted to lowercase) followed by a single character
5613    representing the number of operands for the given operation (which is
5614    usually one of the characters '2', '3', or '4').
5615
5616    OPTABLE is the table in which libfunc fields are to be initialized.
5617    OPNAME is the generic (string) name of the operation.
5618    SUFFIX is the character which specifies the number of operands for
5619      the given generic operation.
5620    MODE is the mode to generate for.
5621 */
5622
5623 static void
5624 gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mode)
5625 {
5626   unsigned opname_len = strlen (opname);
5627   const char *mname = GET_MODE_NAME (mode);
5628   unsigned mname_len = strlen (mname);
5629   char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5630   char *p;
5631   const char *q;
5632
5633   p = libfunc_name;
5634   *p++ = '_';
5635   *p++ = '_';
5636   for (q = opname; *q; )
5637     *p++ = *q++;
5638   for (q = mname; *q; q++)
5639     *p++ = TOLOWER (*q);
5640   *p++ = suffix;
5641   *p = '\0';
5642
5643   set_optab_libfunc (optable, mode,
5644                      ggc_alloc_string (libfunc_name, p - libfunc_name));
5645 }
5646
5647 /* Like gen_libfunc, but verify that integer operation is involved.  */
5648
5649 static void
5650 gen_int_libfunc (optab optable, const char *opname, char suffix,
5651                  enum machine_mode mode)
5652 {
5653   int maxsize = 2 * BITS_PER_WORD;
5654
5655   if (GET_MODE_CLASS (mode) != MODE_INT)
5656     return;
5657   if (maxsize < LONG_LONG_TYPE_SIZE)
5658     maxsize = LONG_LONG_TYPE_SIZE;
5659   if (GET_MODE_CLASS (mode) != MODE_INT
5660       || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5661     return;
5662   gen_libfunc (optable, opname, suffix, mode);
5663 }
5664
5665 /* Like gen_libfunc, but verify that FP and set decimal prefix if needed.  */
5666
5667 static void
5668 gen_fp_libfunc (optab optable, const char *opname, char suffix,
5669                 enum machine_mode mode)
5670 {
5671   char *dec_opname;
5672
5673   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5674     gen_libfunc (optable, opname, suffix, mode);
5675   if (DECIMAL_FLOAT_MODE_P (mode))
5676     {
5677       dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
5678       /* For BID support, change the name to have either a bid_ or dpd_ prefix
5679          depending on the low level floating format used.  */
5680       memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5681       strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5682       gen_libfunc (optable, dec_opname, suffix, mode);
5683     }
5684 }
5685
5686 /* Like gen_libfunc, but verify that fixed-point operation is involved.  */
5687
5688 static void
5689 gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5690                    enum machine_mode mode)
5691 {
5692   if (!ALL_FIXED_POINT_MODE_P (mode))
5693     return;
5694   gen_libfunc (optable, opname, suffix, mode);
5695 }
5696
5697 /* Like gen_libfunc, but verify that signed fixed-point operation is
5698    involved.  */
5699
5700 static void
5701 gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5702                           enum machine_mode mode)
5703 {
5704   if (!SIGNED_FIXED_POINT_MODE_P (mode))
5705     return;
5706   gen_libfunc (optable, opname, suffix, mode);
5707 }
5708
5709 /* Like gen_libfunc, but verify that unsigned fixed-point operation is
5710    involved.  */
5711
5712 static void
5713 gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5714                             enum machine_mode mode)
5715 {
5716   if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5717     return;
5718   gen_libfunc (optable, opname, suffix, mode);
5719 }
5720
5721 /* Like gen_libfunc, but verify that FP or INT operation is involved.  */
5722
5723 static void
5724 gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5725                     enum machine_mode mode)
5726 {
5727   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5728     gen_fp_libfunc (optable, name, suffix, mode);
5729   if (INTEGRAL_MODE_P (mode))
5730     gen_int_libfunc (optable, name, suffix, mode);
5731 }
5732
5733 /* Like gen_libfunc, but verify that FP or INT operation is involved
5734    and add 'v' suffix for integer operation.  */
5735
5736 static void
5737 gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5738                      enum machine_mode mode)
5739 {
5740   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5741     gen_fp_libfunc (optable, name, suffix, mode);
5742   if (GET_MODE_CLASS (mode) == MODE_INT)
5743     {
5744       int len = strlen (name);
5745       char *v_name = alloca (len + 2);
5746       strcpy (v_name, name);
5747       v_name[len] = 'v';
5748       v_name[len + 1] = 0;
5749       gen_int_libfunc (optable, v_name, suffix, mode);
5750     }
5751 }
5752
5753 /* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5754    involved.  */
5755
5756 static void
5757 gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5758                           enum machine_mode mode)
5759 {
5760   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5761     gen_fp_libfunc (optable, name, suffix, mode);
5762   if (INTEGRAL_MODE_P (mode))
5763     gen_int_libfunc (optable, name, suffix, mode);
5764   if (ALL_FIXED_POINT_MODE_P (mode))
5765     gen_fixed_libfunc (optable, name, suffix, mode);
5766 }
5767
5768 /* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5769    involved.  */
5770
5771 static void
5772 gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5773                                  enum machine_mode mode)
5774 {
5775   if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5776     gen_fp_libfunc (optable, name, suffix, mode);
5777   if (INTEGRAL_MODE_P (mode))
5778     gen_int_libfunc (optable, name, suffix, mode);
5779   if (SIGNED_FIXED_POINT_MODE_P (mode))
5780     gen_signed_fixed_libfunc (optable, name, suffix, mode);
5781 }
5782
5783 /* Like gen_libfunc, but verify that INT or FIXED operation is
5784    involved.  */
5785
5786 static void
5787 gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5788                        enum machine_mode mode)
5789 {
5790   if (INTEGRAL_MODE_P (mode))
5791     gen_int_libfunc (optable, name, suffix, mode);
5792   if (ALL_FIXED_POINT_MODE_P (mode))
5793     gen_fixed_libfunc (optable, name, suffix, mode);
5794 }
5795
5796 /* Like gen_libfunc, but verify that INT or signed FIXED operation is
5797    involved.  */
5798
5799 static void
5800 gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5801                               enum machine_mode mode)
5802 {
5803   if (INTEGRAL_MODE_P (mode))
5804     gen_int_libfunc (optable, name, suffix, mode);
5805   if (SIGNED_FIXED_POINT_MODE_P (mode))
5806     gen_signed_fixed_libfunc (optable, name, suffix, mode);
5807 }
5808
5809 /* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5810    involved.  */
5811
5812 static void
5813 gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5814                                 enum machine_mode mode)
5815 {
5816   if (INTEGRAL_MODE_P (mode))
5817     gen_int_libfunc (optable, name, suffix, mode);
5818   if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5819     gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5820 }
5821
5822 /* Initialize the libfunc fields of an entire group of entries of an
5823    inter-mode-class conversion optab.  The string formation rules are
5824    similar to the ones for init_libfuncs, above, but instead of having
5825    a mode name and an operand count these functions have two mode names
5826    and no operand count.  */
5827
5828 static void
5829 gen_interclass_conv_libfunc (convert_optab tab,
5830                              const char *opname,
5831                              enum machine_mode tmode,
5832                              enum machine_mode fmode)
5833 {
5834   size_t opname_len = strlen (opname);
5835   size_t mname_len = 0;
5836
5837   const char *fname, *tname;
5838   const char *q;
5839   char *libfunc_name, *suffix;
5840   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5841   char *p;
5842
5843   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5844      depends on which underlying decimal floating point format is used.  */
5845   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5846
5847   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5848
5849   nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
5850   nondec_name[0] = '_';
5851   nondec_name[1] = '_';
5852   memcpy (&nondec_name[2], opname, opname_len);
5853   nondec_suffix = nondec_name + opname_len + 2;
5854
5855   dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
5856   dec_name[0] = '_';
5857   dec_name[1] = '_';
5858   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5859   memcpy (&dec_name[2+dec_len], opname, opname_len);
5860   dec_suffix = dec_name + dec_len + opname_len + 2;
5861
5862   fname = GET_MODE_NAME (fmode);
5863   tname = GET_MODE_NAME (tmode);
5864
5865   if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5866     {
5867       libfunc_name = dec_name;
5868       suffix = dec_suffix;
5869     }
5870   else
5871     {
5872       libfunc_name = nondec_name;
5873       suffix = nondec_suffix;
5874     }
5875
5876   p = suffix;
5877   for (q = fname; *q; p++, q++)
5878     *p = TOLOWER (*q);
5879   for (q = tname; *q; p++, q++)
5880     *p = TOLOWER (*q);
5881
5882   *p = '\0';
5883
5884   set_conv_libfunc (tab, tmode, fmode,
5885                     ggc_alloc_string (libfunc_name, p - libfunc_name));
5886 }
5887
5888 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5889    int->fp conversion.  */
5890
5891 static void
5892 gen_int_to_fp_conv_libfunc (convert_optab tab,
5893                             const char *opname,
5894                             enum machine_mode tmode,
5895                             enum machine_mode fmode)
5896 {
5897   if (GET_MODE_CLASS (fmode) != MODE_INT)
5898     return;
5899   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5900     return;
5901   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5902 }
5903
5904 /* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5905    naming scheme.  */
5906
5907 static void
5908 gen_ufloat_conv_libfunc (convert_optab tab,
5909                          const char *opname ATTRIBUTE_UNUSED,
5910                          enum machine_mode tmode,
5911                          enum machine_mode fmode)
5912 {
5913   if (DECIMAL_FLOAT_MODE_P (tmode))
5914     gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5915   else
5916     gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5917 }
5918
5919 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5920    fp->int conversion.  */
5921
5922 static void
5923 gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5924                                        const char *opname,
5925                                        enum machine_mode tmode,
5926                                        enum machine_mode fmode)
5927 {
5928   if (GET_MODE_CLASS (fmode) != MODE_INT)
5929     return;
5930   if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5931     return;
5932   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5933 }
5934
5935 /* Same as gen_interclass_conv_libfunc but verify that we are producing
5936    fp->int conversion with no decimal floating point involved.  */
5937
5938 static void
5939 gen_fp_to_int_conv_libfunc (convert_optab tab,
5940                             const char *opname,
5941                             enum machine_mode tmode,
5942                             enum machine_mode fmode)
5943 {
5944   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5945     return;
5946   if (GET_MODE_CLASS (tmode) != MODE_INT)
5947     return;
5948   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5949 }
5950
5951 /* Initialize the libfunc fiels of an of an intra-mode-class conversion optab.
5952    The string formation rules are
5953    similar to the ones for init_libfunc, above.  */
5954
5955 static void
5956 gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5957                              enum machine_mode tmode, enum machine_mode fmode)
5958 {
5959   size_t opname_len = strlen (opname);
5960   size_t mname_len = 0;
5961
5962   const char *fname, *tname;
5963   const char *q;
5964   char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5965   char *libfunc_name, *suffix;
5966   char *p;
5967
5968   /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5969      depends on which underlying decimal floating point format is used.  */
5970   const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5971
5972   mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5973
5974   nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
5975   nondec_name[0] = '_';
5976   nondec_name[1] = '_';
5977   memcpy (&nondec_name[2], opname, opname_len);
5978   nondec_suffix = nondec_name + opname_len + 2;
5979
5980   dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
5981   dec_name[0] = '_';
5982   dec_name[1] = '_';
5983   memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5984   memcpy (&dec_name[2 + dec_len], opname, opname_len);
5985   dec_suffix = dec_name + dec_len + opname_len + 2;
5986
5987   fname = GET_MODE_NAME (fmode);
5988   tname = GET_MODE_NAME (tmode);
5989
5990   if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5991     {
5992       libfunc_name = dec_name;
5993       suffix = dec_suffix;
5994     }
5995   else
5996     {
5997       libfunc_name = nondec_name;
5998       suffix = nondec_suffix;
5999     }
6000
6001   p = suffix;
6002   for (q = fname; *q; p++, q++)
6003     *p = TOLOWER (*q);
6004   for (q = tname; *q; p++, q++)
6005     *p = TOLOWER (*q);
6006
6007   *p++ = '2';
6008   *p = '\0';
6009
6010   set_conv_libfunc (tab, tmode, fmode,
6011                     ggc_alloc_string (libfunc_name, p - libfunc_name));
6012 }
6013
6014 /* Pick proper libcall for trunc_optab.  We need to chose if we do
6015    truncation or extension and interclass or intraclass.  */
6016
6017 static void
6018 gen_trunc_conv_libfunc (convert_optab tab,
6019                          const char *opname,
6020                          enum machine_mode tmode,
6021                          enum machine_mode fmode)
6022 {
6023   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
6024     return;
6025   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
6026     return;
6027   if (tmode == fmode)
6028     return;
6029
6030   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
6031       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
6032      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6033   
6034   if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
6035     return;
6036
6037   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
6038        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
6039       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
6040     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6041 }
6042
6043 /* Pick proper libcall for extend_optab.  We need to chose if we do
6044    truncation or extension and interclass or intraclass.  */
6045
6046 static void
6047 gen_extend_conv_libfunc (convert_optab tab,
6048                          const char *opname ATTRIBUTE_UNUSED,
6049                          enum machine_mode tmode,
6050                          enum machine_mode fmode)
6051 {
6052   if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
6053     return;
6054   if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
6055     return;
6056   if (tmode == fmode)
6057     return;
6058
6059   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
6060       || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
6061      gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6062   
6063   if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
6064     return;
6065
6066   if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
6067        && GET_MODE_CLASS (fmode) == MODE_FLOAT)
6068       || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
6069     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6070 }
6071
6072 /* Pick proper libcall for fract_optab.  We need to chose if we do
6073    interclass or intraclass.  */
6074
6075 static void
6076 gen_fract_conv_libfunc (convert_optab tab,
6077                         const char *opname,
6078                         enum machine_mode tmode,
6079                         enum machine_mode fmode)
6080 {
6081   if (tmode == fmode)
6082     return;
6083   if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
6084     return;
6085
6086   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6087     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6088   else
6089     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6090 }
6091
6092 /* Pick proper libcall for fractuns_optab.  */
6093
6094 static void
6095 gen_fractuns_conv_libfunc (convert_optab tab,
6096                            const char *opname,
6097                            enum machine_mode tmode,
6098                            enum machine_mode fmode)
6099 {
6100   if (tmode == fmode)
6101     return;
6102   /* One mode must be a fixed-point mode, and the other must be an integer
6103      mode. */
6104   if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
6105         || (ALL_FIXED_POINT_MODE_P (fmode)
6106             && GET_MODE_CLASS (tmode) == MODE_INT)))
6107     return;
6108
6109   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6110 }
6111
6112 /* Pick proper libcall for satfract_optab.  We need to chose if we do
6113    interclass or intraclass.  */
6114
6115 static void
6116 gen_satfract_conv_libfunc (convert_optab tab,
6117                            const char *opname,
6118                            enum machine_mode tmode,
6119                            enum machine_mode fmode)
6120 {
6121   if (tmode == fmode)
6122     return;
6123   /* TMODE must be a fixed-point mode.  */
6124   if (!ALL_FIXED_POINT_MODE_P (tmode))
6125     return;
6126
6127   if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6128     gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6129   else
6130     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6131 }
6132
6133 /* Pick proper libcall for satfractuns_optab.  */
6134
6135 static void
6136 gen_satfractuns_conv_libfunc (convert_optab tab,
6137                               const char *opname,
6138                               enum machine_mode tmode,
6139                               enum machine_mode fmode)
6140 {
6141   if (tmode == fmode)
6142     return;
6143   /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6144   if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
6145     return;
6146
6147   gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6148 }
6149
6150 rtx
6151 init_one_libfunc (const char *name)
6152 {
6153   rtx symbol;
6154
6155   /* Create a FUNCTION_DECL that can be passed to
6156      targetm.encode_section_info.  */
6157   /* ??? We don't have any type information except for this is
6158      a function.  Pretend this is "int foo()".  */
6159   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
6160                           build_function_type (integer_type_node, NULL_TREE));
6161   DECL_ARTIFICIAL (decl) = 1;
6162   DECL_EXTERNAL (decl) = 1;
6163   TREE_PUBLIC (decl) = 1;
6164
6165   symbol = XEXP (DECL_RTL (decl), 0);
6166
6167   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
6168      are the flags assigned by targetm.encode_section_info.  */
6169   SET_SYMBOL_REF_DECL (symbol, 0);
6170
6171   return symbol;
6172 }
6173
6174 /* Call this to reset the function entry for one optab (OPTABLE) in mode
6175    MODE to NAME, which should be either 0 or a string constant.  */
6176 void
6177 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
6178 {
6179   rtx val;
6180   struct libfunc_entry e;
6181   struct libfunc_entry **slot;
6182   e.optab = (size_t) (optab_table[0] - optable);
6183   e.mode1 = mode;
6184   e.mode2 = VOIDmode;
6185
6186   if (name)
6187     val = init_one_libfunc (name);
6188   else
6189     val = 0;
6190   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6191   if (*slot == NULL)
6192     *slot = ggc_alloc (sizeof (struct libfunc_entry));
6193   (*slot)->optab = (size_t) (optab_table[0] - optable);
6194   (*slot)->mode1 = mode;
6195   (*slot)->mode2 = VOIDmode;
6196   (*slot)->libfunc = val;
6197 }
6198
6199 /* Call this to reset the function entry for one conversion optab
6200    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6201    either 0 or a string constant.  */
6202 void
6203 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
6204                   enum machine_mode fmode, const char *name)
6205 {
6206   rtx val;
6207   struct libfunc_entry e;
6208   struct libfunc_entry **slot;
6209   e.optab = (size_t) (convert_optab_table[0] - optable);
6210   e.mode1 = tmode;
6211   e.mode2 = fmode;
6212
6213   if (name)
6214     val = init_one_libfunc (name);
6215   else
6216     val = 0;
6217   slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6218   if (*slot == NULL)
6219     *slot = ggc_alloc (sizeof (struct libfunc_entry));
6220   (*slot)->optab = (size_t) (convert_optab_table[0] - optable);
6221   (*slot)->mode1 = tmode;
6222   (*slot)->mode2 = fmode;
6223   (*slot)->libfunc = val;
6224 }
6225
6226 /* Call this to initialize the contents of the optabs
6227    appropriately for the current target machine.  */
6228
6229 void
6230 init_optabs (void)
6231 {
6232   unsigned int i;
6233   enum machine_mode int_mode;
6234
6235   libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
6236   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
6237
6238   for (i = 0; i < NUM_RTX_CODE; i++)
6239     setcc_gen_code[i] = CODE_FOR_nothing;
6240
6241 #ifdef HAVE_conditional_move
6242   for (i = 0; i < NUM_MACHINE_MODES; i++)
6243     movcc_gen_code[i] = CODE_FOR_nothing;
6244 #endif
6245
6246   for (i = 0; i < NUM_MACHINE_MODES; i++)
6247     {
6248       vcond_gen_code[i] = CODE_FOR_nothing;
6249       vcondu_gen_code[i] = CODE_FOR_nothing;
6250     }
6251
6252   add_optab = init_optab (PLUS);
6253   addv_optab = init_optabv (PLUS);
6254   sub_optab = init_optab (MINUS);
6255   subv_optab = init_optabv (MINUS);
6256   ssadd_optab = init_optab (SS_PLUS);
6257   usadd_optab = init_optab (US_PLUS);
6258   sssub_optab = init_optab (SS_MINUS);
6259   ussub_optab = init_optab (US_MINUS);
6260   smul_optab = init_optab (MULT);
6261   ssmul_optab = init_optab (SS_MULT);
6262   usmul_optab = init_optab (US_MULT);
6263   smulv_optab = init_optabv (MULT);
6264   smul_highpart_optab = init_optab (UNKNOWN);
6265   umul_highpart_optab = init_optab (UNKNOWN);
6266   smul_widen_optab = init_optab (UNKNOWN);
6267   umul_widen_optab = init_optab (UNKNOWN);
6268   usmul_widen_optab = init_optab (UNKNOWN);
6269   smadd_widen_optab = init_optab (UNKNOWN);
6270   umadd_widen_optab = init_optab (UNKNOWN);
6271   ssmadd_widen_optab = init_optab (UNKNOWN);
6272   usmadd_widen_optab = init_optab (UNKNOWN);
6273   smsub_widen_optab = init_optab (UNKNOWN);
6274   umsub_widen_optab = init_optab (UNKNOWN);
6275   ssmsub_widen_optab = init_optab (UNKNOWN);
6276   usmsub_widen_optab = init_optab (UNKNOWN);
6277   sdiv_optab = init_optab (DIV);
6278   ssdiv_optab = init_optab (SS_DIV);
6279   usdiv_optab = init_optab (US_DIV);
6280   sdivv_optab = init_optabv (DIV);
6281   sdivmod_optab = init_optab (UNKNOWN);
6282   udiv_optab = init_optab (UDIV);
6283   udivmod_optab = init_optab (UNKNOWN);
6284   smod_optab = init_optab (MOD);
6285   umod_optab = init_optab (UMOD);
6286   fmod_optab = init_optab (UNKNOWN);
6287   remainder_optab = init_optab (UNKNOWN);
6288   ftrunc_optab = init_optab (UNKNOWN);
6289   and_optab = init_optab (AND);
6290   ior_optab = init_optab (IOR);
6291   xor_optab = init_optab (XOR);
6292   ashl_optab = init_optab (ASHIFT);
6293   ssashl_optab = init_optab (SS_ASHIFT);
6294   usashl_optab = init_optab (US_ASHIFT);
6295   ashr_optab = init_optab (ASHIFTRT);
6296   lshr_optab = init_optab (LSHIFTRT);
6297   rotl_optab = init_optab (ROTATE);
6298   rotr_optab = init_optab (ROTATERT);
6299   smin_optab = init_optab (SMIN);
6300   smax_optab = init_optab (SMAX);
6301   umin_optab = init_optab (UMIN);
6302   umax_optab = init_optab (UMAX);
6303   pow_optab = init_optab (UNKNOWN);
6304   atan2_optab = init_optab (UNKNOWN);
6305
6306   /* These three have codes assigned exclusively for the sake of
6307      have_insn_for.  */
6308   mov_optab = init_optab (SET);
6309   movstrict_optab = init_optab (STRICT_LOW_PART);
6310   cmp_optab = init_optab (COMPARE);
6311
6312   storent_optab = init_optab (UNKNOWN);
6313
6314   ucmp_optab = init_optab (UNKNOWN);
6315   tst_optab = init_optab (UNKNOWN);
6316
6317   eq_optab = init_optab (EQ);
6318   ne_optab = init_optab (NE);
6319   gt_optab = init_optab (GT);
6320   ge_optab = init_optab (GE);
6321   lt_optab = init_optab (LT);
6322   le_optab = init_optab (LE);
6323   unord_optab = init_optab (UNORDERED);
6324
6325   neg_optab = init_optab (NEG);
6326   ssneg_optab = init_optab (SS_NEG);
6327   usneg_optab = init_optab (US_NEG);
6328   negv_optab = init_optabv (NEG);
6329   abs_optab = init_optab (ABS);
6330   absv_optab = init_optabv (ABS);
6331   addcc_optab = init_optab (UNKNOWN);
6332   one_cmpl_optab = init_optab (NOT);
6333   bswap_optab = init_optab (BSWAP);
6334   ffs_optab = init_optab (FFS);
6335   clz_optab = init_optab (CLZ);
6336   ctz_optab = init_optab (CTZ);
6337   popcount_optab = init_optab (POPCOUNT);
6338   parity_optab = init_optab (PARITY);
6339   sqrt_optab = init_optab (SQRT);
6340   floor_optab = init_optab (UNKNOWN);
6341   ceil_optab = init_optab (UNKNOWN);
6342   round_optab = init_optab (UNKNOWN);
6343   btrunc_optab = init_optab (UNKNOWN);
6344   nearbyint_optab = init_optab (UNKNOWN);
6345   rint_optab = init_optab (UNKNOWN);
6346   sincos_optab = init_optab (UNKNOWN);
6347   sin_optab = init_optab (UNKNOWN);
6348   asin_optab = init_optab (UNKNOWN);
6349   cos_optab = init_optab (UNKNOWN);
6350   acos_optab = init_optab (UNKNOWN);
6351   exp_optab = init_optab (UNKNOWN);
6352   exp10_optab = init_optab (UNKNOWN);
6353   exp2_optab = init_optab (UNKNOWN);
6354   expm1_optab = init_optab (UNKNOWN);
6355   ldexp_optab = init_optab (UNKNOWN);
6356   scalb_optab = init_optab (UNKNOWN);
6357   logb_optab = init_optab (UNKNOWN);
6358   ilogb_optab = init_optab (UNKNOWN);
6359   log_optab = init_optab (UNKNOWN);
6360   log10_optab = init_optab (UNKNOWN);
6361   log2_optab = init_optab (UNKNOWN);
6362   log1p_optab = init_optab (UNKNOWN);
6363   tan_optab = init_optab (UNKNOWN);
6364   atan_optab = init_optab (UNKNOWN);
6365   copysign_optab = init_optab (UNKNOWN);
6366   signbit_optab = init_optab (UNKNOWN);
6367
6368   isinf_optab = init_optab (UNKNOWN);
6369
6370   strlen_optab = init_optab (UNKNOWN);
6371   cbranch_optab = init_optab (UNKNOWN);
6372   cmov_optab = init_optab (UNKNOWN);
6373   cstore_optab = init_optab (UNKNOWN);
6374   push_optab = init_optab (UNKNOWN);
6375
6376   reduc_smax_optab = init_optab (UNKNOWN);
6377   reduc_umax_optab = init_optab (UNKNOWN);
6378   reduc_smin_optab = init_optab (UNKNOWN);
6379   reduc_umin_optab = init_optab (UNKNOWN);
6380   reduc_splus_optab = init_optab (UNKNOWN);
6381   reduc_uplus_optab = init_optab (UNKNOWN);
6382
6383   ssum_widen_optab = init_optab (UNKNOWN);
6384   usum_widen_optab = init_optab (UNKNOWN);
6385   sdot_prod_optab = init_optab (UNKNOWN); 
6386   udot_prod_optab = init_optab (UNKNOWN);
6387
6388   vec_extract_optab = init_optab (UNKNOWN);
6389   vec_extract_even_optab = init_optab (UNKNOWN);
6390   vec_extract_odd_optab = init_optab (UNKNOWN);
6391   vec_interleave_high_optab = init_optab (UNKNOWN);
6392   vec_interleave_low_optab = init_optab (UNKNOWN);
6393   vec_set_optab = init_optab (UNKNOWN);
6394   vec_init_optab = init_optab (UNKNOWN);
6395   vec_shl_optab = init_optab (UNKNOWN);
6396   vec_shr_optab = init_optab (UNKNOWN);
6397   vec_realign_load_optab = init_optab (UNKNOWN);
6398   movmisalign_optab = init_optab (UNKNOWN);
6399   vec_widen_umult_hi_optab = init_optab (UNKNOWN);
6400   vec_widen_umult_lo_optab = init_optab (UNKNOWN);
6401   vec_widen_smult_hi_optab = init_optab (UNKNOWN);
6402   vec_widen_smult_lo_optab = init_optab (UNKNOWN);
6403   vec_unpacks_hi_optab = init_optab (UNKNOWN);
6404   vec_unpacks_lo_optab = init_optab (UNKNOWN);
6405   vec_unpacku_hi_optab = init_optab (UNKNOWN);
6406   vec_unpacku_lo_optab = init_optab (UNKNOWN);
6407   vec_unpacks_float_hi_optab = init_optab (UNKNOWN);
6408   vec_unpacks_float_lo_optab = init_optab (UNKNOWN);
6409   vec_unpacku_float_hi_optab = init_optab (UNKNOWN);
6410   vec_unpacku_float_lo_optab = init_optab (UNKNOWN);
6411   vec_pack_trunc_optab = init_optab (UNKNOWN);
6412   vec_pack_usat_optab = init_optab (UNKNOWN);
6413   vec_pack_ssat_optab = init_optab (UNKNOWN);
6414   vec_pack_ufix_trunc_optab = init_optab (UNKNOWN);
6415   vec_pack_sfix_trunc_optab = init_optab (UNKNOWN);
6416
6417   powi_optab = init_optab (UNKNOWN);
6418
6419   /* Conversions.  */
6420   sext_optab = init_convert_optab (SIGN_EXTEND);
6421   zext_optab = init_convert_optab (ZERO_EXTEND);
6422   trunc_optab = init_convert_optab (TRUNCATE);
6423   sfix_optab = init_convert_optab (FIX);
6424   ufix_optab = init_convert_optab (UNSIGNED_FIX);
6425   sfixtrunc_optab = init_convert_optab (UNKNOWN);
6426   ufixtrunc_optab = init_convert_optab (UNKNOWN);
6427   sfloat_optab = init_convert_optab (FLOAT);
6428   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
6429   lrint_optab = init_convert_optab (UNKNOWN);
6430   lround_optab = init_convert_optab (UNKNOWN);
6431   lfloor_optab = init_convert_optab (UNKNOWN);
6432   lceil_optab = init_convert_optab (UNKNOWN);
6433
6434   fract_optab = init_convert_optab (FRACT_CONVERT);
6435   fractuns_optab = init_convert_optab (UNSIGNED_FRACT_CONVERT);
6436   satfract_optab = init_convert_optab (SAT_FRACT);
6437   satfractuns_optab = init_convert_optab (UNSIGNED_SAT_FRACT);
6438
6439   for (i = 0; i < NUM_MACHINE_MODES; i++)
6440     {
6441       movmem_optab[i] = CODE_FOR_nothing;
6442       cmpstr_optab[i] = CODE_FOR_nothing;
6443       cmpstrn_optab[i] = CODE_FOR_nothing;
6444       cmpmem_optab[i] = CODE_FOR_nothing;
6445       setmem_optab[i] = CODE_FOR_nothing;
6446
6447       sync_add_optab[i] = CODE_FOR_nothing;
6448       sync_sub_optab[i] = CODE_FOR_nothing;
6449       sync_ior_optab[i] = CODE_FOR_nothing;
6450       sync_and_optab[i] = CODE_FOR_nothing;
6451       sync_xor_optab[i] = CODE_FOR_nothing;
6452       sync_nand_optab[i] = CODE_FOR_nothing;
6453       sync_old_add_optab[i] = CODE_FOR_nothing;
6454       sync_old_sub_optab[i] = CODE_FOR_nothing;
6455       sync_old_ior_optab[i] = CODE_FOR_nothing;
6456       sync_old_and_optab[i] = CODE_FOR_nothing;
6457       sync_old_xor_optab[i] = CODE_FOR_nothing;
6458       sync_old_nand_optab[i] = CODE_FOR_nothing;
6459       sync_new_add_optab[i] = CODE_FOR_nothing;
6460       sync_new_sub_optab[i] = CODE_FOR_nothing;
6461       sync_new_ior_optab[i] = CODE_FOR_nothing;
6462       sync_new_and_optab[i] = CODE_FOR_nothing;
6463       sync_new_xor_optab[i] = CODE_FOR_nothing;
6464       sync_new_nand_optab[i] = CODE_FOR_nothing;
6465       sync_compare_and_swap[i] = CODE_FOR_nothing;
6466       sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
6467       sync_lock_test_and_set[i] = CODE_FOR_nothing;
6468       sync_lock_release[i] = CODE_FOR_nothing;
6469
6470       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
6471     }
6472
6473   /* Fill in the optabs with the insns we support.  */
6474   init_all_optabs ();
6475
6476   /* Initialize the optabs with the names of the library functions.  */
6477   add_optab->libcall_basename = "add";
6478   add_optab->libcall_suffix = '3';
6479   add_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6480   addv_optab->libcall_basename = "add";
6481   addv_optab->libcall_suffix = '3';
6482   addv_optab->libcall_gen = gen_intv_fp_libfunc;
6483   ssadd_optab->libcall_basename = "ssadd";
6484   ssadd_optab->libcall_suffix = '3';
6485   ssadd_optab->libcall_gen = gen_signed_fixed_libfunc;
6486   usadd_optab->libcall_basename = "usadd";
6487   usadd_optab->libcall_suffix = '3';
6488   usadd_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6489   sub_optab->libcall_basename = "sub";
6490   sub_optab->libcall_suffix = '3';
6491   sub_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6492   subv_optab->libcall_basename = "sub";
6493   subv_optab->libcall_suffix = '3';
6494   subv_optab->libcall_gen = gen_intv_fp_libfunc;
6495   sssub_optab->libcall_basename = "sssub";
6496   sssub_optab->libcall_suffix = '3';
6497   sssub_optab->libcall_gen = gen_signed_fixed_libfunc;
6498   ussub_optab->libcall_basename = "ussub";
6499   ussub_optab->libcall_suffix = '3';
6500   ussub_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6501   smul_optab->libcall_basename = "mul";
6502   smul_optab->libcall_suffix = '3';
6503   smul_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6504   smulv_optab->libcall_basename = "mul";
6505   smulv_optab->libcall_suffix = '3';
6506   smulv_optab->libcall_gen = gen_intv_fp_libfunc;
6507   ssmul_optab->libcall_basename = "ssmul";
6508   ssmul_optab->libcall_suffix = '3';
6509   ssmul_optab->libcall_gen = gen_signed_fixed_libfunc;
6510   usmul_optab->libcall_basename = "usmul";
6511   usmul_optab->libcall_suffix = '3';
6512   usmul_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6513   sdiv_optab->libcall_basename = "div";
6514   sdiv_optab->libcall_suffix = '3';
6515   sdiv_optab->libcall_gen = gen_int_fp_signed_fixed_libfunc;
6516   sdivv_optab->libcall_basename = "divv";
6517   sdivv_optab->libcall_suffix = '3';
6518   sdivv_optab->libcall_gen = gen_int_libfunc;
6519   ssdiv_optab->libcall_basename = "ssdiv";
6520   ssdiv_optab->libcall_suffix = '3';
6521   ssdiv_optab->libcall_gen = gen_signed_fixed_libfunc;
6522   udiv_optab->libcall_basename = "udiv";
6523   udiv_optab->libcall_suffix = '3';
6524   udiv_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6525   usdiv_optab->libcall_basename = "usdiv";
6526   usdiv_optab->libcall_suffix = '3';
6527   usdiv_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6528   sdivmod_optab->libcall_basename = "divmod";
6529   sdivmod_optab->libcall_suffix = '4';
6530   sdivmod_optab->libcall_gen = gen_int_libfunc;
6531   udivmod_optab->libcall_basename = "udivmod";
6532   udivmod_optab->libcall_suffix = '4';
6533   udivmod_optab->libcall_gen = gen_int_libfunc;
6534   smod_optab->libcall_basename = "mod";
6535   smod_optab->libcall_suffix = '3';
6536   smod_optab->libcall_gen = gen_int_libfunc;
6537   umod_optab->libcall_basename = "umod";
6538   umod_optab->libcall_suffix = '3';
6539   umod_optab->libcall_gen = gen_int_libfunc;
6540   ftrunc_optab->libcall_basename = "ftrunc";
6541   ftrunc_optab->libcall_suffix = '2';
6542   ftrunc_optab->libcall_gen = gen_fp_libfunc;
6543   and_optab->libcall_basename = "and";
6544   and_optab->libcall_suffix = '3';
6545   and_optab->libcall_gen = gen_int_libfunc;
6546   ior_optab->libcall_basename = "ior";
6547   ior_optab->libcall_suffix = '3';
6548   ior_optab->libcall_gen = gen_int_libfunc;
6549   xor_optab->libcall_basename = "xor";
6550   xor_optab->libcall_suffix = '3';
6551   xor_optab->libcall_gen = gen_int_libfunc;
6552   ashl_optab->libcall_basename = "ashl";
6553   ashl_optab->libcall_suffix = '3';
6554   ashl_optab->libcall_gen = gen_int_fixed_libfunc;
6555   ssashl_optab->libcall_basename = "ssashl";
6556   ssashl_optab->libcall_suffix = '3';
6557   ssashl_optab->libcall_gen = gen_signed_fixed_libfunc;
6558   usashl_optab->libcall_basename = "usashl";
6559   usashl_optab->libcall_suffix = '3';
6560   usashl_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6561   ashr_optab->libcall_basename = "ashr";
6562   ashr_optab->libcall_suffix = '3';
6563   ashr_optab->libcall_gen = gen_int_signed_fixed_libfunc;
6564   lshr_optab->libcall_basename = "lshr";
6565   lshr_optab->libcall_suffix = '3';
6566   lshr_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6567   smin_optab->libcall_basename = "min";
6568   smin_optab->libcall_suffix = '3';
6569   smin_optab->libcall_gen = gen_int_fp_libfunc;
6570   smax_optab->libcall_basename = "max";
6571   smax_optab->libcall_suffix = '3';
6572   smax_optab->libcall_gen = gen_int_fp_libfunc;
6573   umin_optab->libcall_basename = "umin";
6574   umin_optab->libcall_suffix = '3';
6575   umin_optab->libcall_gen = gen_int_libfunc;
6576   umax_optab->libcall_basename = "umax";
6577   umax_optab->libcall_suffix = '3';
6578   umax_optab->libcall_gen = gen_int_libfunc;
6579   neg_optab->libcall_basename = "neg";
6580   neg_optab->libcall_suffix = '2';
6581   neg_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6582   ssneg_optab->libcall_basename = "ssneg";
6583   ssneg_optab->libcall_suffix = '2';
6584   ssneg_optab->libcall_gen = gen_signed_fixed_libfunc;
6585   usneg_optab->libcall_basename = "usneg";
6586   usneg_optab->libcall_suffix = '2';
6587   usneg_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6588   negv_optab->libcall_basename = "neg";
6589   negv_optab->libcall_suffix = '2';
6590   negv_optab->libcall_gen = gen_intv_fp_libfunc;
6591   one_cmpl_optab->libcall_basename = "one_cmpl";
6592   one_cmpl_optab->libcall_suffix = '2';
6593   one_cmpl_optab->libcall_gen = gen_int_libfunc;
6594   ffs_optab->libcall_basename = "ffs";
6595   ffs_optab->libcall_suffix = '2';
6596   ffs_optab->libcall_gen = gen_int_libfunc;
6597   clz_optab->libcall_basename = "clz";
6598   clz_optab->libcall_suffix = '2';
6599   clz_optab->libcall_gen = gen_int_libfunc;
6600   ctz_optab->libcall_basename = "ctz";
6601   ctz_optab->libcall_suffix = '2';
6602   ctz_optab->libcall_gen = gen_int_libfunc;
6603   popcount_optab->libcall_basename = "popcount";
6604   popcount_optab->libcall_suffix = '2';
6605   popcount_optab->libcall_gen = gen_int_libfunc;
6606   parity_optab->libcall_basename = "parity";
6607   parity_optab->libcall_suffix = '2';
6608   parity_optab->libcall_gen = gen_int_libfunc;
6609
6610   /* Comparison libcalls for integers MUST come in pairs,
6611      signed/unsigned.  */
6612   cmp_optab->libcall_basename = "cmp";
6613   cmp_optab->libcall_suffix = '2';
6614   cmp_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6615   ucmp_optab->libcall_basename = "ucmp";
6616   ucmp_optab->libcall_suffix = '2';
6617   ucmp_optab->libcall_gen = gen_int_libfunc;
6618
6619   /* EQ etc are floating point only.  */
6620   eq_optab->libcall_basename = "eq";
6621   eq_optab->libcall_suffix = '2';
6622   eq_optab->libcall_gen = gen_fp_libfunc;
6623   ne_optab->libcall_basename = "ne";
6624   ne_optab->libcall_suffix = '2';
6625   ne_optab->libcall_gen = gen_fp_libfunc;
6626   gt_optab->libcall_basename = "gt";
6627   gt_optab->libcall_suffix = '2';
6628   gt_optab->libcall_gen = gen_fp_libfunc;
6629   ge_optab->libcall_basename = "ge";
6630   ge_optab->libcall_suffix = '2';
6631   ge_optab->libcall_gen = gen_fp_libfunc;
6632   lt_optab->libcall_basename = "lt";
6633   lt_optab->libcall_suffix = '2';
6634   lt_optab->libcall_gen = gen_fp_libfunc;
6635   le_optab->libcall_basename = "le";
6636   le_optab->libcall_suffix = '2';
6637   le_optab->libcall_gen = gen_fp_libfunc;
6638   unord_optab->libcall_basename = "unord";
6639   unord_optab->libcall_suffix = '2';
6640   unord_optab->libcall_gen = gen_fp_libfunc;
6641
6642   powi_optab->libcall_basename = "powi";
6643   powi_optab->libcall_suffix = '2';
6644   powi_optab->libcall_gen = gen_fp_libfunc;
6645
6646   /* Conversions.  */
6647   sfloat_optab->libcall_basename = "float";
6648   sfloat_optab->libcall_gen = gen_int_to_fp_conv_libfunc;
6649   ufloat_optab->libcall_gen = gen_ufloat_conv_libfunc;
6650   sfix_optab->libcall_basename = "fix";
6651   sfix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6652   ufix_optab->libcall_basename = "fixuns";
6653   ufix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6654   lrint_optab->libcall_basename = "lrint";
6655   lrint_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6656   lround_optab->libcall_basename = "lround";
6657   lround_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6658   lfloor_optab->libcall_basename = "lfloor";
6659   lfloor_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6660   lceil_optab->libcall_basename = "lceil";
6661   lceil_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6662
6663   /* trunc_optab is also used for FLOAT_EXTEND.  */
6664   sext_optab->libcall_basename = "extend";
6665   sext_optab->libcall_gen = gen_extend_conv_libfunc;
6666   trunc_optab->libcall_basename = "trunc";
6667   trunc_optab->libcall_gen = gen_trunc_conv_libfunc;
6668
6669   /* Conversions for fixed-point modes and other modes.  */
6670   fract_optab->libcall_basename = "fract";
6671   fract_optab->libcall_gen = gen_fract_conv_libfunc;
6672   satfract_optab->libcall_basename = "satfract";
6673   satfract_optab->libcall_gen = gen_satfract_conv_libfunc;
6674   fractuns_optab->libcall_basename = "fractuns";
6675   fractuns_optab->libcall_gen = gen_fractuns_conv_libfunc;
6676   satfractuns_optab->libcall_basename = "satfractuns";
6677   satfractuns_optab->libcall_gen = gen_satfractuns_conv_libfunc;
6678
6679   /* The ffs function operates on `int'.  Fall back on it if we do not
6680      have a libgcc2 function for that width.  */
6681   if (INT_TYPE_SIZE < BITS_PER_WORD)
6682     {
6683       int_mode = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
6684       set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6685                          "ffs");
6686     }
6687
6688   /* Explicitly initialize the bswap libfuncs since we need them to be
6689      valid for things other than word_mode.  */
6690   set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6691   set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6692
6693   /* Use cabs for double complex abs, since systems generally have cabs.
6694      Don't define any libcall for float complex, so that cabs will be used.  */
6695   if (complex_double_type_node)
6696     set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), "cabs");
6697
6698   abort_libfunc = init_one_libfunc ("abort");
6699   memcpy_libfunc = init_one_libfunc ("memcpy");
6700   memmove_libfunc = init_one_libfunc ("memmove");
6701   memcmp_libfunc = init_one_libfunc ("memcmp");
6702   memset_libfunc = init_one_libfunc ("memset");
6703   setbits_libfunc = init_one_libfunc ("__setbits");
6704
6705 #ifndef DONT_USE_BUILTIN_SETJMP
6706   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6707   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6708 #else
6709   setjmp_libfunc = init_one_libfunc ("setjmp");
6710   longjmp_libfunc = init_one_libfunc ("longjmp");
6711 #endif
6712   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6713   unwind_sjlj_unregister_libfunc
6714     = init_one_libfunc ("_Unwind_SjLj_Unregister");
6715
6716   /* For function entry/exit instrumentation.  */
6717   profile_function_entry_libfunc
6718     = init_one_libfunc ("__cyg_profile_func_enter");
6719   profile_function_exit_libfunc
6720     = init_one_libfunc ("__cyg_profile_func_exit");
6721
6722   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6723
6724   if (HAVE_conditional_trap)
6725     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
6726
6727   /* Allow the target to add more libcalls or rename some, etc.  */
6728   targetm.init_libfuncs ();
6729 }
6730
6731 /* Print information about the current contents of the optabs on
6732    STDERR.  */
6733
6734 void
6735 debug_optab_libfuncs (void)
6736 {
6737   int i;
6738   int j;
6739   int k;
6740
6741   /* Dump the arithmetic optabs.  */
6742   for (i = 0; i != (int) OTI_MAX; i++)
6743     for (j = 0; j < NUM_MACHINE_MODES; ++j)
6744       {
6745         optab o;
6746         rtx l;
6747
6748         o = optab_table[i];
6749         l = optab_libfunc (optab_table[i], j);
6750         if (l)
6751           {
6752             gcc_assert (GET_CODE (l) == SYMBOL_REF);
6753             fprintf (stderr, "%s\t%s:\t%s\n",
6754                      GET_RTX_NAME (o->code),
6755                      GET_MODE_NAME (j),
6756                      XSTR (l, 0));
6757           }
6758       }
6759
6760   /* Dump the conversion optabs.  */
6761   for (i = 0; i < (int) COI_MAX; ++i)
6762     for (j = 0; j < NUM_MACHINE_MODES; ++j)
6763       for (k = 0; k < NUM_MACHINE_MODES; ++k)
6764         {
6765           convert_optab o;
6766           rtx l;
6767
6768           o = convert_optab_table[i];
6769           l = convert_optab_libfunc (o, j, k);
6770           if (l)
6771             {
6772               gcc_assert (GET_CODE (l) == SYMBOL_REF);
6773               fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6774                        GET_RTX_NAME (o->code),
6775                        GET_MODE_NAME (j),
6776                        GET_MODE_NAME (k),
6777                        XSTR (l, 0));
6778             }
6779         }
6780 }
6781
6782 \f
6783 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6784    CODE.  Return 0 on failure.  */
6785
6786 rtx
6787 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
6788                rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
6789 {
6790   enum machine_mode mode = GET_MODE (op1);
6791   enum insn_code icode;
6792   rtx insn;
6793
6794   if (!HAVE_conditional_trap)
6795     return 0;
6796
6797   if (mode == VOIDmode)
6798     return 0;
6799
6800   icode = optab_handler (cmp_optab, mode)->insn_code;
6801   if (icode == CODE_FOR_nothing)
6802     return 0;
6803
6804   start_sequence ();
6805   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
6806   op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
6807   if (!op1 || !op2)
6808     {
6809       end_sequence ();
6810       return 0;
6811     }
6812   emit_insn (GEN_FCN (icode) (op1, op2));
6813
6814   PUT_CODE (trap_rtx, code);
6815   gcc_assert (HAVE_conditional_trap);
6816   insn = gen_conditional_trap (trap_rtx, tcode);
6817   if (insn)
6818     {
6819       emit_insn (insn);
6820       insn = get_insns ();
6821     }
6822   end_sequence ();
6823
6824   return insn;
6825 }
6826
6827 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6828    or unsigned operation code.  */
6829
6830 static enum rtx_code
6831 get_rtx_code (enum tree_code tcode, bool unsignedp)
6832 {
6833   enum rtx_code code;
6834   switch (tcode)
6835     {
6836     case EQ_EXPR:
6837       code = EQ;
6838       break;
6839     case NE_EXPR:
6840       code = NE;
6841       break;
6842     case LT_EXPR:
6843       code = unsignedp ? LTU : LT;
6844       break;
6845     case LE_EXPR:
6846       code = unsignedp ? LEU : LE;
6847       break;
6848     case GT_EXPR:
6849       code = unsignedp ? GTU : GT;
6850       break;
6851     case GE_EXPR:
6852       code = unsignedp ? GEU : GE;
6853       break;
6854
6855     case UNORDERED_EXPR:
6856       code = UNORDERED;
6857       break;
6858     case ORDERED_EXPR:
6859       code = ORDERED;
6860       break;
6861     case UNLT_EXPR:
6862       code = UNLT;
6863       break;
6864     case UNLE_EXPR:
6865       code = UNLE;
6866       break;
6867     case UNGT_EXPR:
6868       code = UNGT;
6869       break;
6870     case UNGE_EXPR:
6871       code = UNGE;
6872       break;
6873     case UNEQ_EXPR:
6874       code = UNEQ;
6875       break;
6876     case LTGT_EXPR:
6877       code = LTGT;
6878       break;
6879
6880     default:
6881       gcc_unreachable ();
6882     }
6883   return code;
6884 }
6885
6886 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6887    unsigned operators. Do not generate compare instruction.  */
6888
6889 static rtx
6890 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6891 {
6892   enum rtx_code rcode;
6893   tree t_op0, t_op1;
6894   rtx rtx_op0, rtx_op1;
6895
6896   /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6897      ensures that condition is a relational operation.  */
6898   gcc_assert (COMPARISON_CLASS_P (cond));
6899
6900   rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6901   t_op0 = TREE_OPERAND (cond, 0);
6902   t_op1 = TREE_OPERAND (cond, 1);
6903
6904   /* Expand operands.  */
6905   rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6906                          EXPAND_STACK_PARM);
6907   rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6908                          EXPAND_STACK_PARM);
6909
6910   if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
6911       && GET_MODE (rtx_op0) != VOIDmode)
6912     rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
6913
6914   if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
6915       && GET_MODE (rtx_op1) != VOIDmode)
6916     rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
6917
6918   return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
6919 }
6920
6921 /* Return insn code for VEC_COND_EXPR EXPR.  */
6922
6923 static inline enum insn_code
6924 get_vcond_icode (tree expr, enum machine_mode mode)
6925 {
6926   enum insn_code icode = CODE_FOR_nothing;
6927
6928   if (TYPE_UNSIGNED (TREE_TYPE (expr)))
6929     icode = vcondu_gen_code[mode];
6930   else
6931     icode = vcond_gen_code[mode];
6932   return icode;
6933 }
6934
6935 /* Return TRUE iff, appropriate vector insns are available
6936    for vector cond expr expr in VMODE mode.  */
6937
6938 bool
6939 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
6940 {
6941   if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
6942     return false;
6943   return true;
6944 }
6945
6946 /* Generate insns for VEC_COND_EXPR.  */
6947
6948 rtx
6949 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
6950 {
6951   enum insn_code icode;
6952   rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
6953   enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
6954   bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
6955
6956   icode = get_vcond_icode (vec_cond_expr, mode);
6957   if (icode == CODE_FOR_nothing)
6958     return 0;
6959
6960   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6961     target = gen_reg_rtx (mode);
6962
6963   /* Get comparison rtx.  First expand both cond expr operands.  */
6964   comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
6965                                    unsignedp, icode);
6966   cc_op0 = XEXP (comparison, 0);
6967   cc_op1 = XEXP (comparison, 1);
6968   /* Expand both operands and force them in reg, if required.  */
6969   rtx_op1 = expand_normal (TREE_OPERAND (vec_cond_expr, 1));
6970   if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
6971       && mode != VOIDmode)
6972     rtx_op1 = force_reg (mode, rtx_op1);
6973
6974   rtx_op2 = expand_normal (TREE_OPERAND (vec_cond_expr, 2));
6975   if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
6976       && mode != VOIDmode)
6977     rtx_op2 = force_reg (mode, rtx_op2);
6978
6979   /* Emit instruction! */
6980   emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
6981                               comparison, cc_op0,  cc_op1));
6982
6983   return target;
6984 }
6985
6986 \f
6987 /* This is an internal subroutine of the other compare_and_swap expanders.
6988    MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6989    operation.  TARGET is an optional place to store the value result of
6990    the operation.  ICODE is the particular instruction to expand.  Return
6991    the result of the operation.  */
6992
6993 static rtx
6994 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6995                                rtx target, enum insn_code icode)
6996 {
6997   enum machine_mode mode = GET_MODE (mem);
6998   rtx insn;
6999
7000   if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7001     target = gen_reg_rtx (mode);
7002
7003   if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
7004     old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
7005   if (!insn_data[icode].operand[2].predicate (old_val, mode))
7006     old_val = force_reg (mode, old_val);
7007
7008   if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
7009     new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
7010   if (!insn_data[icode].operand[3].predicate (new_val, mode))
7011     new_val = force_reg (mode, new_val);
7012
7013   insn = GEN_FCN (icode) (target, mem, old_val, new_val);
7014   if (insn == NULL_RTX)
7015     return NULL_RTX;
7016   emit_insn (insn);
7017
7018   return target;
7019 }
7020
7021 /* Expand a compare-and-swap operation and return its value.  */
7022
7023 rtx
7024 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
7025 {
7026   enum machine_mode mode = GET_MODE (mem);
7027   enum insn_code icode = sync_compare_and_swap[mode];
7028
7029   if (icode == CODE_FOR_nothing)
7030     return NULL_RTX;
7031
7032   return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
7033 }
7034
7035 /* Expand a compare-and-swap operation and store true into the result if
7036    the operation was successful and false otherwise.  Return the result.
7037    Unlike other routines, TARGET is not optional.  */
7038
7039 rtx
7040 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
7041 {
7042   enum machine_mode mode = GET_MODE (mem);
7043   enum insn_code icode;
7044   rtx subtarget, label0, label1;
7045
7046   /* If the target supports a compare-and-swap pattern that simultaneously
7047      sets some flag for success, then use it.  Otherwise use the regular
7048      compare-and-swap and follow that immediately with a compare insn.  */
7049   icode = sync_compare_and_swap_cc[mode];
7050   switch (icode)
7051     {
7052     default:
7053       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
7054                                                  NULL_RTX, icode);
7055       if (subtarget != NULL_RTX)
7056         break;
7057
7058       /* FALLTHRU */
7059     case CODE_FOR_nothing:
7060       icode = sync_compare_and_swap[mode];
7061       if (icode == CODE_FOR_nothing)
7062         return NULL_RTX;
7063
7064       /* Ensure that if old_val == mem, that we're not comparing
7065          against an old value.  */
7066       if (MEM_P (old_val))
7067         old_val = force_reg (mode, old_val);
7068
7069       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
7070                                                  NULL_RTX, icode);
7071       if (subtarget == NULL_RTX)
7072         return NULL_RTX;
7073
7074       emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
7075     }
7076
7077   /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
7078      setcc instruction from the beginning.  We don't work too hard here,
7079      but it's nice to not be stupid about initial code gen either.  */
7080   if (STORE_FLAG_VALUE == 1)
7081     {
7082       icode = setcc_gen_code[EQ];
7083       if (icode != CODE_FOR_nothing)
7084         {
7085           enum machine_mode cmode = insn_data[icode].operand[0].mode;
7086           rtx insn;
7087
7088           subtarget = target;
7089           if (!insn_data[icode].operand[0].predicate (target, cmode))
7090             subtarget = gen_reg_rtx (cmode);
7091
7092           insn = GEN_FCN (icode) (subtarget);
7093           if (insn)
7094             {
7095               emit_insn (insn);
7096               if (GET_MODE (target) != GET_MODE (subtarget))
7097                 {
7098                   convert_move (target, subtarget, 1);
7099                   subtarget = target;
7100                 }
7101               return subtarget;
7102             }
7103         }
7104     }
7105
7106   /* Without an appropriate setcc instruction, use a set of branches to
7107      get 1 and 0 stored into target.  Presumably if the target has a
7108      STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt.  */
7109
7110   label0 = gen_label_rtx ();
7111   label1 = gen_label_rtx ();
7112
7113   emit_jump_insn (bcc_gen_fctn[EQ] (label0));
7114   emit_move_insn (target, const0_rtx);
7115   emit_jump_insn (gen_jump (label1));
7116   emit_barrier ();
7117   emit_label (label0);
7118   emit_move_insn (target, const1_rtx);
7119   emit_label (label1);
7120
7121   return target;
7122 }
7123
7124 /* This is a helper function for the other atomic operations.  This function
7125    emits a loop that contains SEQ that iterates until a compare-and-swap
7126    operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
7127    a set of instructions that takes a value from OLD_REG as an input and
7128    produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
7129    set to the current contents of MEM.  After SEQ, a compare-and-swap will
7130    attempt to update MEM with NEW_REG.  The function returns true when the
7131    loop was generated successfully.  */
7132
7133 static bool
7134 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
7135 {
7136   enum machine_mode mode = GET_MODE (mem);
7137   enum insn_code icode;
7138   rtx label, cmp_reg, subtarget;
7139
7140   /* The loop we want to generate looks like
7141
7142         cmp_reg = mem;
7143       label:
7144         old_reg = cmp_reg;
7145         seq;
7146         cmp_reg = compare-and-swap(mem, old_reg, new_reg)
7147         if (cmp_reg != old_reg)
7148           goto label;
7149
7150      Note that we only do the plain load from memory once.  Subsequent
7151      iterations use the value loaded by the compare-and-swap pattern.  */
7152
7153   label = gen_label_rtx ();
7154   cmp_reg = gen_reg_rtx (mode);
7155
7156   emit_move_insn (cmp_reg, mem);
7157   emit_label (label);
7158   emit_move_insn (old_reg, cmp_reg);
7159   if (seq)
7160     emit_insn (seq);
7161
7162   /* If the target supports a compare-and-swap pattern that simultaneously
7163      sets some flag for success, then use it.  Otherwise use the regular
7164      compare-and-swap and follow that immediately with a compare insn.  */
7165   icode = sync_compare_and_swap_cc[mode];
7166   switch (icode)
7167     {
7168     default:
7169       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
7170                                                  cmp_reg, icode);
7171       if (subtarget != NULL_RTX)
7172         {
7173           gcc_assert (subtarget == cmp_reg);
7174           break;
7175         }
7176
7177       /* FALLTHRU */
7178     case CODE_FOR_nothing:
7179       icode = sync_compare_and_swap[mode];
7180       if (icode == CODE_FOR_nothing)
7181         return false;
7182
7183       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
7184                                                  cmp_reg, icode);
7185       if (subtarget == NULL_RTX)
7186         return false;
7187       if (subtarget != cmp_reg)
7188         emit_move_insn (cmp_reg, subtarget);
7189
7190       emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
7191     }
7192
7193   /* ??? Mark this jump predicted not taken?  */
7194   emit_jump_insn (bcc_gen_fctn[NE] (label));
7195
7196   return true;
7197 }
7198
7199 /* This function generates the atomic operation MEM CODE= VAL.  In this
7200    case, we do not care about any resulting value.  Returns NULL if we
7201    cannot generate the operation.  */
7202
7203 rtx
7204 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
7205 {
7206   enum machine_mode mode = GET_MODE (mem);
7207   enum insn_code icode;
7208   rtx insn;
7209
7210   /* Look to see if the target supports the operation directly.  */
7211   switch (code)
7212     {
7213     case PLUS:
7214       icode = sync_add_optab[mode];
7215       break;
7216     case IOR:
7217       icode = sync_ior_optab[mode];
7218       break;
7219     case XOR:
7220       icode = sync_xor_optab[mode];
7221       break;
7222     case AND:
7223       icode = sync_and_optab[mode];
7224       break;
7225     case NOT:
7226       icode = sync_nand_optab[mode];
7227       break;
7228
7229     case MINUS:
7230       icode = sync_sub_optab[mode];
7231       if (icode == CODE_FOR_nothing || CONST_INT_P (val))
7232         {
7233           icode = sync_add_optab[mode];
7234           if (icode != CODE_FOR_nothing)
7235             {
7236               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7237               code = PLUS;
7238             }
7239         }
7240       break;
7241
7242     default:
7243       gcc_unreachable ();
7244     }
7245
7246   /* Generate the direct operation, if present.  */
7247   if (icode != CODE_FOR_nothing)
7248     {
7249       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7250         val = convert_modes (mode, GET_MODE (val), val, 1);
7251       if (!insn_data[icode].operand[1].predicate (val, mode))
7252         val = force_reg (mode, val);
7253
7254       insn = GEN_FCN (icode) (mem, val);
7255       if (insn)
7256         {
7257           emit_insn (insn);
7258           return const0_rtx;
7259         }
7260     }
7261
7262   /* Failing that, generate a compare-and-swap loop in which we perform the
7263      operation with normal arithmetic instructions.  */
7264   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7265     {
7266       rtx t0 = gen_reg_rtx (mode), t1;
7267
7268       start_sequence ();
7269
7270       t1 = t0;
7271       if (code == NOT)
7272         {
7273           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
7274           code = AND;
7275         }
7276       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7277                                 true, OPTAB_LIB_WIDEN);
7278
7279       insn = get_insns ();
7280       end_sequence ();
7281
7282       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7283         return const0_rtx;
7284     }
7285
7286   return NULL_RTX;
7287 }
7288
7289 /* This function generates the atomic operation MEM CODE= VAL.  In this
7290    case, we do care about the resulting value: if AFTER is true then
7291    return the value MEM holds after the operation, if AFTER is false
7292    then return the value MEM holds before the operation.  TARGET is an
7293    optional place for the result value to be stored.  */
7294
7295 rtx
7296 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
7297                              bool after, rtx target)
7298 {
7299   enum machine_mode mode = GET_MODE (mem);
7300   enum insn_code old_code, new_code, icode;
7301   bool compensate;
7302   rtx insn;
7303
7304   /* Look to see if the target supports the operation directly.  */
7305   switch (code)
7306     {
7307     case PLUS:
7308       old_code = sync_old_add_optab[mode];
7309       new_code = sync_new_add_optab[mode];
7310       break;
7311     case IOR:
7312       old_code = sync_old_ior_optab[mode];
7313       new_code = sync_new_ior_optab[mode];
7314       break;
7315     case XOR:
7316       old_code = sync_old_xor_optab[mode];
7317       new_code = sync_new_xor_optab[mode];
7318       break;
7319     case AND:
7320       old_code = sync_old_and_optab[mode];
7321       new_code = sync_new_and_optab[mode];
7322       break;
7323     case NOT:
7324       old_code = sync_old_nand_optab[mode];
7325       new_code = sync_new_nand_optab[mode];
7326       break;
7327
7328     case MINUS:
7329       old_code = sync_old_sub_optab[mode];
7330       new_code = sync_new_sub_optab[mode];
7331       if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
7332           || CONST_INT_P (val))
7333         {
7334           old_code = sync_old_add_optab[mode];
7335           new_code = sync_new_add_optab[mode];
7336           if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
7337             {
7338               val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7339               code = PLUS;
7340             }
7341         }
7342       break;
7343
7344     default:
7345       gcc_unreachable ();
7346     }
7347
7348   /* If the target does supports the proper new/old operation, great.  But
7349      if we only support the opposite old/new operation, check to see if we
7350      can compensate.  In the case in which the old value is supported, then
7351      we can always perform the operation again with normal arithmetic.  In
7352      the case in which the new value is supported, then we can only handle
7353      this in the case the operation is reversible.  */
7354   compensate = false;
7355   if (after)
7356     {
7357       icode = new_code;
7358       if (icode == CODE_FOR_nothing)
7359         {
7360           icode = old_code;
7361           if (icode != CODE_FOR_nothing)
7362             compensate = true;
7363         }
7364     }
7365   else
7366     {
7367       icode = old_code;
7368       if (icode == CODE_FOR_nothing
7369           && (code == PLUS || code == MINUS || code == XOR))
7370         {
7371           icode = new_code;
7372           if (icode != CODE_FOR_nothing)
7373             compensate = true;
7374         }
7375     }
7376
7377   /* If we found something supported, great.  */
7378   if (icode != CODE_FOR_nothing)
7379     {
7380       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7381         target = gen_reg_rtx (mode);
7382
7383       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7384         val = convert_modes (mode, GET_MODE (val), val, 1);
7385       if (!insn_data[icode].operand[2].predicate (val, mode))
7386         val = force_reg (mode, val);
7387
7388       insn = GEN_FCN (icode) (target, mem, val);
7389       if (insn)
7390         {
7391           emit_insn (insn);
7392
7393           /* If we need to compensate for using an operation with the
7394              wrong return value, do so now.  */
7395           if (compensate)
7396             {
7397               if (!after)
7398                 {
7399                   if (code == PLUS)
7400                     code = MINUS;
7401                   else if (code == MINUS)
7402                     code = PLUS;
7403                 }
7404
7405               if (code == NOT)
7406                 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
7407               target = expand_simple_binop (mode, code, target, val, NULL_RTX,
7408                                             true, OPTAB_LIB_WIDEN);
7409             }
7410
7411           return target;
7412         }
7413     }
7414
7415   /* Failing that, generate a compare-and-swap loop in which we perform the
7416      operation with normal arithmetic instructions.  */
7417   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7418     {
7419       rtx t0 = gen_reg_rtx (mode), t1;
7420
7421       if (!target || !register_operand (target, mode))
7422         target = gen_reg_rtx (mode);
7423
7424       start_sequence ();
7425
7426       if (!after)
7427         emit_move_insn (target, t0);
7428       t1 = t0;
7429       if (code == NOT)
7430         {
7431           t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
7432           code = AND;
7433         }
7434       t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7435                                 true, OPTAB_LIB_WIDEN);
7436       if (after)
7437         emit_move_insn (target, t1);
7438
7439       insn = get_insns ();
7440       end_sequence ();
7441
7442       if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7443         return target;
7444     }
7445
7446   return NULL_RTX;
7447 }
7448
7449 /* This function expands a test-and-set operation.  Ideally we atomically
7450    store VAL in MEM and return the previous value in MEM.  Some targets
7451    may not support this operation and only support VAL with the constant 1;
7452    in this case while the return value will be 0/1, but the exact value
7453    stored in MEM is target defined.  TARGET is an option place to stick
7454    the return value.  */
7455
7456 rtx
7457 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
7458 {
7459   enum machine_mode mode = GET_MODE (mem);
7460   enum insn_code icode;
7461   rtx insn;
7462
7463   /* If the target supports the test-and-set directly, great.  */
7464   icode = sync_lock_test_and_set[mode];
7465   if (icode != CODE_FOR_nothing)
7466     {
7467       if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7468         target = gen_reg_rtx (mode);
7469
7470       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7471         val = convert_modes (mode, GET_MODE (val), val, 1);
7472       if (!insn_data[icode].operand[2].predicate (val, mode))
7473         val = force_reg (mode, val);
7474
7475       insn = GEN_FCN (icode) (target, mem, val);
7476       if (insn)
7477         {
7478           emit_insn (insn);
7479           return target;
7480         }
7481     }
7482
7483   /* Otherwise, use a compare-and-swap loop for the exchange.  */
7484   if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7485     {
7486       if (!target || !register_operand (target, mode))
7487         target = gen_reg_rtx (mode);
7488       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7489         val = convert_modes (mode, GET_MODE (val), val, 1);
7490       if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7491         return target;
7492     }
7493
7494   return NULL_RTX;
7495 }
7496
7497 #include "gt-optabs.h"