OSDN Git Service

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