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