OSDN Git Service

2004-08-17 Paul Brook <paul@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004 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 we are optimizing,
786      force expensive constants into a register.  */
787   if (CONSTANT_P (op0) && optimize
788       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
789     op0 = force_reg (mode, op0);
790
791   if (CONSTANT_P (op1) && optimize
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 we are optimizing,
2352      force expensive constants into a register.  */
2353   if (CONSTANT_P (op0) && optimize
2354       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2355     op0 = force_reg (mode, op0);
2356
2357   if (CONSTANT_P (op1) && optimize
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
2452 /* Expand the two-valued library call indicated by BINOPTAB, but
2453    preserve only one of the values.  If TARG0 is non-NULL, the first
2454    value is placed into TARG0; otherwise the second value is placed
2455    into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2456    value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2457    This routine assumes that the value returned by the library call is
2458    as if the return value was of an integral mode twice as wide as the
2459    mode of OP0.  Returns 1 if the call was successful.  */
2460
2461 bool
2462 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, 
2463                              rtx targ0, rtx targ1, enum rtx_code code)
2464 {
2465   enum machine_mode mode;
2466   enum machine_mode libval_mode;
2467   rtx libval;
2468   rtx insns;
2469   
2470   /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2471   if (!((targ0 != NULL_RTX) ^ (targ1 != NULL_RTX)))
2472     abort ();
2473
2474   mode = GET_MODE (op0);
2475   if (!binoptab->handlers[(int) mode].libfunc)
2476     return false;
2477
2478   /* The value returned by the library function will have twice as
2479      many bits as the nominal MODE.  */
2480   libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode), 
2481                                         MODE_INT);
2482   start_sequence ();
2483   libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2484                                     NULL_RTX, LCT_CONST, 
2485                                     libval_mode, 2,
2486                                     op0, mode, 
2487                                     op1, mode);
2488   /* Get the part of VAL containing the value that we want.  */
2489   libval = simplify_gen_subreg (mode, libval, libval_mode,
2490                                 targ0 ? 0 : GET_MODE_SIZE (mode));
2491   insns = get_insns ();
2492   end_sequence ();
2493   /* Move the into the desired location.  */
2494   emit_libcall_block (insns, targ0 ? targ0 : targ1, libval, 
2495                       gen_rtx_fmt_ee (code, mode, op0, op1));
2496   
2497   return true;
2498 }
2499
2500 \f
2501 /* Wrapper around expand_unop which takes an rtx code to specify
2502    the operation to perform, not an optab pointer.  All other
2503    arguments are the same.  */
2504 rtx
2505 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2506                     rtx target, int unsignedp)
2507 {
2508   optab unop = code_to_optab[(int) code];
2509   if (unop == 0)
2510     abort ();
2511
2512   return expand_unop (mode, unop, op0, target, unsignedp);
2513 }
2514
2515 /* Try calculating
2516         (clz:narrow x)
2517    as
2518         (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2519 static rtx
2520 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2521 {
2522   enum mode_class class = GET_MODE_CLASS (mode);
2523   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2524     {
2525       enum machine_mode wider_mode;
2526       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2527            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2528         {
2529           if (clz_optab->handlers[(int) wider_mode].insn_code
2530               != CODE_FOR_nothing)
2531             {
2532               rtx xop0, temp, last;
2533
2534               last = get_last_insn ();
2535
2536               if (target == 0)
2537                 target = gen_reg_rtx (mode);
2538               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2539               temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2540               if (temp != 0)
2541                 temp = expand_binop (wider_mode, sub_optab, temp,
2542                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2543                                               - GET_MODE_BITSIZE (mode)),
2544                                      target, true, OPTAB_DIRECT);
2545               if (temp == 0)
2546                 delete_insns_since (last);
2547
2548               return temp;
2549             }
2550         }
2551     }
2552   return 0;
2553 }
2554
2555 /* Try calculating (parity x) as (and (popcount x) 1), where
2556    popcount can also be done in a wider mode.  */
2557 static rtx
2558 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2559 {
2560   enum mode_class class = GET_MODE_CLASS (mode);
2561   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2562     {
2563       enum machine_mode wider_mode;
2564       for (wider_mode = mode; wider_mode != VOIDmode;
2565            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2566         {
2567           if (popcount_optab->handlers[(int) wider_mode].insn_code
2568               != CODE_FOR_nothing)
2569             {
2570               rtx xop0, temp, last;
2571
2572               last = get_last_insn ();
2573
2574               if (target == 0)
2575                 target = gen_reg_rtx (mode);
2576               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2577               temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2578                                   true);
2579               if (temp != 0)
2580                 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2581                                      target, true, OPTAB_DIRECT);
2582               if (temp == 0)
2583                 delete_insns_since (last);
2584
2585               return temp;
2586             }
2587         }
2588     }
2589   return 0;
2590 }
2591
2592 /* Generate code to perform an operation specified by UNOPTAB
2593    on operand OP0, with result having machine-mode MODE.
2594
2595    UNSIGNEDP is for the case where we have to widen the operands
2596    to perform the operation.  It says to use zero-extension.
2597
2598    If TARGET is nonzero, the value
2599    is generated there, if it is convenient to do so.
2600    In all cases an rtx is returned for the locus of the value;
2601    this may or may not be TARGET.  */
2602
2603 rtx
2604 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2605              int unsignedp)
2606 {
2607   enum mode_class class;
2608   enum machine_mode wider_mode;
2609   rtx temp;
2610   rtx last = get_last_insn ();
2611   rtx pat;
2612
2613   class = GET_MODE_CLASS (mode);
2614
2615   if (flag_force_mem)
2616     op0 = force_not_mem (op0);
2617
2618   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2619     {
2620       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2621       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2622       rtx xop0 = op0;
2623
2624       if (target)
2625         temp = target;
2626       else
2627         temp = gen_reg_rtx (mode);
2628
2629       if (GET_MODE (xop0) != VOIDmode
2630           && GET_MODE (xop0) != mode0)
2631         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2632
2633       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2634
2635       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2636         xop0 = copy_to_mode_reg (mode0, xop0);
2637
2638       if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2639         temp = gen_reg_rtx (mode);
2640
2641       pat = GEN_FCN (icode) (temp, xop0);
2642       if (pat)
2643         {
2644           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2645               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2646             {
2647               delete_insns_since (last);
2648               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2649             }
2650
2651           emit_insn (pat);
2652
2653           return temp;
2654         }
2655       else
2656         delete_insns_since (last);
2657     }
2658
2659   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2660
2661   /* Widening clz needs special treatment.  */
2662   if (unoptab == clz_optab)
2663     {
2664       temp = widen_clz (mode, op0, target);
2665       if (temp)
2666         return temp;
2667       else
2668         goto try_libcall;
2669     }
2670
2671   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2672     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2673          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2674       {
2675         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2676           {
2677             rtx xop0 = op0;
2678
2679             /* For certain operations, we need not actually extend
2680                the narrow operand, as long as we will truncate the
2681                results to the same narrowness.  */
2682
2683             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2684                                   (unoptab == neg_optab
2685                                    || unoptab == one_cmpl_optab)
2686                                   && class == MODE_INT);
2687
2688             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2689                                 unsignedp);
2690
2691             if (temp)
2692               {
2693                 if (class != MODE_INT)
2694                   {
2695                     if (target == 0)
2696                       target = gen_reg_rtx (mode);
2697                     convert_move (target, temp, 0);
2698                     return target;
2699                   }
2700                 else
2701                   return gen_lowpart (mode, temp);
2702               }
2703             else
2704               delete_insns_since (last);
2705           }
2706       }
2707
2708   /* These can be done a word at a time.  */
2709   if (unoptab == one_cmpl_optab
2710       && class == MODE_INT
2711       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2712       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2713     {
2714       int i;
2715       rtx insns;
2716
2717       if (target == 0 || target == op0)
2718         target = gen_reg_rtx (mode);
2719
2720       start_sequence ();
2721
2722       /* Do the actual arithmetic.  */
2723       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2724         {
2725           rtx target_piece = operand_subword (target, i, 1, mode);
2726           rtx x = expand_unop (word_mode, unoptab,
2727                                operand_subword_force (op0, i, mode),
2728                                target_piece, unsignedp);
2729
2730           if (target_piece != x)
2731             emit_move_insn (target_piece, x);
2732         }
2733
2734       insns = get_insns ();
2735       end_sequence ();
2736
2737       emit_no_conflict_block (insns, target, op0, NULL_RTX,
2738                               gen_rtx_fmt_e (unoptab->code, mode,
2739                                              copy_rtx (op0)));
2740       return target;
2741     }
2742
2743   /* Open-code the complex negation operation.  */
2744   else if (unoptab->code == NEG
2745            && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2746     {
2747       rtx target_piece;
2748       rtx x;
2749       rtx seq;
2750
2751       /* Find the correct mode for the real and imaginary parts.  */
2752       enum machine_mode submode = GET_MODE_INNER (mode);
2753
2754       if (submode == BLKmode)
2755         abort ();
2756
2757       if (target == 0)
2758         target = gen_reg_rtx (mode);
2759
2760       start_sequence ();
2761
2762       target_piece = gen_imagpart (submode, target);
2763       x = expand_unop (submode, unoptab,
2764                        gen_imagpart (submode, op0),
2765                        target_piece, unsignedp);
2766       if (target_piece != x)
2767         emit_move_insn (target_piece, x);
2768
2769       target_piece = gen_realpart (submode, target);
2770       x = expand_unop (submode, unoptab,
2771                        gen_realpart (submode, op0),
2772                        target_piece, unsignedp);
2773       if (target_piece != x)
2774         emit_move_insn (target_piece, x);
2775
2776       seq = get_insns ();
2777       end_sequence ();
2778
2779       emit_no_conflict_block (seq, target, op0, 0,
2780                               gen_rtx_fmt_e (unoptab->code, mode,
2781                                              copy_rtx (op0)));
2782       return target;
2783     }
2784
2785   /* Try negating floating point values by flipping the sign bit.  */
2786   if (unoptab->code == NEG && class == MODE_FLOAT
2787       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2788     {
2789       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2790       enum machine_mode imode = int_mode_for_mode (mode);
2791       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2792
2793       if (imode != BLKmode && bitpos >= 0 && fmt->has_signed_zero)
2794         {
2795           HOST_WIDE_INT hi, lo;
2796           rtx last = get_last_insn ();
2797
2798           /* Handle targets with different FP word orders.  */
2799           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2800             {
2801               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2802               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2803               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2804             }
2805
2806           if (bitpos < HOST_BITS_PER_WIDE_INT)
2807             {
2808               hi = 0;
2809               lo = (HOST_WIDE_INT) 1 << bitpos;
2810             }
2811           else
2812             {
2813               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2814               lo = 0;
2815             }
2816           temp = expand_binop (imode, xor_optab,
2817                                gen_lowpart (imode, op0),
2818                                immed_double_const (lo, hi, imode),
2819                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2820           if (temp != 0)
2821             {
2822               rtx insn;
2823               if (target == 0)
2824                 target = gen_reg_rtx (mode);
2825               insn = emit_move_insn (target, gen_lowpart (mode, temp));
2826               set_unique_reg_note (insn, REG_EQUAL,
2827                                    gen_rtx_fmt_e (NEG, mode,
2828                                                   copy_rtx (op0)));
2829               return target;
2830             }
2831           delete_insns_since (last);
2832         }
2833     }
2834
2835   /* Try calculating parity (x) as popcount (x) % 2.  */
2836   if (unoptab == parity_optab)
2837     {
2838       temp = expand_parity (mode, op0, target);
2839       if (temp)
2840         return temp;
2841     }
2842
2843   /* If there is no negation pattern, try subtracting from zero.  */
2844   if (unoptab == neg_optab && class == MODE_INT)
2845     {
2846       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2847                            target, unsignedp, OPTAB_DIRECT);
2848       if (temp)
2849         return temp;
2850     }
2851
2852  try_libcall:
2853   /* Now try a library call in this mode.  */
2854   if (unoptab->handlers[(int) mode].libfunc)
2855     {
2856       rtx insns;
2857       rtx value;
2858       enum machine_mode outmode = mode;
2859
2860       /* All of these functions return small values.  Thus we choose to
2861          have them return something that isn't a double-word.  */
2862       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2863           || unoptab == popcount_optab || unoptab == parity_optab)
2864         outmode
2865             = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2866
2867       start_sequence ();
2868
2869       /* Pass 1 for NO_QUEUE so we don't lose any increments
2870          if the libcall is cse'd or moved.  */
2871       value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2872                                        NULL_RTX, LCT_CONST, outmode,
2873                                        1, op0, mode);
2874       insns = get_insns ();
2875       end_sequence ();
2876
2877       target = gen_reg_rtx (outmode);
2878       emit_libcall_block (insns, target, value,
2879                           gen_rtx_fmt_e (unoptab->code, mode, op0));
2880
2881       return target;
2882     }
2883
2884   if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
2885     return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
2886
2887   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2888
2889   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2890     {
2891       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2892            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2893         {
2894           if ((unoptab->handlers[(int) wider_mode].insn_code
2895                != CODE_FOR_nothing)
2896               || unoptab->handlers[(int) wider_mode].libfunc)
2897             {
2898               rtx xop0 = op0;
2899
2900               /* For certain operations, we need not actually extend
2901                  the narrow operand, as long as we will truncate the
2902                  results to the same narrowness.  */
2903
2904               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2905                                     (unoptab == neg_optab
2906                                      || unoptab == one_cmpl_optab)
2907                                     && class == MODE_INT);
2908
2909               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2910                                   unsignedp);
2911
2912               /* If we are generating clz using wider mode, adjust the
2913                  result.  */
2914               if (unoptab == clz_optab && temp != 0)
2915                 temp = expand_binop (wider_mode, sub_optab, temp,
2916                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2917                                               - GET_MODE_BITSIZE (mode)),
2918                                      target, true, OPTAB_DIRECT);
2919
2920               if (temp)
2921                 {
2922                   if (class != MODE_INT)
2923                     {
2924                       if (target == 0)
2925                         target = gen_reg_rtx (mode);
2926                       convert_move (target, temp, 0);
2927                       return target;
2928                     }
2929                   else
2930                     return gen_lowpart (mode, temp);
2931                 }
2932               else
2933                 delete_insns_since (last);
2934             }
2935         }
2936     }
2937
2938   /* If there is no negate operation, try doing a subtract from zero.
2939      The US Software GOFAST library needs this.  FIXME: This is *wrong*
2940      for floating-point operations due to negative zeros!  */
2941   if (unoptab->code == NEG)
2942     {
2943       rtx temp;
2944       temp = expand_binop (mode,
2945                            unoptab == negv_optab ? subv_optab : sub_optab,
2946                            CONST0_RTX (mode), op0,
2947                            target, unsignedp, OPTAB_LIB_WIDEN);
2948       if (temp)
2949         return temp;
2950     }
2951
2952   return 0;
2953 }
2954 \f
2955 /* Emit code to compute the absolute value of OP0, with result to
2956    TARGET if convenient.  (TARGET may be 0.)  The return value says
2957    where the result actually is to be found.
2958
2959    MODE is the mode of the operand; the mode of the result is
2960    different but can be deduced from MODE.
2961
2962  */
2963
2964 rtx
2965 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2966                    int result_unsignedp)
2967 {
2968   rtx temp;
2969
2970   if (! flag_trapv)
2971     result_unsignedp = 1;
2972
2973   /* First try to do it with a special abs instruction.  */
2974   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2975                       op0, target, 0);
2976   if (temp != 0)
2977     return temp;
2978
2979   /* For floating point modes, try clearing the sign bit.  */
2980   if (GET_MODE_CLASS (mode) == MODE_FLOAT
2981       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2982     {
2983       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2984       enum machine_mode imode = int_mode_for_mode (mode);
2985       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2986
2987       if (imode != BLKmode && bitpos >= 0)
2988         {
2989           HOST_WIDE_INT hi, lo;
2990           rtx last = get_last_insn ();
2991
2992           /* Handle targets with different FP word orders.  */
2993           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2994             {
2995               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2996               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2997               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2998             }
2999
3000           if (bitpos < HOST_BITS_PER_WIDE_INT)
3001             {
3002               hi = 0;
3003               lo = (HOST_WIDE_INT) 1 << bitpos;
3004             }
3005           else
3006             {
3007               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3008               lo = 0;
3009             }
3010           temp = expand_binop (imode, and_optab,
3011                                gen_lowpart (imode, op0),
3012                                immed_double_const (~lo, ~hi, imode),
3013                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
3014           if (temp != 0)
3015             {
3016               rtx insn;
3017               if (target == 0)
3018                 target = gen_reg_rtx (mode);
3019               insn = emit_move_insn (target, gen_lowpart (mode, temp));
3020               set_unique_reg_note (insn, REG_EQUAL,
3021                                    gen_rtx_fmt_e (ABS, mode,
3022                                                   copy_rtx (op0)));
3023               return target;
3024             }
3025           delete_insns_since (last);
3026         }
3027     }
3028
3029   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
3030   if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3031     {
3032       rtx last = get_last_insn ();
3033
3034       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3035       if (temp != 0)
3036         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3037                              OPTAB_WIDEN);
3038
3039       if (temp != 0)
3040         return temp;
3041
3042       delete_insns_since (last);
3043     }
3044
3045   /* If this machine has expensive jumps, we can do integer absolute
3046      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3047      where W is the width of MODE.  */
3048
3049   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
3050     {
3051       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3052                                    size_int (GET_MODE_BITSIZE (mode) - 1),
3053                                    NULL_RTX, 0);
3054
3055       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3056                            OPTAB_LIB_WIDEN);
3057       if (temp != 0)
3058         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3059                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
3060
3061       if (temp != 0)
3062         return temp;
3063     }
3064
3065   return NULL_RTX;
3066 }
3067
3068 rtx
3069 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3070             int result_unsignedp, int safe)
3071 {
3072   rtx temp, op1;
3073
3074   if (! flag_trapv)
3075     result_unsignedp = 1;
3076
3077   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3078   if (temp != 0)
3079     return temp;
3080
3081   /* If that does not win, use conditional jump and negate.  */
3082
3083   /* It is safe to use the target if it is the same
3084      as the source if this is also a pseudo register */
3085   if (op0 == target && REG_P (op0)
3086       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3087     safe = 1;
3088
3089   op1 = gen_label_rtx ();
3090   if (target == 0 || ! safe
3091       || GET_MODE (target) != mode
3092       || (MEM_P (target) && MEM_VOLATILE_P (target))
3093       || (REG_P (target)
3094           && REGNO (target) < FIRST_PSEUDO_REGISTER))
3095     target = gen_reg_rtx (mode);
3096
3097   emit_move_insn (target, op0);
3098   NO_DEFER_POP;
3099
3100   /* If this mode is an integer too wide to compare properly,
3101      compare word by word.  Rely on CSE to optimize constant cases.  */
3102   if (GET_MODE_CLASS (mode) == MODE_INT
3103       && ! can_compare_p (GE, mode, ccp_jump))
3104     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
3105                                   NULL_RTX, op1);
3106   else
3107     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3108                              NULL_RTX, NULL_RTX, op1);
3109
3110   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3111                      target, target, 0);
3112   if (op0 != target)
3113     emit_move_insn (target, op0);
3114   emit_label (op1);
3115   OK_DEFER_POP;
3116   return target;
3117 }
3118 \f
3119 /* Emit code to compute the absolute value of OP0, with result to
3120    TARGET if convenient.  (TARGET may be 0.)  The return value says
3121    where the result actually is to be found.
3122
3123    MODE is the mode of the operand; the mode of the result is
3124    different but can be deduced from MODE.
3125
3126    UNSIGNEDP is relevant for complex integer modes.  */
3127
3128 rtx
3129 expand_complex_abs (enum machine_mode mode, rtx op0, rtx target,
3130                     int unsignedp)
3131 {
3132   enum mode_class class = GET_MODE_CLASS (mode);
3133   enum machine_mode wider_mode;
3134   rtx temp;
3135   rtx entry_last = get_last_insn ();
3136   rtx last;
3137   rtx pat;
3138   optab this_abs_optab;
3139
3140   /* Find the correct mode for the real and imaginary parts.  */
3141   enum machine_mode submode = GET_MODE_INNER (mode);
3142
3143   if (submode == BLKmode)
3144     abort ();
3145
3146   if (flag_force_mem)
3147     op0 = force_not_mem (op0);
3148
3149   last = get_last_insn ();
3150
3151   this_abs_optab = ! unsignedp && flag_trapv
3152                    && (GET_MODE_CLASS(mode) == MODE_INT)
3153                    ? absv_optab : abs_optab;
3154
3155   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3156     {
3157       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
3158       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3159       rtx xop0 = op0;
3160
3161       if (target)
3162         temp = target;
3163       else
3164         temp = gen_reg_rtx (submode);
3165
3166       if (GET_MODE (xop0) != VOIDmode
3167           && GET_MODE (xop0) != mode0)
3168         xop0 = convert_to_mode (mode0, xop0, unsignedp);
3169
3170       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
3171
3172       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
3173         xop0 = copy_to_mode_reg (mode0, xop0);
3174
3175       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
3176         temp = gen_reg_rtx (submode);
3177
3178       pat = GEN_FCN (icode) (temp, xop0);
3179       if (pat)
3180         {
3181           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3182               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
3183                                    NULL_RTX))
3184             {
3185               delete_insns_since (last);
3186               return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
3187                                   unsignedp);
3188             }
3189
3190           emit_insn (pat);
3191
3192           return temp;
3193         }
3194       else
3195         delete_insns_since (last);
3196     }
3197
3198   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
3199
3200   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3201        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3202     {
3203       if (this_abs_optab->handlers[(int) wider_mode].insn_code
3204           != CODE_FOR_nothing)
3205         {
3206           rtx xop0 = op0;
3207
3208           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3209           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3210
3211           if (temp)
3212             {
3213               if (class != MODE_COMPLEX_INT)
3214                 {
3215                   if (target == 0)
3216                     target = gen_reg_rtx (submode);
3217                   convert_move (target, temp, 0);
3218                   return target;
3219                 }
3220               else
3221                 return gen_lowpart (submode, temp);
3222             }
3223           else
3224             delete_insns_since (last);
3225         }
3226     }
3227
3228   /* Open-code the complex absolute-value operation
3229      if we can open-code sqrt.  Otherwise it's not worth while.  */
3230   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
3231       && ! flag_trapv)
3232     {
3233       rtx real, imag, total;
3234
3235       real = gen_realpart (submode, op0);
3236       imag = gen_imagpart (submode, op0);
3237
3238       /* Square both parts.  */
3239       real = expand_mult (submode, real, real, NULL_RTX, 0);
3240       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
3241
3242       /* Sum the parts.  */
3243       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
3244                             0, OPTAB_LIB_WIDEN);
3245
3246       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
3247       target = expand_unop (submode, sqrt_optab, total, target, 0);
3248       if (target == 0)
3249         delete_insns_since (last);
3250       else
3251         return target;
3252     }
3253
3254   /* Now try a library call in this mode.  */
3255   if (this_abs_optab->handlers[(int) mode].libfunc)
3256     {
3257       rtx insns;
3258       rtx value;
3259
3260       start_sequence ();
3261
3262       /* Pass 1 for NO_QUEUE so we don't lose any increments
3263          if the libcall is cse'd or moved.  */
3264       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
3265                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
3266       insns = get_insns ();
3267       end_sequence ();
3268
3269       target = gen_reg_rtx (submode);
3270       emit_libcall_block (insns, target, value,
3271                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
3272
3273       return target;
3274     }
3275
3276   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3277
3278   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3279        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3280     {
3281       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
3282            != CODE_FOR_nothing)
3283           || this_abs_optab->handlers[(int) wider_mode].libfunc)
3284         {
3285           rtx xop0 = op0;
3286
3287           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3288
3289           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3290
3291           if (temp)
3292             {
3293               if (class != MODE_COMPLEX_INT)
3294                 {
3295                   if (target == 0)
3296                     target = gen_reg_rtx (submode);
3297                   convert_move (target, temp, 0);
3298                   return target;
3299                 }
3300               else
3301                 return gen_lowpart (submode, temp);
3302             }
3303           else
3304             delete_insns_since (last);
3305         }
3306     }
3307
3308   delete_insns_since (entry_last);
3309   return 0;
3310 }
3311 \f
3312 /* Generate an instruction whose insn-code is INSN_CODE,
3313    with two operands: an output TARGET and an input OP0.
3314    TARGET *must* be nonzero, and the output is always stored there.
3315    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3316    the value that is stored into TARGET.  */
3317
3318 void
3319 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3320 {
3321   rtx temp;
3322   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3323   rtx pat;
3324
3325   temp = target;
3326
3327   /* Sign and zero extension from memory is often done specially on
3328      RISC machines, so forcing into a register here can pessimize
3329      code.  */
3330   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
3331     op0 = force_not_mem (op0);
3332
3333   /* Now, if insn does not accept our operands, put them into pseudos.  */
3334
3335   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3336     op0 = copy_to_mode_reg (mode0, op0);
3337
3338   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
3339       || (flag_force_mem && MEM_P (temp)))
3340     temp = gen_reg_rtx (GET_MODE (temp));
3341
3342   pat = GEN_FCN (icode) (temp, op0);
3343
3344   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3345     add_equal_note (pat, temp, code, op0, NULL_RTX);
3346
3347   emit_insn (pat);
3348
3349   if (temp != target)
3350     emit_move_insn (target, temp);
3351 }
3352 \f
3353 /* Emit code to perform a series of operations on a multi-word quantity, one
3354    word at a time.
3355
3356    Such a block is preceded by a CLOBBER of the output, consists of multiple
3357    insns, each setting one word of the output, and followed by a SET copying
3358    the output to itself.
3359
3360    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3361    note indicating that it doesn't conflict with the (also multi-word)
3362    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3363    notes.
3364
3365    INSNS is a block of code generated to perform the operation, not including
3366    the CLOBBER and final copy.  All insns that compute intermediate values
3367    are first emitted, followed by the block as described above.
3368
3369    TARGET, OP0, and OP1 are the output and inputs of the operations,
3370    respectively.  OP1 may be zero for a unary operation.
3371
3372    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3373    on the last insn.
3374
3375    If TARGET is not a register, INSNS is simply emitted with no special
3376    processing.  Likewise if anything in INSNS is not an INSN or if
3377    there is a libcall block inside INSNS.
3378
3379    The final insn emitted is returned.  */
3380
3381 rtx
3382 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3383 {
3384   rtx prev, next, first, last, insn;
3385
3386   if (!REG_P (target) || reload_in_progress)
3387     return emit_insn (insns);
3388   else
3389     for (insn = insns; insn; insn = NEXT_INSN (insn))
3390       if (!NONJUMP_INSN_P (insn)
3391           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3392         return emit_insn (insns);
3393
3394   /* First emit all insns that do not store into words of the output and remove
3395      these from the list.  */
3396   for (insn = insns; insn; insn = next)
3397     {
3398       rtx set = 0, note;
3399       int i;
3400
3401       next = NEXT_INSN (insn);
3402
3403       /* Some ports (cris) create a libcall regions at their own.  We must
3404          avoid any potential nesting of LIBCALLs.  */
3405       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3406         remove_note (insn, note);
3407       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3408         remove_note (insn, note);
3409
3410       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3411           || GET_CODE (PATTERN (insn)) == CLOBBER)
3412         set = PATTERN (insn);
3413       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3414         {
3415           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3416             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3417               {
3418                 set = XVECEXP (PATTERN (insn), 0, i);
3419                 break;
3420               }
3421         }
3422
3423       if (set == 0)
3424         abort ();
3425
3426       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3427         {
3428           if (PREV_INSN (insn))
3429             NEXT_INSN (PREV_INSN (insn)) = next;
3430           else
3431             insns = next;
3432
3433           if (next)
3434             PREV_INSN (next) = PREV_INSN (insn);
3435
3436           add_insn (insn);
3437         }
3438     }
3439
3440   prev = get_last_insn ();
3441
3442   /* Now write the CLOBBER of the output, followed by the setting of each
3443      of the words, followed by the final copy.  */
3444   if (target != op0 && target != op1)
3445     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3446
3447   for (insn = insns; insn; insn = next)
3448     {
3449       next = NEXT_INSN (insn);
3450       add_insn (insn);
3451
3452       if (op1 && REG_P (op1))
3453         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3454                                               REG_NOTES (insn));
3455
3456       if (op0 && REG_P (op0))
3457         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3458                                               REG_NOTES (insn));
3459     }
3460
3461   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3462       != CODE_FOR_nothing)
3463     {
3464       last = emit_move_insn (target, target);
3465       if (equiv)
3466         set_unique_reg_note (last, REG_EQUAL, equiv);
3467     }
3468   else
3469     {
3470       last = get_last_insn ();
3471
3472       /* Remove any existing REG_EQUAL note from "last", or else it will
3473          be mistaken for a note referring to the full contents of the
3474          alleged libcall value when found together with the REG_RETVAL
3475          note added below.  An existing note can come from an insn
3476          expansion at "last".  */
3477       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3478     }
3479
3480   if (prev == 0)
3481     first = get_insns ();
3482   else
3483     first = NEXT_INSN (prev);
3484
3485   /* Encapsulate the block so it gets manipulated as a unit.  */
3486   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3487                                          REG_NOTES (first));
3488   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3489
3490   return last;
3491 }
3492 \f
3493 /* Emit code to make a call to a constant function or a library call.
3494
3495    INSNS is a list containing all insns emitted in the call.
3496    These insns leave the result in RESULT.  Our block is to copy RESULT
3497    to TARGET, which is logically equivalent to EQUIV.
3498
3499    We first emit any insns that set a pseudo on the assumption that these are
3500    loading constants into registers; doing so allows them to be safely cse'ed
3501    between blocks.  Then we emit all the other insns in the block, followed by
3502    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3503    note with an operand of EQUIV.
3504
3505    Moving assignments to pseudos outside of the block is done to improve
3506    the generated code, but is not required to generate correct code,
3507    hence being unable to move an assignment is not grounds for not making
3508    a libcall block.  There are two reasons why it is safe to leave these
3509    insns inside the block: First, we know that these pseudos cannot be
3510    used in generated RTL outside the block since they are created for
3511    temporary purposes within the block.  Second, CSE will not record the
3512    values of anything set inside a libcall block, so we know they must
3513    be dead at the end of the block.
3514
3515    Except for the first group of insns (the ones setting pseudos), the
3516    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3517
3518 void
3519 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3520 {
3521   rtx final_dest = target;
3522   rtx prev, next, first, last, insn;
3523
3524   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3525      into a MEM later.  Protect the libcall block from this change.  */
3526   if (! REG_P (target) || REG_USERVAR_P (target))
3527     target = gen_reg_rtx (GET_MODE (target));
3528
3529   /* If we're using non-call exceptions, a libcall corresponding to an
3530      operation that may trap may also trap.  */
3531   if (flag_non_call_exceptions && may_trap_p (equiv))
3532     {
3533       for (insn = insns; insn; insn = NEXT_INSN (insn))
3534         if (CALL_P (insn))
3535           {
3536             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3537
3538             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3539               remove_note (insn, note);
3540           }
3541     }
3542   else
3543   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3544      reg note to indicate that this call cannot throw or execute a nonlocal
3545      goto (unless there is already a REG_EH_REGION note, in which case
3546      we update it).  */
3547     for (insn = insns; insn; insn = NEXT_INSN (insn))
3548       if (CALL_P (insn))
3549         {
3550           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3551
3552           if (note != 0)
3553             XEXP (note, 0) = constm1_rtx;
3554           else
3555             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3556                                                   REG_NOTES (insn));
3557         }
3558
3559   /* First emit all insns that set pseudos.  Remove them from the list as
3560      we go.  Avoid insns that set pseudos which were referenced in previous
3561      insns.  These can be generated by move_by_pieces, for example,
3562      to update an address.  Similarly, avoid insns that reference things
3563      set in previous insns.  */
3564
3565   for (insn = insns; insn; insn = next)
3566     {
3567       rtx set = single_set (insn);
3568       rtx note;
3569
3570       /* Some ports (cris) create a libcall regions at their own.  We must
3571          avoid any potential nesting of LIBCALLs.  */
3572       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3573         remove_note (insn, note);
3574       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3575         remove_note (insn, note);
3576
3577       next = NEXT_INSN (insn);
3578
3579       if (set != 0 && REG_P (SET_DEST (set))
3580           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3581           && (insn == insns
3582               || ((! INSN_P(insns)
3583                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3584                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
3585                   && ! modified_in_p (SET_SRC (set), insns)
3586                   && ! modified_between_p (SET_SRC (set), insns, insn))))
3587         {
3588           if (PREV_INSN (insn))
3589             NEXT_INSN (PREV_INSN (insn)) = next;
3590           else
3591             insns = next;
3592
3593           if (next)
3594             PREV_INSN (next) = PREV_INSN (insn);
3595
3596           add_insn (insn);
3597         }
3598
3599       /* Some ports use a loop to copy large arguments onto the stack.
3600          Don't move anything outside such a loop.  */
3601       if (LABEL_P (insn))
3602         break;
3603     }
3604
3605   prev = get_last_insn ();
3606
3607   /* Write the remaining insns followed by the final copy.  */
3608
3609   for (insn = insns; insn; insn = next)
3610     {
3611       next = NEXT_INSN (insn);
3612
3613       add_insn (insn);
3614     }
3615
3616   last = emit_move_insn (target, result);
3617   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3618       != CODE_FOR_nothing)
3619     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3620   else
3621     {
3622       /* Remove any existing REG_EQUAL note from "last", or else it will
3623          be mistaken for a note referring to the full contents of the
3624          libcall value when found together with the REG_RETVAL note added
3625          below.  An existing note can come from an insn expansion at
3626          "last".  */
3627       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3628     }
3629
3630   if (final_dest != target)
3631     emit_move_insn (final_dest, target);
3632
3633   if (prev == 0)
3634     first = get_insns ();
3635   else
3636     first = NEXT_INSN (prev);
3637
3638   /* Encapsulate the block so it gets manipulated as a unit.  */
3639   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3640     {
3641       /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3642          when the encapsulated region would not be in one basic block,
3643          i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3644        */
3645       bool attach_libcall_retval_notes = true;
3646       next = NEXT_INSN (last);
3647       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3648         if (control_flow_insn_p (insn))
3649           {
3650             attach_libcall_retval_notes = false;
3651             break;
3652           }
3653
3654       if (attach_libcall_retval_notes)
3655         {
3656           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3657                                                  REG_NOTES (first));
3658           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3659                                                 REG_NOTES (last));
3660         }
3661     }
3662 }
3663 \f
3664 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3665    PURPOSE describes how this comparison will be used.  CODE is the rtx
3666    comparison code we will be using.
3667
3668    ??? Actually, CODE is slightly weaker than that.  A target is still
3669    required to implement all of the normal bcc operations, but not
3670    required to implement all (or any) of the unordered bcc operations.  */
3671
3672 int
3673 can_compare_p (enum rtx_code code, enum machine_mode mode,
3674                enum can_compare_purpose purpose)
3675 {
3676   do
3677     {
3678       if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3679         {
3680           if (purpose == ccp_jump)
3681             return bcc_gen_fctn[(int) code] != NULL;
3682           else if (purpose == ccp_store_flag)
3683             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3684           else
3685             /* There's only one cmov entry point, and it's allowed to fail.  */
3686             return 1;
3687         }
3688       if (purpose == ccp_jump
3689           && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3690         return 1;
3691       if (purpose == ccp_cmov
3692           && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3693         return 1;
3694       if (purpose == ccp_store_flag
3695           && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3696         return 1;
3697
3698       mode = GET_MODE_WIDER_MODE (mode);
3699     }
3700   while (mode != VOIDmode);
3701
3702   return 0;
3703 }
3704
3705 /* This function is called when we are going to emit a compare instruction that
3706    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3707
3708    *PMODE is the mode of the inputs (in case they are const_int).
3709    *PUNSIGNEDP nonzero says that the operands are unsigned;
3710    this matters if they need to be widened.
3711
3712    If they have mode BLKmode, then SIZE specifies the size of both operands.
3713
3714    This function performs all the setup necessary so that the caller only has
3715    to emit a single comparison insn.  This setup can involve doing a BLKmode
3716    comparison or emitting a library call to perform the comparison if no insn
3717    is available to handle it.
3718    The values which are passed in through pointers can be modified; the caller
3719    should perform the comparison on the modified values.  */
3720
3721 static void
3722 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3723                   enum machine_mode *pmode, int *punsignedp,
3724                   enum can_compare_purpose purpose)
3725 {
3726   enum machine_mode mode = *pmode;
3727   rtx x = *px, y = *py;
3728   int unsignedp = *punsignedp;
3729   enum mode_class class;
3730
3731   class = GET_MODE_CLASS (mode);
3732
3733   /* They could both be VOIDmode if both args are immediate constants,
3734      but we should fold that at an earlier stage.
3735      With no special code here, this will call abort,
3736      reminding the programmer to implement such folding.  */
3737
3738   if (mode != BLKmode && flag_force_mem)
3739     {
3740       /* Load duplicate non-volatile operands once.  */
3741       if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
3742         {
3743           x = force_not_mem (x);
3744           y = x;
3745         }
3746       else
3747         {
3748           x = force_not_mem (x);
3749           y = force_not_mem (y);
3750         }
3751     }
3752
3753   /* If we are inside an appropriately-short loop and we are optimizing,
3754      force expensive constants into a register.  */
3755   if (CONSTANT_P (x) && optimize
3756       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3757     x = force_reg (mode, x);
3758
3759   if (CONSTANT_P (y) && optimize
3760       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3761     y = force_reg (mode, y);
3762
3763 #ifdef HAVE_cc0
3764   /* Abort if we have a non-canonical comparison.  The RTL documentation
3765      states that canonical comparisons are required only for targets which
3766      have cc0.  */
3767   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3768     abort ();
3769 #endif
3770
3771   /* Don't let both operands fail to indicate the mode.  */
3772   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3773     x = force_reg (mode, x);
3774
3775   /* Handle all BLKmode compares.  */
3776
3777   if (mode == BLKmode)
3778     {
3779       enum machine_mode cmp_mode, result_mode;
3780       enum insn_code cmp_code;
3781       tree length_type;
3782       rtx libfunc;
3783       rtx result;
3784       rtx opalign
3785         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3786
3787       if (size == 0)
3788         abort ();
3789
3790       /* Try to use a memory block compare insn - either cmpstr
3791          or cmpmem will do.  */
3792       for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3793            cmp_mode != VOIDmode;
3794            cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3795         {
3796           cmp_code = cmpmem_optab[cmp_mode];
3797           if (cmp_code == CODE_FOR_nothing)
3798             cmp_code = cmpstr_optab[cmp_mode];
3799           if (cmp_code == CODE_FOR_nothing)
3800             continue;
3801
3802           /* Must make sure the size fits the insn's mode.  */
3803           if ((GET_CODE (size) == CONST_INT
3804                && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3805               || (GET_MODE_BITSIZE (GET_MODE (size))
3806                   > GET_MODE_BITSIZE (cmp_mode)))
3807             continue;
3808
3809           result_mode = insn_data[cmp_code].operand[0].mode;
3810           result = gen_reg_rtx (result_mode);
3811           size = convert_to_mode (cmp_mode, size, 1);
3812           emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3813
3814           *px = result;
3815           *py = const0_rtx;
3816           *pmode = result_mode;
3817           return;
3818         }
3819
3820       /* Otherwise call a library function, memcmp.  */
3821       libfunc = memcmp_libfunc;
3822       length_type = sizetype;
3823       result_mode = TYPE_MODE (integer_type_node);
3824       cmp_mode = TYPE_MODE (length_type);
3825       size = convert_to_mode (TYPE_MODE (length_type), size,
3826                               TYPE_UNSIGNED (length_type));
3827
3828       result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3829                                         result_mode, 3,
3830                                         XEXP (x, 0), Pmode,
3831                                         XEXP (y, 0), Pmode,
3832                                         size, cmp_mode);
3833       *px = result;
3834       *py = const0_rtx;
3835       *pmode = result_mode;
3836       return;
3837     }
3838
3839   /* Don't allow operands to the compare to trap, as that can put the
3840      compare and branch in different basic blocks.  */
3841   if (flag_non_call_exceptions)
3842     {
3843       if (may_trap_p (x))
3844         x = force_reg (mode, x);
3845       if (may_trap_p (y))
3846         y = force_reg (mode, y);
3847     }
3848
3849   *px = x;
3850   *py = y;
3851   if (can_compare_p (*pcomparison, mode, purpose))
3852     return;
3853
3854   /* Handle a lib call just for the mode we are using.  */
3855
3856   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3857     {
3858       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3859       rtx result;
3860
3861       /* If we want unsigned, and this mode has a distinct unsigned
3862          comparison routine, use that.  */
3863       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3864         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3865
3866       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3867                                         word_mode, 2, x, mode, y, mode);
3868
3869       *px = result;
3870       *pmode = word_mode;
3871       if (TARGET_LIB_INT_CMP_BIASED)
3872         /* Integer comparison returns a result that must be compared
3873            against 1, so that even if we do an unsigned compare
3874            afterward, there is still a value that can represent the
3875            result "less than".  */
3876         *py = const1_rtx;
3877       else
3878         {
3879           *py = const0_rtx;
3880           *punsignedp = 1;
3881         }
3882       return;
3883     }
3884
3885   if (class == MODE_FLOAT)
3886     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3887
3888   else
3889     abort ();
3890 }
3891
3892 /* Before emitting an insn with code ICODE, make sure that X, which is going
3893    to be used for operand OPNUM of the insn, is converted from mode MODE to
3894    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3895    that it is accepted by the operand predicate.  Return the new value.  */
3896
3897 rtx
3898 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3899                  enum machine_mode wider_mode, int unsignedp)
3900 {
3901   if (mode != wider_mode)
3902     x = convert_modes (wider_mode, mode, x, unsignedp);
3903
3904   if (! (*insn_data[icode].operand[opnum].predicate)
3905       (x, insn_data[icode].operand[opnum].mode))
3906     {
3907       if (no_new_pseudos)
3908         return NULL_RTX;
3909       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3910     }
3911
3912   return x;
3913 }
3914
3915 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3916    we can do the comparison.
3917    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3918    be NULL_RTX which indicates that only a comparison is to be generated.  */
3919
3920 static void
3921 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3922                           enum rtx_code comparison, int unsignedp, rtx label)
3923 {
3924   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3925   enum mode_class class = GET_MODE_CLASS (mode);
3926   enum machine_mode wider_mode = mode;
3927
3928   /* Try combined insns first.  */
3929   do
3930     {
3931       enum insn_code icode;
3932       PUT_MODE (test, wider_mode);
3933
3934       if (label)
3935         {
3936           icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3937
3938           if (icode != CODE_FOR_nothing
3939               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3940             {
3941               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3942               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3943               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3944               return;
3945             }
3946         }
3947
3948       /* Handle some compares against zero.  */
3949       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3950       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3951         {
3952           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3953           emit_insn (GEN_FCN (icode) (x));
3954           if (label)
3955             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3956           return;
3957         }
3958
3959       /* Handle compares for which there is a directly suitable insn.  */
3960
3961       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3962       if (icode != CODE_FOR_nothing)
3963         {
3964           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3965           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3966           emit_insn (GEN_FCN (icode) (x, y));
3967           if (label)
3968             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3969           return;
3970         }
3971
3972       if (class != MODE_INT && class != MODE_FLOAT
3973           && class != MODE_COMPLEX_FLOAT)
3974         break;
3975
3976       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3977     }
3978   while (wider_mode != VOIDmode);
3979
3980   abort ();
3981 }
3982
3983 /* Generate code to compare X with Y so that the condition codes are
3984    set and to jump to LABEL if the condition is true.  If X is a
3985    constant and Y is not a constant, then the comparison is swapped to
3986    ensure that the comparison RTL has the canonical form.
3987
3988    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3989    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3990    the proper branch condition code.
3991
3992    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3993
3994    MODE is the mode of the inputs (in case they are const_int).
3995
3996    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3997    be passed unchanged to emit_cmp_insn, then potentially converted into an
3998    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3999
4000 void
4001 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4002                          enum machine_mode mode, int unsignedp, rtx label)
4003 {
4004   rtx op0 = x, op1 = y;
4005
4006   /* Swap operands and condition to ensure canonical RTL.  */
4007   if (swap_commutative_operands_p (x, y))
4008     {
4009       /* If we're not emitting a branch, this means some caller
4010          is out of sync.  */
4011       if (! label)
4012         abort ();
4013
4014       op0 = y, op1 = x;
4015       comparison = swap_condition (comparison);
4016     }
4017
4018 #ifdef HAVE_cc0
4019   /* If OP0 is still a constant, then both X and Y must be constants.  Force
4020      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
4021      RTL.  */
4022   if (CONSTANT_P (op0))
4023     op0 = force_reg (mode, op0);
4024 #endif
4025
4026   if (unsignedp)
4027     comparison = unsigned_condition (comparison);
4028
4029   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
4030                     ccp_jump);
4031   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
4032 }
4033
4034 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
4035
4036 void
4037 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4038                enum machine_mode mode, int unsignedp)
4039 {
4040   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
4041 }
4042 \f
4043 /* Emit a library call comparison between floating point X and Y.
4044    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4045
4046 static void
4047 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
4048                        enum machine_mode *pmode, int *punsignedp)
4049 {
4050   enum rtx_code comparison = *pcomparison;
4051   enum rtx_code swapped = swap_condition (comparison);
4052   enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4053   rtx x = *px;
4054   rtx y = *py;
4055   enum machine_mode orig_mode = GET_MODE (x);
4056   enum machine_mode mode;
4057   rtx value, target, insns, equiv;
4058   rtx libfunc = 0;
4059   bool reversed_p = false;
4060
4061   for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
4062     {
4063       if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
4064         break;
4065
4066       if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
4067         {
4068           rtx tmp;
4069           tmp = x; x = y; y = tmp;
4070           comparison = swapped;
4071           break;
4072         }
4073
4074       if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
4075           && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4076         {
4077           comparison = reversed;
4078           reversed_p = true;
4079           break;
4080         }
4081     }
4082  
4083   if (mode == VOIDmode)
4084     abort ();
4085
4086   if (mode != orig_mode)
4087     {
4088       x = convert_to_mode (mode, x, 0);
4089       y = convert_to_mode (mode, y, 0);
4090     }
4091
4092   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4093      the RTL.  The allows the RTL optimizers to delete the libcall if the
4094      condition can be determined at compile-time.  */
4095   if (comparison == UNORDERED)
4096     {
4097       rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
4098       equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
4099       equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
4100                                     temp, const_true_rtx, equiv);
4101     }
4102   else
4103     {
4104       equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
4105       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4106         {
4107           rtx true_rtx, false_rtx;
4108
4109           switch (comparison)
4110             {
4111             case EQ:
4112               true_rtx = const0_rtx;
4113               false_rtx = const_true_rtx;
4114               break;
4115
4116             case NE:
4117               true_rtx = const_true_rtx;
4118               false_rtx = const0_rtx;
4119               break;
4120
4121             case GT:
4122               true_rtx = const1_rtx;
4123               false_rtx = const0_rtx;
4124               break;
4125
4126             case GE:
4127               true_rtx = const0_rtx;
4128               false_rtx = constm1_rtx;
4129               break;
4130
4131             case LT:
4132               true_rtx = constm1_rtx;
4133               false_rtx = const0_rtx;
4134               break;
4135
4136             case LE:
4137               true_rtx = const0_rtx;
4138               false_rtx = const1_rtx;
4139               break;
4140
4141             default:
4142               abort ();
4143             }
4144           equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
4145                                         equiv, true_rtx, false_rtx);
4146         }
4147     }
4148
4149   start_sequence ();
4150   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4151                                    word_mode, 2, x, mode, y, mode);
4152   insns = get_insns ();
4153   end_sequence ();
4154
4155   target = gen_reg_rtx (word_mode);
4156   emit_libcall_block (insns, target, value, equiv);
4157
4158   if (comparison == UNORDERED
4159       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4160     comparison = reversed_p ? EQ : NE;
4161
4162   *px = target;
4163   *py = const0_rtx;
4164   *pmode = word_mode;
4165   *pcomparison = comparison;
4166   *punsignedp = 0;
4167 }
4168 \f
4169 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4170
4171 void
4172 emit_indirect_jump (rtx loc)
4173 {
4174   if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
4175          (loc, Pmode)))
4176     loc = copy_to_mode_reg (Pmode, loc);
4177
4178   emit_jump_insn (gen_indirect_jump (loc));
4179   emit_barrier ();
4180 }
4181 \f
4182 #ifdef HAVE_conditional_move
4183
4184 /* Emit a conditional move instruction if the machine supports one for that
4185    condition and machine mode.
4186
4187    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4188    the mode to use should they be constants.  If it is VOIDmode, they cannot
4189    both be constants.
4190
4191    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4192    should be stored there.  MODE is the mode to use should they be constants.
4193    If it is VOIDmode, they cannot both be constants.
4194
4195    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4196    is not supported.  */
4197
4198 rtx
4199 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4200                        enum machine_mode cmode, rtx op2, rtx op3,
4201                        enum machine_mode mode, int unsignedp)
4202 {
4203   rtx tem, subtarget, comparison, insn;
4204   enum insn_code icode;
4205   enum rtx_code reversed;
4206
4207   /* If one operand is constant, make it the second one.  Only do this
4208      if the other operand is not constant as well.  */
4209
4210   if (swap_commutative_operands_p (op0, op1))
4211     {
4212       tem = op0;
4213       op0 = op1;
4214       op1 = tem;
4215       code = swap_condition (code);
4216     }
4217
4218   /* get_condition will prefer to generate LT and GT even if the old
4219      comparison was against zero, so undo that canonicalization here since
4220      comparisons against zero are cheaper.  */
4221   if (code == LT && op1 == const1_rtx)
4222     code = LE, op1 = const0_rtx;
4223   else if (code == GT && op1 == constm1_rtx)
4224     code = GE, op1 = const0_rtx;
4225
4226   if (cmode == VOIDmode)
4227     cmode = GET_MODE (op0);
4228
4229   if (swap_commutative_operands_p (op2, op3)
4230       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4231           != UNKNOWN))
4232     {
4233       tem = op2;
4234       op2 = op3;
4235       op3 = tem;
4236       code = reversed;
4237     }
4238
4239   if (mode == VOIDmode)
4240     mode = GET_MODE (op2);
4241
4242   icode = movcc_gen_code[mode];
4243
4244   if (icode == CODE_FOR_nothing)
4245     return 0;
4246
4247   if (flag_force_mem)
4248     {
4249       op2 = force_not_mem (op2);
4250       op3 = force_not_mem (op3);
4251     }
4252
4253   if (!target)
4254     target = gen_reg_rtx (mode);
4255
4256   subtarget = target;
4257
4258   /* If the insn doesn't accept these operands, put them in pseudos.  */
4259
4260   if (! (*insn_data[icode].operand[0].predicate)
4261       (subtarget, insn_data[icode].operand[0].mode))
4262     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4263
4264   if (! (*insn_data[icode].operand[2].predicate)
4265       (op2, insn_data[icode].operand[2].mode))
4266     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4267
4268   if (! (*insn_data[icode].operand[3].predicate)
4269       (op3, insn_data[icode].operand[3].mode))
4270     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4271
4272   /* Everything should now be in the suitable form, so emit the compare insn
4273      and then the conditional move.  */
4274
4275   comparison
4276     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4277
4278   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4279   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4280      return NULL and let the caller figure out how best to deal with this
4281      situation.  */
4282   if (GET_CODE (comparison) != code)
4283     return NULL_RTX;
4284
4285   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4286
4287   /* If that failed, then give up.  */
4288   if (insn == 0)
4289     return 0;
4290
4291   emit_insn (insn);
4292
4293   if (subtarget != target)
4294     convert_move (target, subtarget, 0);
4295
4296   return target;
4297 }
4298
4299 /* Return nonzero if a conditional move of mode MODE is supported.
4300
4301    This function is for combine so it can tell whether an insn that looks
4302    like a conditional move is actually supported by the hardware.  If we
4303    guess wrong we lose a bit on optimization, but that's it.  */
4304 /* ??? sparc64 supports conditionally moving integers values based on fp
4305    comparisons, and vice versa.  How do we handle them?  */
4306
4307 int
4308 can_conditionally_move_p (enum machine_mode mode)
4309 {
4310   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4311     return 1;
4312
4313   return 0;
4314 }
4315
4316 #endif /* HAVE_conditional_move */
4317
4318 /* Emit a conditional addition instruction if the machine supports one for that
4319    condition and machine mode.
4320
4321    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4322    the mode to use should they be constants.  If it is VOIDmode, they cannot
4323    both be constants.
4324
4325    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4326    should be stored there.  MODE is the mode to use should they be constants.
4327    If it is VOIDmode, they cannot both be constants.
4328
4329    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4330    is not supported.  */
4331
4332 rtx
4333 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4334                       enum machine_mode cmode, rtx op2, rtx op3,
4335                       enum machine_mode mode, int unsignedp)
4336 {
4337   rtx tem, subtarget, comparison, insn;
4338   enum insn_code icode;
4339   enum rtx_code reversed;
4340
4341   /* If one operand is constant, make it the second one.  Only do this
4342      if the other operand is not constant as well.  */
4343
4344   if (swap_commutative_operands_p (op0, op1))
4345     {
4346       tem = op0;
4347       op0 = op1;
4348       op1 = tem;
4349       code = swap_condition (code);
4350     }
4351
4352   /* get_condition will prefer to generate LT and GT even if the old
4353      comparison was against zero, so undo that canonicalization here since
4354      comparisons against zero are cheaper.  */
4355   if (code == LT && op1 == const1_rtx)
4356     code = LE, op1 = const0_rtx;
4357   else if (code == GT && op1 == constm1_rtx)
4358     code = GE, op1 = const0_rtx;
4359
4360   if (cmode == VOIDmode)
4361     cmode = GET_MODE (op0);
4362
4363   if (swap_commutative_operands_p (op2, op3)
4364       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4365           != UNKNOWN))
4366     {
4367       tem = op2;
4368       op2 = op3;
4369       op3 = tem;
4370       code = reversed;
4371     }
4372
4373   if (mode == VOIDmode)
4374     mode = GET_MODE (op2);
4375
4376   icode = addcc_optab->handlers[(int) mode].insn_code;
4377
4378   if (icode == CODE_FOR_nothing)
4379     return 0;
4380
4381   if (flag_force_mem)
4382     {
4383       op2 = force_not_mem (op2);
4384       op3 = force_not_mem (op3);
4385     }
4386
4387   if (!target)
4388     target = gen_reg_rtx (mode);
4389
4390   /* If the insn doesn't accept these operands, put them in pseudos.  */
4391
4392   if (! (*insn_data[icode].operand[0].predicate)
4393       (target, insn_data[icode].operand[0].mode))
4394     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4395   else
4396     subtarget = target;
4397
4398   if (! (*insn_data[icode].operand[2].predicate)
4399       (op2, insn_data[icode].operand[2].mode))
4400     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4401
4402   if (! (*insn_data[icode].operand[3].predicate)
4403       (op3, insn_data[icode].operand[3].mode))
4404     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4405
4406   /* Everything should now be in the suitable form, so emit the compare insn
4407      and then the conditional move.  */
4408
4409   comparison
4410     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4411
4412   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4413   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4414      return NULL and let the caller figure out how best to deal with this
4415      situation.  */
4416   if (GET_CODE (comparison) != code)
4417     return NULL_RTX;
4418
4419   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4420
4421   /* If that failed, then give up.  */
4422   if (insn == 0)
4423     return 0;
4424
4425   emit_insn (insn);
4426
4427   if (subtarget != target)
4428     convert_move (target, subtarget, 0);
4429
4430   return target;
4431 }
4432 \f
4433 /* These functions attempt to generate an insn body, rather than
4434    emitting the insn, but if the gen function already emits them, we
4435    make no attempt to turn them back into naked patterns.  */
4436
4437 /* Generate and return an insn body to add Y to X.  */
4438
4439 rtx
4440 gen_add2_insn (rtx x, rtx y)
4441 {
4442   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4443
4444   if (! ((*insn_data[icode].operand[0].predicate)
4445          (x, insn_data[icode].operand[0].mode))
4446       || ! ((*insn_data[icode].operand[1].predicate)
4447             (x, insn_data[icode].operand[1].mode))
4448       || ! ((*insn_data[icode].operand[2].predicate)
4449             (y, insn_data[icode].operand[2].mode)))
4450     abort ();
4451
4452   return (GEN_FCN (icode) (x, x, y));
4453 }
4454
4455 /* Generate and return an insn body to add r1 and c,
4456    storing the result in r0.  */
4457 rtx
4458 gen_add3_insn (rtx r0, rtx r1, rtx c)
4459 {
4460   int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4461
4462   if (icode == CODE_FOR_nothing
4463       || ! ((*insn_data[icode].operand[0].predicate)
4464             (r0, insn_data[icode].operand[0].mode))
4465       || ! ((*insn_data[icode].operand[1].predicate)
4466             (r1, insn_data[icode].operand[1].mode))
4467       || ! ((*insn_data[icode].operand[2].predicate)
4468             (c, insn_data[icode].operand[2].mode)))
4469     return NULL_RTX;
4470
4471   return (GEN_FCN (icode) (r0, r1, c));
4472 }
4473
4474 int
4475 have_add2_insn (rtx x, rtx y)
4476 {
4477   int icode;
4478
4479   if (GET_MODE (x) == VOIDmode)
4480     abort ();
4481
4482   icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4483
4484   if (icode == CODE_FOR_nothing)
4485     return 0;
4486
4487   if (! ((*insn_data[icode].operand[0].predicate)
4488          (x, insn_data[icode].operand[0].mode))
4489       || ! ((*insn_data[icode].operand[1].predicate)
4490             (x, insn_data[icode].operand[1].mode))
4491       || ! ((*insn_data[icode].operand[2].predicate)
4492             (y, insn_data[icode].operand[2].mode)))
4493     return 0;
4494
4495   return 1;
4496 }
4497
4498 /* Generate and return an insn body to subtract Y from X.  */
4499
4500 rtx
4501 gen_sub2_insn (rtx x, rtx y)
4502 {
4503   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4504
4505   if (! ((*insn_data[icode].operand[0].predicate)
4506          (x, insn_data[icode].operand[0].mode))
4507       || ! ((*insn_data[icode].operand[1].predicate)
4508             (x, insn_data[icode].operand[1].mode))
4509       || ! ((*insn_data[icode].operand[2].predicate)
4510             (y, insn_data[icode].operand[2].mode)))
4511     abort ();
4512
4513   return (GEN_FCN (icode) (x, x, y));
4514 }
4515
4516 /* Generate and return an insn body to subtract r1 and c,
4517    storing the result in r0.  */
4518 rtx
4519 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4520 {
4521   int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4522
4523   if (icode == CODE_FOR_nothing
4524       || ! ((*insn_data[icode].operand[0].predicate)
4525             (r0, insn_data[icode].operand[0].mode))
4526       || ! ((*insn_data[icode].operand[1].predicate)
4527             (r1, insn_data[icode].operand[1].mode))
4528       || ! ((*insn_data[icode].operand[2].predicate)
4529             (c, insn_data[icode].operand[2].mode)))
4530     return NULL_RTX;
4531
4532   return (GEN_FCN (icode) (r0, r1, c));
4533 }
4534
4535 int
4536 have_sub2_insn (rtx x, rtx y)
4537 {
4538   int icode;
4539
4540   if (GET_MODE (x) == VOIDmode)
4541     abort ();
4542
4543   icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4544
4545   if (icode == CODE_FOR_nothing)
4546     return 0;
4547
4548   if (! ((*insn_data[icode].operand[0].predicate)
4549          (x, insn_data[icode].operand[0].mode))
4550       || ! ((*insn_data[icode].operand[1].predicate)
4551             (x, insn_data[icode].operand[1].mode))
4552       || ! ((*insn_data[icode].operand[2].predicate)
4553             (y, insn_data[icode].operand[2].mode)))
4554     return 0;
4555
4556   return 1;
4557 }
4558
4559 /* Generate the body of an instruction to copy Y into X.
4560    It may be a list of insns, if one insn isn't enough.  */
4561
4562 rtx
4563 gen_move_insn (rtx x, rtx y)
4564 {
4565   rtx seq;
4566
4567   start_sequence ();
4568   emit_move_insn_1 (x, y);
4569   seq = get_insns ();
4570   end_sequence ();
4571   return seq;
4572 }
4573 \f
4574 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4575    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4576    no such operation exists, CODE_FOR_nothing will be returned.  */
4577
4578 enum insn_code
4579 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4580               int unsignedp)
4581 {
4582   convert_optab tab;
4583 #ifdef HAVE_ptr_extend
4584   if (unsignedp < 0)
4585     return CODE_FOR_ptr_extend;
4586 #endif
4587
4588   tab = unsignedp ? zext_optab : sext_optab;
4589   return tab->handlers[to_mode][from_mode].insn_code;
4590 }
4591
4592 /* Generate the body of an insn to extend Y (with mode MFROM)
4593    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4594
4595 rtx
4596 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4597                  enum machine_mode mfrom, int unsignedp)
4598 {
4599   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4600   return GEN_FCN (icode) (x, y);
4601 }
4602 \f
4603 /* can_fix_p and can_float_p say whether the target machine
4604    can directly convert a given fixed point type to
4605    a given floating point type, or vice versa.
4606    The returned value is the CODE_FOR_... value to use,
4607    or CODE_FOR_nothing if these modes cannot be directly converted.
4608
4609    *TRUNCP_PTR is set to 1 if it is necessary to output
4610    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4611
4612 static enum insn_code
4613 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4614            int unsignedp, int *truncp_ptr)
4615 {
4616   convert_optab tab;
4617   enum insn_code icode;
4618
4619   tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4620   icode = tab->handlers[fixmode][fltmode].insn_code;
4621   if (icode != CODE_FOR_nothing)
4622     {
4623       *truncp_ptr = 0;
4624       return icode;
4625     }
4626
4627   /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4628      for this to work. We need to rework the fix* and ftrunc* patterns
4629      and documentation.  */
4630   tab = unsignedp ? ufix_optab : sfix_optab;
4631   icode = tab->handlers[fixmode][fltmode].insn_code;
4632   if (icode != CODE_FOR_nothing
4633       && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4634     {
4635       *truncp_ptr = 1;
4636       return icode;
4637     }
4638
4639   *truncp_ptr = 0;
4640   return CODE_FOR_nothing;
4641 }
4642
4643 static enum insn_code
4644 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4645              int unsignedp)
4646 {
4647   convert_optab tab;
4648
4649   tab = unsignedp ? ufloat_optab : sfloat_optab;
4650   return tab->handlers[fltmode][fixmode].insn_code;
4651 }
4652 \f
4653 /* Generate code to convert FROM to floating point
4654    and store in TO.  FROM must be fixed point and not VOIDmode.
4655    UNSIGNEDP nonzero means regard FROM as unsigned.
4656    Normally this is done by correcting the final value
4657    if it is negative.  */
4658
4659 void
4660 expand_float (rtx to, rtx from, int unsignedp)
4661 {
4662   enum insn_code icode;
4663   rtx target = to;
4664   enum machine_mode fmode, imode;
4665
4666   /* Crash now, because we won't be able to decide which mode to use.  */
4667   if (GET_MODE (from) == VOIDmode)
4668     abort ();
4669
4670   /* Look for an insn to do the conversion.  Do it in the specified
4671      modes if possible; otherwise convert either input, output or both to
4672      wider mode.  If the integer mode is wider than the mode of FROM,
4673      we can do the conversion signed even if the input is unsigned.  */
4674
4675   for (fmode = GET_MODE (to); fmode != VOIDmode;
4676        fmode = GET_MODE_WIDER_MODE (fmode))
4677     for (imode = GET_MODE (from); imode != VOIDmode;
4678          imode = GET_MODE_WIDER_MODE (imode))
4679       {
4680         int doing_unsigned = unsignedp;
4681
4682         if (fmode != GET_MODE (to)
4683             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4684           continue;
4685
4686         icode = can_float_p (fmode, imode, unsignedp);
4687         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4688           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4689
4690         if (icode != CODE_FOR_nothing)
4691           {
4692             if (imode != GET_MODE (from))
4693               from = convert_to_mode (imode, from, unsignedp);
4694
4695             if (fmode != GET_MODE (to))
4696               target = gen_reg_rtx (fmode);
4697
4698             emit_unop_insn (icode, target, from,
4699                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4700
4701             if (target != to)
4702               convert_move (to, target, 0);
4703             return;
4704           }
4705       }
4706
4707   /* Unsigned integer, and no way to convert directly.
4708      Convert as signed, then conditionally adjust the result.  */
4709   if (unsignedp)
4710     {
4711       rtx label = gen_label_rtx ();
4712       rtx temp;
4713       REAL_VALUE_TYPE offset;
4714
4715       if (flag_force_mem)
4716         from = force_not_mem (from);
4717
4718       /* Look for a usable floating mode FMODE wider than the source and at
4719          least as wide as the target.  Using FMODE will avoid rounding woes
4720          with unsigned values greater than the signed maximum value.  */
4721
4722       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4723            fmode = GET_MODE_WIDER_MODE (fmode))
4724         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4725             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4726           break;
4727
4728       if (fmode == VOIDmode)
4729         {
4730           /* There is no such mode.  Pretend the target is wide enough.  */
4731           fmode = GET_MODE (to);
4732
4733           /* Avoid double-rounding when TO is narrower than FROM.  */
4734           if ((significand_size (fmode) + 1)
4735               < GET_MODE_BITSIZE (GET_MODE (from)))
4736             {
4737               rtx temp1;
4738               rtx neglabel = gen_label_rtx ();
4739
4740               /* Don't use TARGET if it isn't a register, is a hard register,
4741                  or is the wrong mode.  */
4742               if (!REG_P (target)
4743                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4744                   || GET_MODE (target) != fmode)
4745                 target = gen_reg_rtx (fmode);
4746
4747               imode = GET_MODE (from);
4748               do_pending_stack_adjust ();
4749
4750               /* Test whether the sign bit is set.  */
4751               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4752                                        0, neglabel);
4753
4754               /* The sign bit is not set.  Convert as signed.  */
4755               expand_float (target, from, 0);
4756               emit_jump_insn (gen_jump (label));
4757               emit_barrier ();
4758
4759               /* The sign bit is set.
4760                  Convert to a usable (positive signed) value by shifting right
4761                  one bit, while remembering if a nonzero bit was shifted
4762                  out; i.e., compute  (from & 1) | (from >> 1).  */
4763
4764               emit_label (neglabel);
4765               temp = expand_binop (imode, and_optab, from, const1_rtx,
4766                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4767               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4768                                     NULL_RTX, 1);
4769               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4770                                    OPTAB_LIB_WIDEN);
4771               expand_float (target, temp, 0);
4772
4773               /* Multiply by 2 to undo the shift above.  */
4774               temp = expand_binop (fmode, add_optab, target, target,
4775                                    target, 0, OPTAB_LIB_WIDEN);
4776               if (temp != target)
4777                 emit_move_insn (target, temp);
4778
4779               do_pending_stack_adjust ();
4780               emit_label (label);
4781               goto done;
4782             }
4783         }
4784
4785       /* If we are about to do some arithmetic to correct for an
4786          unsigned operand, do it in a pseudo-register.  */
4787
4788       if (GET_MODE (to) != fmode
4789           || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4790         target = gen_reg_rtx (fmode);
4791
4792       /* Convert as signed integer to floating.  */
4793       expand_float (target, from, 0);
4794
4795       /* If FROM is negative (and therefore TO is negative),
4796          correct its value by 2**bitwidth.  */
4797
4798       do_pending_stack_adjust ();
4799       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4800                                0, label);
4801
4802
4803       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4804       temp = expand_binop (fmode, add_optab, target,
4805                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4806                            target, 0, OPTAB_LIB_WIDEN);
4807       if (temp != target)
4808         emit_move_insn (target, temp);
4809
4810       do_pending_stack_adjust ();
4811       emit_label (label);
4812       goto done;
4813     }
4814
4815   /* No hardware instruction available; call a library routine.  */
4816     {
4817       rtx libfunc;
4818       rtx insns;
4819       rtx value;
4820       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4821
4822       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4823         from = convert_to_mode (SImode, from, unsignedp);
4824
4825       if (flag_force_mem)
4826         from = force_not_mem (from);
4827
4828       libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4829       if (!libfunc)
4830         abort ();
4831
4832       start_sequence ();
4833
4834       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4835                                        GET_MODE (to), 1, from,
4836                                        GET_MODE (from));
4837       insns = get_insns ();
4838       end_sequence ();
4839
4840       emit_libcall_block (insns, target, value,
4841                           gen_rtx_FLOAT (GET_MODE (to), from));
4842     }
4843
4844  done:
4845
4846   /* Copy result to requested destination
4847      if we have been computing in a temp location.  */
4848
4849   if (target != to)
4850     {
4851       if (GET_MODE (target) == GET_MODE (to))
4852         emit_move_insn (to, target);
4853       else
4854         convert_move (to, target, 0);
4855     }
4856 }
4857 \f
4858 /* Generate code to convert FROM to fixed point and store in TO.  FROM
4859    must be floating point.  */
4860
4861 void
4862 expand_fix (rtx to, rtx from, int unsignedp)
4863 {
4864   enum insn_code icode;
4865   rtx target = to;
4866   enum machine_mode fmode, imode;
4867   int must_trunc = 0;
4868
4869   /* We first try to find a pair of modes, one real and one integer, at
4870      least as wide as FROM and TO, respectively, in which we can open-code
4871      this conversion.  If the integer mode is wider than the mode of TO,
4872      we can do the conversion either signed or unsigned.  */
4873
4874   for (fmode = GET_MODE (from); fmode != VOIDmode;
4875        fmode = GET_MODE_WIDER_MODE (fmode))
4876     for (imode = GET_MODE (to); imode != VOIDmode;
4877          imode = GET_MODE_WIDER_MODE (imode))
4878       {
4879         int doing_unsigned = unsignedp;
4880
4881         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4882         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4883           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4884
4885         if (icode != CODE_FOR_nothing)
4886           {
4887             if (fmode != GET_MODE (from))
4888               from = convert_to_mode (fmode, from, 0);
4889
4890             if (must_trunc)
4891               {
4892                 rtx temp = gen_reg_rtx (GET_MODE (from));
4893                 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4894                                     temp, 0);
4895               }
4896
4897             if (imode != GET_MODE (to))
4898               target = gen_reg_rtx (imode);
4899
4900             emit_unop_insn (icode, target, from,
4901                             doing_unsigned ? UNSIGNED_FIX : FIX);
4902             if (target != to)
4903               convert_move (to, target, unsignedp);
4904             return;
4905           }
4906       }
4907
4908   /* For an unsigned conversion, there is one more way to do it.
4909      If we have a signed conversion, we generate code that compares
4910      the real value to the largest representable positive number.  If if
4911      is smaller, the conversion is done normally.  Otherwise, subtract
4912      one plus the highest signed number, convert, and add it back.
4913
4914      We only need to check all real modes, since we know we didn't find
4915      anything with a wider integer mode.
4916
4917      This code used to extend FP value into mode wider than the destination.
4918      This is not needed.  Consider, for instance conversion from SFmode
4919      into DImode.
4920
4921      The hot path trought the code is dealing with inputs smaller than 2^63
4922      and doing just the conversion, so there is no bits to lose.
4923
4924      In the other path we know the value is positive in the range 2^63..2^64-1
4925      inclusive.  (as for other imput overflow happens and result is undefined)
4926      So we know that the most important bit set in mantissa corresponds to
4927      2^63.  The subtraction of 2^63 should not generate any rounding as it
4928      simply clears out that bit.  The rest is trivial.  */
4929
4930   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4931     for (fmode = GET_MODE (from); fmode != VOIDmode;
4932          fmode = GET_MODE_WIDER_MODE (fmode))
4933       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4934                                          &must_trunc))
4935         {
4936           int bitsize;
4937           REAL_VALUE_TYPE offset;
4938           rtx limit, lab1, lab2, insn;
4939
4940           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4941           real_2expN (&offset, bitsize - 1);
4942           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4943           lab1 = gen_label_rtx ();
4944           lab2 = gen_label_rtx ();
4945
4946           if (flag_force_mem)
4947             from = force_not_mem (from);
4948
4949           if (fmode != GET_MODE (from))
4950             from = convert_to_mode (fmode, from, 0);
4951
4952           /* See if we need to do the subtraction.  */
4953           do_pending_stack_adjust ();
4954           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4955                                    0, lab1);
4956
4957           /* If not, do the signed "fix" and branch around fixup code.  */
4958           expand_fix (to, from, 0);
4959           emit_jump_insn (gen_jump (lab2));
4960           emit_barrier ();
4961
4962           /* Otherwise, subtract 2**(N-1), convert to signed number,
4963              then add 2**(N-1).  Do the addition using XOR since this
4964              will often generate better code.  */
4965           emit_label (lab1);
4966           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4967                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
4968           expand_fix (to, target, 0);
4969           target = expand_binop (GET_MODE (to), xor_optab, to,
4970                                  gen_int_mode
4971                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
4972                                   GET_MODE (to)),
4973                                  to, 1, OPTAB_LIB_WIDEN);
4974
4975           if (target != to)
4976             emit_move_insn (to, target);
4977
4978           emit_label (lab2);
4979
4980           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4981               != CODE_FOR_nothing)
4982             {
4983               /* Make a place for a REG_NOTE and add it.  */
4984               insn = emit_move_insn (to, to);
4985               set_unique_reg_note (insn,
4986                                    REG_EQUAL,
4987                                    gen_rtx_fmt_e (UNSIGNED_FIX,
4988                                                   GET_MODE (to),
4989                                                   copy_rtx (from)));
4990             }
4991
4992           return;
4993         }
4994
4995   /* We can't do it with an insn, so use a library call.  But first ensure
4996      that the mode of TO is at least as wide as SImode, since those are the
4997      only library calls we know about.  */
4998
4999   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5000     {
5001       target = gen_reg_rtx (SImode);
5002
5003       expand_fix (target, from, unsignedp);
5004     }
5005   else
5006     {
5007       rtx insns;
5008       rtx value;
5009       rtx libfunc;
5010       
5011       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5012       libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
5013       if (!libfunc)
5014         abort ();
5015
5016       if (flag_force_mem)
5017         from = force_not_mem (from);
5018
5019       start_sequence ();
5020
5021       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5022                                        GET_MODE (to), 1, from,
5023                                        GET_MODE (from));
5024       insns = get_insns ();
5025       end_sequence ();
5026
5027       emit_libcall_block (insns, target, value,
5028                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5029                                          GET_MODE (to), from));
5030     }
5031
5032   if (target != to)
5033     {
5034       if (GET_MODE (to) == GET_MODE (target))
5035         emit_move_insn (to, target);
5036       else
5037         convert_move (to, target, 0);
5038     }
5039 }
5040 \f
5041 /* Report whether we have an instruction to perform the operation
5042    specified by CODE on operands of mode MODE.  */
5043 int
5044 have_insn_for (enum rtx_code code, enum machine_mode mode)
5045 {
5046   return (code_to_optab[(int) code] != 0
5047           && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
5048               != CODE_FOR_nothing));
5049 }
5050
5051 /* Create a blank optab.  */
5052 static optab
5053 new_optab (void)
5054 {
5055   int i;
5056   optab op = ggc_alloc (sizeof (struct optab));
5057   for (i = 0; i < NUM_MACHINE_MODES; i++)
5058     {
5059       op->handlers[i].insn_code = CODE_FOR_nothing;
5060       op->handlers[i].libfunc = 0;
5061     }
5062
5063   return op;
5064 }
5065
5066 static convert_optab
5067 new_convert_optab (void)
5068 {
5069   int i, j;
5070   convert_optab op = ggc_alloc (sizeof (struct convert_optab));
5071   for (i = 0; i < NUM_MACHINE_MODES; i++)
5072     for (j = 0; j < NUM_MACHINE_MODES; j++)
5073       {
5074         op->handlers[i][j].insn_code = CODE_FOR_nothing;
5075         op->handlers[i][j].libfunc = 0;
5076       }
5077   return op;
5078 }
5079
5080 /* Same, but fill in its code as CODE, and write it into the
5081    code_to_optab table.  */
5082 static inline optab
5083 init_optab (enum rtx_code code)
5084 {
5085   optab op = new_optab ();
5086   op->code = code;
5087   code_to_optab[(int) code] = op;
5088   return op;
5089 }
5090
5091 /* Same, but fill in its code as CODE, and do _not_ write it into
5092    the code_to_optab table.  */
5093 static inline optab
5094 init_optabv (enum rtx_code code)
5095 {
5096   optab op = new_optab ();
5097   op->code = code;
5098   return op;
5099 }
5100
5101 /* Conversion optabs never go in the code_to_optab table.  */
5102 static inline convert_optab
5103 init_convert_optab (enum rtx_code code)
5104 {
5105   convert_optab op = new_convert_optab ();
5106   op->code = code;
5107   return op;
5108 }
5109
5110 /* Initialize the libfunc fields of an entire group of entries in some
5111    optab.  Each entry is set equal to a string consisting of a leading
5112    pair of underscores followed by a generic operation name followed by
5113    a mode name (downshifted to lowercase) followed by a single character
5114    representing the number of operands for the given operation (which is
5115    usually one of the characters '2', '3', or '4').
5116
5117    OPTABLE is the table in which libfunc fields are to be initialized.
5118    FIRST_MODE is the first machine mode index in the given optab to
5119      initialize.
5120    LAST_MODE is the last machine mode index in the given optab to
5121      initialize.
5122    OPNAME is the generic (string) name of the operation.
5123    SUFFIX is the character which specifies the number of operands for
5124      the given generic operation.
5125 */
5126
5127 static void
5128 init_libfuncs (optab optable, int first_mode, int last_mode,
5129                const char *opname, int suffix)
5130 {
5131   int mode;
5132   unsigned opname_len = strlen (opname);
5133
5134   for (mode = first_mode; (int) mode <= (int) last_mode;
5135        mode = (enum machine_mode) ((int) mode + 1))
5136     {
5137       const char *mname = GET_MODE_NAME (mode);
5138       unsigned mname_len = strlen (mname);
5139       char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5140       char *p;
5141       const char *q;
5142
5143       p = libfunc_name;
5144       *p++ = '_';
5145       *p++ = '_';
5146       for (q = opname; *q; )
5147         *p++ = *q++;
5148       for (q = mname; *q; q++)
5149         *p++ = TOLOWER (*q);
5150       *p++ = suffix;
5151       *p = '\0';
5152
5153       optable->handlers[(int) mode].libfunc
5154         = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5155     }
5156 }
5157
5158 /* Initialize the libfunc fields of an entire group of entries in some
5159    optab which correspond to all integer mode operations.  The parameters
5160    have the same meaning as similarly named ones for the `init_libfuncs'
5161    routine.  (See above).  */
5162
5163 static void
5164 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5165 {
5166   int maxsize = 2*BITS_PER_WORD;
5167   if (maxsize < LONG_LONG_TYPE_SIZE)
5168     maxsize = LONG_LONG_TYPE_SIZE;
5169   init_libfuncs (optable, word_mode,
5170                  mode_for_size (maxsize, MODE_INT, 0),
5171                  opname, suffix);
5172 }
5173
5174 /* Initialize the libfunc fields of an entire group of entries in some
5175    optab which correspond to all real mode operations.  The parameters
5176    have the same meaning as similarly named ones for the `init_libfuncs'
5177    routine.  (See above).  */
5178
5179 static void
5180 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5181 {
5182   init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5183 }
5184
5185 /* Initialize the libfunc fields of an entire group of entries of an
5186    inter-mode-class conversion optab.  The string formation rules are
5187    similar to the ones for init_libfuncs, above, but instead of having
5188    a mode name and an operand count these functions have two mode names
5189    and no operand count.  */
5190 static void
5191 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5192                                enum mode_class from_class,
5193                                enum mode_class to_class)
5194 {
5195   enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5196   enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5197   size_t opname_len = strlen (opname);
5198   size_t max_mname_len = 0;
5199
5200   enum machine_mode fmode, tmode;
5201   const char *fname, *tname;
5202   const char *q;
5203   char *libfunc_name, *suffix;
5204   char *p;
5205
5206   for (fmode = first_from_mode;
5207        fmode != VOIDmode;
5208        fmode = GET_MODE_WIDER_MODE (fmode))
5209     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5210
5211   for (tmode = first_to_mode;
5212        tmode != VOIDmode;
5213        tmode = GET_MODE_WIDER_MODE (tmode))
5214     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5215
5216   libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5217   libfunc_name[0] = '_';
5218   libfunc_name[1] = '_';
5219   memcpy (&libfunc_name[2], opname, opname_len);
5220   suffix = libfunc_name + opname_len + 2;
5221
5222   for (fmode = first_from_mode; fmode != VOIDmode;
5223        fmode = GET_MODE_WIDER_MODE (fmode))
5224     for (tmode = first_to_mode; tmode != VOIDmode;
5225          tmode = GET_MODE_WIDER_MODE (tmode))
5226       {
5227         fname = GET_MODE_NAME (fmode);
5228         tname = GET_MODE_NAME (tmode);
5229
5230         p = suffix;
5231         for (q = fname; *q; p++, q++)
5232           *p = TOLOWER (*q);
5233         for (q = tname; *q; p++, q++)
5234           *p = TOLOWER (*q);
5235
5236         *p = '\0';
5237
5238         tab->handlers[tmode][fmode].libfunc
5239           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5240                                                 p - libfunc_name));
5241       }
5242 }
5243
5244 /* Initialize the libfunc fields of an entire group of entries of an
5245    intra-mode-class conversion optab.  The string formation rules are
5246    similar to the ones for init_libfunc, above.  WIDENING says whether
5247    the optab goes from narrow to wide modes or vice versa.  These functions
5248    have two mode names _and_ an operand count.  */
5249 static void
5250 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5251                                enum mode_class class, bool widening)
5252 {
5253   enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5254   size_t opname_len = strlen (opname);
5255   size_t max_mname_len = 0;
5256
5257   enum machine_mode nmode, wmode;
5258   const char *nname, *wname;
5259   const char *q;
5260   char *libfunc_name, *suffix;
5261   char *p;
5262
5263   for (nmode = first_mode; nmode != VOIDmode;
5264        nmode = GET_MODE_WIDER_MODE (nmode))
5265     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5266
5267   libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5268   libfunc_name[0] = '_';
5269   libfunc_name[1] = '_';
5270   memcpy (&libfunc_name[2], opname, opname_len);
5271   suffix = libfunc_name + opname_len + 2;
5272
5273   for (nmode = first_mode; nmode != VOIDmode;
5274        nmode = GET_MODE_WIDER_MODE (nmode))
5275     for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5276          wmode = GET_MODE_WIDER_MODE (wmode))
5277       {
5278         nname = GET_MODE_NAME (nmode);
5279         wname = GET_MODE_NAME (wmode);
5280
5281         p = suffix;
5282         for (q = widening ? nname : wname; *q; p++, q++)
5283           *p = TOLOWER (*q);
5284         for (q = widening ? wname : nname; *q; p++, q++)
5285           *p = TOLOWER (*q);
5286
5287         *p++ = '2';
5288         *p = '\0';
5289
5290         tab->handlers[widening ? wmode : nmode]
5291                      [widening ? nmode : wmode].libfunc
5292           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5293                                                 p - libfunc_name));
5294       }
5295 }
5296
5297
5298 rtx
5299 init_one_libfunc (const char *name)
5300 {
5301   rtx symbol;
5302
5303   /* Create a FUNCTION_DECL that can be passed to
5304      targetm.encode_section_info.  */
5305   /* ??? We don't have any type information except for this is
5306      a function.  Pretend this is "int foo()".  */
5307   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5308                           build_function_type (integer_type_node, NULL_TREE));
5309   DECL_ARTIFICIAL (decl) = 1;
5310   DECL_EXTERNAL (decl) = 1;
5311   TREE_PUBLIC (decl) = 1;
5312
5313   symbol = XEXP (DECL_RTL (decl), 0);
5314
5315   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
5316      are the flags assigned by targetm.encode_section_info.  */
5317   SYMBOL_REF_DECL (symbol) = 0;
5318
5319   return symbol;
5320 }
5321
5322 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5323    MODE to NAME, which should be either 0 or a string constant.  */
5324 void
5325 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5326 {
5327   if (name)
5328     optable->handlers[mode].libfunc = init_one_libfunc (name);
5329   else
5330     optable->handlers[mode].libfunc = 0;
5331 }
5332
5333 /* Call this to reset the function entry for one conversion optab
5334    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5335    either 0 or a string constant.  */
5336 void
5337 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5338                   enum machine_mode fmode, const char *name)
5339 {
5340   if (name)
5341     optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5342   else
5343     optable->handlers[tmode][fmode].libfunc = 0;
5344 }
5345
5346 /* Call this once to initialize the contents of the optabs
5347    appropriately for the current target machine.  */
5348
5349 void
5350 init_optabs (void)
5351 {
5352   unsigned int i;
5353
5354   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5355
5356   for (i = 0; i < NUM_RTX_CODE; i++)
5357     setcc_gen_code[i] = CODE_FOR_nothing;
5358
5359 #ifdef HAVE_conditional_move
5360   for (i = 0; i < NUM_MACHINE_MODES; i++)
5361     movcc_gen_code[i] = CODE_FOR_nothing;
5362 #endif
5363
5364   add_optab = init_optab (PLUS);
5365   addv_optab = init_optabv (PLUS);
5366   sub_optab = init_optab (MINUS);
5367   subv_optab = init_optabv (MINUS);
5368   smul_optab = init_optab (MULT);
5369   smulv_optab = init_optabv (MULT);
5370   smul_highpart_optab = init_optab (UNKNOWN);
5371   umul_highpart_optab = init_optab (UNKNOWN);
5372   smul_widen_optab = init_optab (UNKNOWN);
5373   umul_widen_optab = init_optab (UNKNOWN);
5374   sdiv_optab = init_optab (DIV);
5375   sdivv_optab = init_optabv (DIV);
5376   sdivmod_optab = init_optab (UNKNOWN);
5377   udiv_optab = init_optab (UDIV);
5378   udivmod_optab = init_optab (UNKNOWN);
5379   smod_optab = init_optab (MOD);
5380   umod_optab = init_optab (UMOD);
5381   fmod_optab = init_optab (UNKNOWN);
5382   drem_optab = init_optab (UNKNOWN);
5383   ftrunc_optab = init_optab (UNKNOWN);
5384   and_optab = init_optab (AND);
5385   ior_optab = init_optab (IOR);
5386   xor_optab = init_optab (XOR);
5387   ashl_optab = init_optab (ASHIFT);
5388   ashr_optab = init_optab (ASHIFTRT);
5389   lshr_optab = init_optab (LSHIFTRT);
5390   rotl_optab = init_optab (ROTATE);
5391   rotr_optab = init_optab (ROTATERT);
5392   smin_optab = init_optab (SMIN);
5393   smax_optab = init_optab (SMAX);
5394   umin_optab = init_optab (UMIN);
5395   umax_optab = init_optab (UMAX);
5396   pow_optab = init_optab (UNKNOWN);
5397   atan2_optab = init_optab (UNKNOWN);
5398
5399   /* These three have codes assigned exclusively for the sake of
5400      have_insn_for.  */
5401   mov_optab = init_optab (SET);
5402   movstrict_optab = init_optab (STRICT_LOW_PART);
5403   cmp_optab = init_optab (COMPARE);
5404
5405   ucmp_optab = init_optab (UNKNOWN);
5406   tst_optab = init_optab (UNKNOWN);
5407
5408   eq_optab = init_optab (EQ);
5409   ne_optab = init_optab (NE);
5410   gt_optab = init_optab (GT);
5411   ge_optab = init_optab (GE);
5412   lt_optab = init_optab (LT);
5413   le_optab = init_optab (LE);
5414   unord_optab = init_optab (UNORDERED);
5415
5416   neg_optab = init_optab (NEG);
5417   negv_optab = init_optabv (NEG);
5418   abs_optab = init_optab (ABS);
5419   absv_optab = init_optabv (ABS);
5420   addcc_optab = init_optab (UNKNOWN);
5421   one_cmpl_optab = init_optab (NOT);
5422   ffs_optab = init_optab (FFS);
5423   clz_optab = init_optab (CLZ);
5424   ctz_optab = init_optab (CTZ);
5425   popcount_optab = init_optab (POPCOUNT);
5426   parity_optab = init_optab (PARITY);
5427   sqrt_optab = init_optab (SQRT);
5428   floor_optab = init_optab (UNKNOWN);
5429   ceil_optab = init_optab (UNKNOWN);
5430   round_optab = init_optab (UNKNOWN);
5431   btrunc_optab = init_optab (UNKNOWN);
5432   nearbyint_optab = init_optab (UNKNOWN);
5433   sincos_optab = init_optab (UNKNOWN);
5434   sin_optab = init_optab (UNKNOWN);
5435   asin_optab = init_optab (UNKNOWN);
5436   cos_optab = init_optab (UNKNOWN);
5437   acos_optab = init_optab (UNKNOWN);
5438   exp_optab = init_optab (UNKNOWN);
5439   exp10_optab = init_optab (UNKNOWN);
5440   exp2_optab = init_optab (UNKNOWN);
5441   expm1_optab = init_optab (UNKNOWN);
5442   logb_optab = init_optab (UNKNOWN);
5443   ilogb_optab = init_optab (UNKNOWN);
5444   log_optab = init_optab (UNKNOWN);
5445   log10_optab = init_optab (UNKNOWN);
5446   log2_optab = init_optab (UNKNOWN);
5447   log1p_optab = init_optab (UNKNOWN);
5448   tan_optab = init_optab (UNKNOWN);
5449   atan_optab = init_optab (UNKNOWN);
5450   strlen_optab = init_optab (UNKNOWN);
5451   cbranch_optab = init_optab (UNKNOWN);
5452   cmov_optab = init_optab (UNKNOWN);
5453   cstore_optab = init_optab (UNKNOWN);
5454   push_optab = init_optab (UNKNOWN);
5455
5456   vec_extract_optab = init_optab (UNKNOWN);
5457   vec_set_optab = init_optab (UNKNOWN);
5458   vec_init_optab = init_optab (UNKNOWN);
5459   /* Conversions.  */
5460   sext_optab = init_convert_optab (SIGN_EXTEND);
5461   zext_optab = init_convert_optab (ZERO_EXTEND);
5462   trunc_optab = init_convert_optab (TRUNCATE);
5463   sfix_optab = init_convert_optab (FIX);
5464   ufix_optab = init_convert_optab (UNSIGNED_FIX);
5465   sfixtrunc_optab = init_convert_optab (UNKNOWN);
5466   ufixtrunc_optab = init_convert_optab (UNKNOWN);
5467   sfloat_optab = init_convert_optab (FLOAT);
5468   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5469
5470   for (i = 0; i < NUM_MACHINE_MODES; i++)
5471     {
5472       movmem_optab[i] = CODE_FOR_nothing;
5473       clrmem_optab[i] = CODE_FOR_nothing;
5474       cmpstr_optab[i] = CODE_FOR_nothing;
5475       cmpmem_optab[i] = CODE_FOR_nothing;
5476
5477 #ifdef HAVE_SECONDARY_RELOADS
5478       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5479 #endif
5480     }
5481
5482   /* Fill in the optabs with the insns we support.  */
5483   init_all_optabs ();
5484
5485   /* Initialize the optabs with the names of the library functions.  */
5486   if (TARGET_LIBGCC_LIBFUNCS)
5487     {
5488       init_integral_libfuncs (add_optab, "add", '3');
5489       init_floating_libfuncs (add_optab, "add", '3');
5490       init_integral_libfuncs (addv_optab, "addv", '3');
5491       init_floating_libfuncs (addv_optab, "add", '3');
5492       init_integral_libfuncs (sub_optab, "sub", '3');
5493       init_floating_libfuncs (sub_optab, "sub", '3');
5494       init_integral_libfuncs (subv_optab, "subv", '3');
5495       init_floating_libfuncs (subv_optab, "sub", '3');
5496       init_integral_libfuncs (smul_optab, "mul", '3');
5497       init_floating_libfuncs (smul_optab, "mul", '3');
5498       init_integral_libfuncs (smulv_optab, "mulv", '3');
5499       init_floating_libfuncs (smulv_optab, "mul", '3');
5500       init_integral_libfuncs (sdiv_optab, "div", '3');
5501       init_floating_libfuncs (sdiv_optab, "div", '3');
5502       init_integral_libfuncs (sdivv_optab, "divv", '3');
5503       init_integral_libfuncs (udiv_optab, "udiv", '3');
5504       init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5505       init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5506       init_integral_libfuncs (smod_optab, "mod", '3');
5507       init_integral_libfuncs (umod_optab, "umod", '3');
5508       init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5509       init_integral_libfuncs (and_optab, "and", '3');
5510       init_integral_libfuncs (ior_optab, "ior", '3');
5511       init_integral_libfuncs (xor_optab, "xor", '3');
5512       init_integral_libfuncs (ashl_optab, "ashl", '3');
5513       init_integral_libfuncs (ashr_optab, "ashr", '3');
5514       init_integral_libfuncs (lshr_optab, "lshr", '3');
5515       init_integral_libfuncs (smin_optab, "min", '3');
5516       init_floating_libfuncs (smin_optab, "min", '3');
5517       init_integral_libfuncs (smax_optab, "max", '3');
5518       init_floating_libfuncs (smax_optab, "max", '3');
5519       init_integral_libfuncs (umin_optab, "umin", '3');
5520       init_integral_libfuncs (umax_optab, "umax", '3');
5521       init_integral_libfuncs (neg_optab, "neg", '2');
5522       init_floating_libfuncs (neg_optab, "neg", '2');
5523       init_integral_libfuncs (negv_optab, "negv", '2');
5524       init_floating_libfuncs (negv_optab, "neg", '2');
5525       init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5526       init_integral_libfuncs (ffs_optab, "ffs", '2');
5527       init_integral_libfuncs (clz_optab, "clz", '2');
5528       init_integral_libfuncs (ctz_optab, "ctz", '2');
5529       init_integral_libfuncs (popcount_optab, "popcount", '2');
5530       init_integral_libfuncs (parity_optab, "parity", '2');
5531
5532       /* Comparison libcalls for integers MUST come in pairs,
5533          signed/unsigned.  */
5534       init_integral_libfuncs (cmp_optab, "cmp", '2');
5535       init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5536       init_floating_libfuncs (cmp_optab, "cmp", '2');
5537
5538       /* EQ etc are floating point only.  */
5539       init_floating_libfuncs (eq_optab, "eq", '2');
5540       init_floating_libfuncs (ne_optab, "ne", '2');
5541       init_floating_libfuncs (gt_optab, "gt", '2');
5542       init_floating_libfuncs (ge_optab, "ge", '2');
5543       init_floating_libfuncs (lt_optab, "lt", '2');
5544       init_floating_libfuncs (le_optab, "le", '2');
5545       init_floating_libfuncs (unord_optab, "unord", '2');
5546
5547       /* Conversions.  */
5548       init_interclass_conv_libfuncs (sfloat_optab, "float", 
5549                                      MODE_INT, MODE_FLOAT);
5550       init_interclass_conv_libfuncs (sfix_optab, "fix",     
5551                                      MODE_FLOAT, MODE_INT);
5552       init_interclass_conv_libfuncs (ufix_optab, "fixuns",  
5553                                      MODE_FLOAT, MODE_INT);
5554
5555       /* sext_optab is also used for FLOAT_EXTEND.  */
5556       init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5557       init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5558     }
5559
5560   /* Use cabs for double complex abs, since systems generally have cabs.
5561      Don't define any libcall for float complex, so that cabs will be used.  */
5562   if (complex_double_type_node)
5563     abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5564       = init_one_libfunc ("cabs");
5565
5566   /* The ffs function operates on `int'.  */
5567   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5568     = init_one_libfunc ("ffs");
5569
5570   abort_libfunc = init_one_libfunc ("abort");
5571   memcpy_libfunc = init_one_libfunc ("memcpy");
5572   memmove_libfunc = init_one_libfunc ("memmove");
5573   memcmp_libfunc = init_one_libfunc ("memcmp");
5574   memset_libfunc = init_one_libfunc ("memset");
5575   setbits_libfunc = init_one_libfunc ("__setbits");
5576
5577   unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5578                                             ? "_Unwind_SjLj_Resume"
5579                                             : "_Unwind_Resume");
5580 #ifndef DONT_USE_BUILTIN_SETJMP
5581   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5582   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5583 #else
5584   setjmp_libfunc = init_one_libfunc ("setjmp");
5585   longjmp_libfunc = init_one_libfunc ("longjmp");
5586 #endif
5587   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5588   unwind_sjlj_unregister_libfunc
5589     = init_one_libfunc ("_Unwind_SjLj_Unregister");
5590
5591   /* For function entry/exit instrumentation.  */
5592   profile_function_entry_libfunc
5593     = init_one_libfunc ("__cyg_profile_func_enter");
5594   profile_function_exit_libfunc
5595     = init_one_libfunc ("__cyg_profile_func_exit");
5596
5597   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5598
5599   if (HAVE_conditional_trap)
5600     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5601
5602   /* Allow the target to add more libcalls or rename some, etc.  */
5603   targetm.init_libfuncs ();
5604 }
5605
5606 #ifdef DEBUG
5607
5608 /* Print information about the current contents of the optabs on
5609    STDERR.  */
5610
5611 static void
5612 debug_optab_libfuncs (void)
5613 {
5614   int i;
5615   int j;
5616   int k;
5617
5618   /* Dump the arithmetic optabs.  */
5619   for (i = 0; i != (int) OTI_MAX; i++) 
5620     for (j = 0; j < NUM_MACHINE_MODES; ++j)
5621       {
5622         optab o;
5623         struct optab_handlers *h;
5624
5625         o = optab_table[i];
5626         h = &o->handlers[j];
5627         if (h->libfunc)
5628           {
5629             if (GET_CODE (h->libfunc) != SYMBOL_REF)
5630               abort ();
5631             fprintf (stderr, "%s\t%s:\t%s\n", 
5632                      GET_RTX_NAME (o->code),
5633                      GET_MODE_NAME (j),
5634                      XSTR (h->libfunc, 0));
5635           }
5636       }
5637
5638   /* Dump the conversion optabs.  */
5639   for (i = 0; i < (int) CTI_MAX; ++i)
5640     for (j = 0; j < NUM_MACHINE_MODES; ++j)
5641       for (k = 0; k < NUM_MACHINE_MODES; ++k)
5642         {
5643           convert_optab o;
5644           struct optab_handlers *h;
5645
5646           o = &convert_optab_table[i];
5647           h = &o->handlers[j][k];
5648           if (h->libfunc)
5649             {
5650               if (GET_CODE (h->libfunc) != SYMBOL_REF)
5651                 abort ();
5652               fprintf (stderr, "%s\t%s\t%s:\t%s\n", 
5653                        GET_RTX_NAME (o->code),
5654                        GET_MODE_NAME (j),
5655                        GET_MODE_NAME (k),
5656                        XSTR (h->libfunc, 0));
5657             }
5658         }
5659 }
5660
5661 #endif /* DEBUG */
5662
5663 \f
5664 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5665    CODE.  Return 0 on failure.  */
5666
5667 rtx
5668 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5669                rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5670 {
5671   enum machine_mode mode = GET_MODE (op1);
5672   enum insn_code icode;
5673   rtx insn;
5674
5675   if (!HAVE_conditional_trap)
5676     return 0;
5677
5678   if (mode == VOIDmode)
5679     return 0;
5680
5681   icode = cmp_optab->handlers[(int) mode].insn_code;
5682   if (icode == CODE_FOR_nothing)
5683     return 0;
5684
5685   start_sequence ();
5686   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5687   op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5688   if (!op1 || !op2)
5689     {
5690       end_sequence ();
5691       return 0;
5692     }
5693   emit_insn (GEN_FCN (icode) (op1, op2));
5694
5695   PUT_CODE (trap_rtx, code);
5696   insn = gen_conditional_trap (trap_rtx, tcode);
5697   if (insn)
5698     {
5699       emit_insn (insn);
5700       insn = get_insns ();
5701     }
5702   end_sequence ();
5703
5704   return insn;
5705 }
5706
5707 #include "gt-optabs.h"