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