OSDN Git Service

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