xref: /NextBSD/contrib/gcc/optabs.c (revision 5e568154a01fb6be74908baed265f265a56f002f)
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 
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
add_equal_note(rtx insns,rtx target,enum rtx_code code,rtx op0,rtx op1)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 
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
widen_operand(rtx op,enum machine_mode mode,enum machine_mode oldmode,int unsignedp,int no_extend)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 
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
optab_for_tree_code(enum tree_code code,tree type)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 
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
expand_widen_pattern_expr(tree exp,rtx op0,rtx op1,rtx wide_op,rtx target,int unsignedp)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
expand_ternary_op(enum machine_mode mode,optab ternary_optab,rtx op0,rtx op1,rtx op2,rtx target,int unsignedp)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
simplify_expand_binop(enum machine_mode mode,optab binoptab,rtx op0,rtx op1,rtx target,int unsignedp,enum optab_methods methods)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
force_expand_binop(enum machine_mode mode,optab binoptab,rtx op0,rtx op1,rtx target,int unsignedp,enum optab_methods methods)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
expand_vec_shift_expr(tree vec_shift_expr,rtx target)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
expand_superword_shift(optab binoptab,rtx outof_input,rtx superword_op1,rtx outof_target,rtx into_target,int unsignedp,enum optab_methods methods)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
expand_subword_shift(enum machine_mode op1_mode,optab binoptab,rtx outof_input,rtx into_input,rtx op1,rtx outof_target,rtx into_target,int unsignedp,enum optab_methods methods,unsigned HOST_WIDE_INT shift_mask)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
expand_doubleword_shift_condmove(enum machine_mode op1_mode,optab binoptab,enum rtx_code cmp_code,rtx cmp1,rtx cmp2,rtx outof_input,rtx into_input,rtx subword_op1,rtx superword_op1,rtx outof_target,rtx into_target,int unsignedp,enum optab_methods methods,unsigned HOST_WIDE_INT shift_mask)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
expand_doubleword_shift(enum machine_mode op1_mode,optab binoptab,rtx outof_input,rtx into_input,rtx op1,rtx outof_target,rtx into_target,int unsignedp,enum optab_methods methods,unsigned HOST_WIDE_INT shift_mask)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 
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
expand_doubleword_mult(enum machine_mode mode,rtx op0,rtx op1,rtx target,bool umulp,enum optab_methods methods)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 
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
expand_simple_binop(enum machine_mode mode,enum rtx_code code,rtx op0,rtx op1,rtx target,int unsignedp,enum optab_methods methods)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
swap_commutative_operands_with_target(rtx target,rtx op0,rtx op1)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
expand_binop(enum machine_mode mode,optab binoptab,rtx op0,rtx op1,rtx target,int unsignedp,enum optab_methods methods)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 
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
sign_expand_binop(enum machine_mode mode,optab uoptab,optab soptab,rtx op0,rtx op1,rtx target,int unsignedp,enum optab_methods methods)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 
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
expand_twoval_unop(optab unoptab,rtx op0,rtx targ0,rtx targ1,int unsignedp)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 
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
expand_twoval_binop(optab binoptab,rtx op0,rtx op1,rtx targ0,rtx targ1,int unsignedp)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
expand_twoval_binop_libfunc(optab binoptab,rtx op0,rtx op1,rtx targ0,rtx targ1,enum rtx_code code)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 
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
expand_simple_unop(enum machine_mode mode,enum rtx_code code,rtx op0,rtx target,int unsignedp)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
widen_clz(enum machine_mode mode,rtx op0,rtx target)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
expand_parity(enum machine_mode mode,rtx op0,rtx target)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
lowpart_subreg_maybe_copy(enum machine_mode omode,rtx val,enum machine_mode imode)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
expand_absneg_bit(enum rtx_code code,enum machine_mode mode,rtx op0,rtx target)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
expand_unop(enum machine_mode mode,optab unoptab,rtx op0,rtx target,int unsignedp)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 
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
expand_abs_nojump(enum machine_mode mode,rtx op0,rtx target,int result_unsignedp)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
expand_abs(enum machine_mode mode,rtx op0,rtx target,int result_unsignedp,int safe)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
expand_copysign_absneg(enum machine_mode mode,rtx op0,rtx op1,rtx target,int bitpos,bool op0_is_abs)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
expand_copysign_bit(enum machine_mode mode,rtx op0,rtx op1,rtx target,int bitpos,bool op0_is_abs)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
expand_copysign(rtx op0,rtx op1,rtx target)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 
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
emit_unop_insn(int icode,rtx target,rtx op0,enum rtx_code code)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 
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
no_conflict_move_test(rtx dest,rtx set,void * p0)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
maybe_encapsulate_block(rtx first,rtx last,rtx equiv)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
emit_no_conflict_block(rtx insns,rtx target,rtx op0,rtx op1,rtx equiv)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 
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
emit_libcall_block(rtx insns,rtx target,rtx result,rtx equiv)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 
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
can_compare_p(enum rtx_code code,enum machine_mode mode,enum can_compare_purpose purpose)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
prepare_cmp_insn(rtx * px,rtx * py,enum rtx_code * pcomparison,rtx size,enum machine_mode * pmode,int * punsignedp,enum can_compare_purpose purpose)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
prepare_operand(int icode,rtx x,int opnum,enum machine_mode mode,enum machine_mode wider_mode,int unsignedp)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
emit_cmp_and_jump_insn_1(rtx x,rtx y,enum machine_mode mode,enum rtx_code comparison,int unsignedp,rtx label)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
emit_cmp_and_jump_insns(rtx x,rtx y,enum rtx_code comparison,rtx size,enum machine_mode mode,int unsignedp,rtx label)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
emit_cmp_insn(rtx x,rtx y,enum rtx_code comparison,rtx size,enum machine_mode mode,int unsignedp)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 
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
prepare_float_lib_cmp(rtx * px,rtx * py,enum rtx_code * pcomparison,enum machine_mode * pmode,int * punsignedp)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 
4021 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4022 
4023 void
emit_indirect_jump(rtx loc)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 
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
emit_conditional_move(rtx target,enum rtx_code code,rtx op0,rtx op1,enum machine_mode cmode,rtx op2,rtx op3,enum machine_mode mode,int unsignedp)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
can_conditionally_move_p(enum machine_mode mode)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
emit_conditional_add(rtx target,enum rtx_code code,rtx op0,rtx op1,enum machine_mode cmode,rtx op2,rtx op3,enum machine_mode mode,int unsignedp)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 
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
gen_add2_insn(rtx x,rtx y)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
gen_add3_insn(rtx r0,rtx r1,rtx c)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
have_add2_insn(rtx x,rtx y)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
gen_sub2_insn(rtx x,rtx y)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
gen_sub3_insn(rtx r0,rtx r1,rtx c)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
have_sub2_insn(rtx x,rtx y)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
gen_move_insn(rtx x,rtx y)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 
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
can_extend_p(enum machine_mode to_mode,enum machine_mode from_mode,int unsignedp)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
gen_extend_insn(rtx x,rtx y,enum machine_mode mto,enum machine_mode mfrom,int unsignedp)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 
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
can_fix_p(enum machine_mode fixmode,enum machine_mode fltmode,int unsignedp,int * truncp_ptr)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
can_float_p(enum machine_mode fltmode,enum machine_mode fixmode,int unsignedp)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 
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
expand_float(rtx to,rtx from,int unsignedp)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 
4694 /* Generate code to convert FROM to fixed point and store in TO.  FROM
4695    must be floating point.  */
4696 
4697 void
expand_fix(rtx to,rtx from,int unsignedp)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 
4870 /* Report whether we have an instruction to perform the operation
4871    specified by CODE on operands of mode MODE.  */
4872 int
have_insn_for(enum rtx_code code,enum machine_mode mode)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
new_optab(void)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
new_convert_optab(void)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
init_optab(enum rtx_code code)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
init_optabv(enum rtx_code code)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
init_convert_optab(enum rtx_code code)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
init_libfuncs(optab optable,int first_mode,int last_mode,const char * opname,int suffix)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
init_integral_libfuncs(optab optable,const char * opname,int suffix)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
init_floating_libfuncs(optab optable,const char * opname,int suffix)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
init_interclass_conv_libfuncs(convert_optab tab,const char * opname,enum mode_class from_class,enum mode_class to_class)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
init_intraclass_conv_libfuncs(convert_optab tab,const char * opname,enum mode_class class,bool widening)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
init_one_libfunc(const char * name)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
set_optab_libfunc(optab optable,enum machine_mode mode,const char * name)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
set_conv_libfunc(convert_optab optable,enum machine_mode tmode,enum machine_mode fmode,const char * name)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
init_optabs(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
debug_optab_libfuncs(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 
5568 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5569    CODE.  Return 0 on failure.  */
5570 
5571 rtx
gen_cond_trap(enum rtx_code code ATTRIBUTE_UNUSED,rtx op1,rtx op2 ATTRIBUTE_UNUSED,rtx tcode ATTRIBUTE_UNUSED)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
get_rtx_code(enum tree_code tcode,bool unsignedp)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
vector_compare_rtx(tree cond,bool unsignedp,enum insn_code icode)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
get_vcond_icode(tree expr,enum machine_mode mode)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
expand_vec_cond_expr_p(tree expr,enum machine_mode vmode)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
expand_vec_cond_expr(tree vec_cond_expr,rtx target)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 
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
expand_val_compare_and_swap_1(rtx mem,rtx old_val,rtx new_val,rtx target,enum insn_code icode)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
expand_val_compare_and_swap(rtx mem,rtx old_val,rtx new_val,rtx target)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
expand_bool_compare_and_swap(rtx mem,rtx old_val,rtx new_val,rtx target)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
expand_compare_and_swap_loop(rtx mem,rtx old_reg,rtx new_reg,rtx seq)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
expand_sync_operation(rtx mem,rtx val,enum rtx_code code)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
expand_sync_fetch_operation(rtx mem,rtx val,enum rtx_code code,bool after,rtx target)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
expand_sync_lock_test_and_set(rtx mem,rtx val,rtx target)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"
6282