OSDN Git Service

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