OSDN Git Service

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