OSDN Git Service

041ec928f1523666c7630450643e8c4bdb2815f7
[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 /* Wrapper around expand_binop which takes an rtx code to specify
632    the operation to perform, not an optab pointer.  All other
633    arguments are the same.  */
634 rtx
635 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
636                      rtx op1, rtx target, int unsignedp,
637                      enum optab_methods methods)
638 {
639   optab binop = code_to_optab[(int) code];
640   if (binop == 0)
641     abort ();
642
643   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
644 }
645
646 /* Generate code to perform an operation specified by BINOPTAB
647    on operands OP0 and OP1, with result having machine-mode MODE.
648
649    UNSIGNEDP is for the case where we have to widen the operands
650    to perform the operation.  It says to use zero-extension.
651
652    If TARGET is nonzero, the value
653    is generated there, if it is convenient to do so.
654    In all cases an rtx is returned for the locus of the value;
655    this may or may not be TARGET.  */
656
657 rtx
658 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
659               rtx target, int unsignedp, enum optab_methods methods)
660 {
661   enum optab_methods next_methods
662     = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
663        ? OPTAB_WIDEN : methods);
664   enum mode_class class;
665   enum machine_mode wider_mode;
666   rtx temp;
667   int commutative_op = 0;
668   int shift_op = (binoptab->code == ASHIFT
669                   || binoptab->code == ASHIFTRT
670                   || binoptab->code == LSHIFTRT
671                   || binoptab->code == ROTATE
672                   || binoptab->code == ROTATERT);
673   rtx entry_last = get_last_insn ();
674   rtx last;
675
676   class = GET_MODE_CLASS (mode);
677
678   op0 = protect_from_queue (op0, 0);
679   op1 = protect_from_queue (op1, 0);
680   if (target)
681     target = protect_from_queue (target, 1);
682
683   if (flag_force_mem)
684     {
685       /* Load duplicate non-volatile operands once.  */
686       if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
687         {
688           op0 = force_not_mem (op0);
689           op1 = op0;
690         }
691       else
692         {
693           op0 = force_not_mem (op0);
694           op1 = force_not_mem (op1);
695         }
696     }
697
698   /* If subtracting an integer constant, convert this into an addition of
699      the negated constant.  */
700
701   if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
702     {
703       op1 = negate_rtx (mode, op1);
704       binoptab = add_optab;
705     }
706
707   /* If we are inside an appropriately-short loop and one operand is an
708      expensive constant, force it into a register.  */
709   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
710       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
711     op0 = force_reg (mode, op0);
712
713   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
714       && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
715     op1 = force_reg (mode, op1);
716
717   /* Record where to delete back to if we backtrack.  */
718   last = get_last_insn ();
719
720   /* If operation is commutative,
721      try to make the first operand a register.
722      Even better, try to make it the same as the target.
723      Also try to make the last operand a constant.  */
724   if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
725       || binoptab == smul_widen_optab
726       || binoptab == umul_widen_optab
727       || binoptab == smul_highpart_optab
728       || binoptab == umul_highpart_optab)
729     {
730       commutative_op = 1;
731
732       if (((target == 0 || REG_P (target))
733            ? ((REG_P (op1)
734                && !REG_P (op0))
735               || target == op1)
736            : rtx_equal_p (op1, target))
737           || GET_CODE (op0) == CONST_INT)
738         {
739           temp = op1;
740           op1 = op0;
741           op0 = temp;
742         }
743     }
744
745   /* If we can do it with a three-operand insn, do so.  */
746
747   if (methods != OPTAB_MUST_WIDEN
748       && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
749     {
750       int icode = (int) binoptab->handlers[(int) mode].insn_code;
751       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
752       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
753       rtx pat;
754       rtx xop0 = op0, xop1 = op1;
755
756       if (target)
757         temp = target;
758       else
759         temp = gen_reg_rtx (mode);
760
761       /* If it is a commutative operator and the modes would match
762          if we would swap the operands, we can save the conversions.  */
763       if (commutative_op)
764         {
765           if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
766               && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
767             {
768               rtx tmp;
769
770               tmp = op0; op0 = op1; op1 = tmp;
771               tmp = xop0; xop0 = xop1; xop1 = tmp;
772             }
773         }
774
775       /* In case the insn wants input operands in modes different from
776          those of the actual operands, convert the operands.  It would
777          seem that we don't need to convert CONST_INTs, but we do, so
778          that they're properly zero-extended, sign-extended or truncated
779          for their mode.  */
780
781       if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
782         xop0 = convert_modes (mode0,
783                               GET_MODE (op0) != VOIDmode
784                               ? GET_MODE (op0)
785                               : mode,
786                               xop0, unsignedp);
787
788       if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
789         xop1 = convert_modes (mode1,
790                               GET_MODE (op1) != VOIDmode
791                               ? GET_MODE (op1)
792                               : mode,
793                               xop1, unsignedp);
794
795       /* Now, if insn's predicates don't allow our operands, put them into
796          pseudo regs.  */
797
798       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
799           && mode0 != VOIDmode)
800         xop0 = copy_to_mode_reg (mode0, xop0);
801
802       if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
803           && mode1 != VOIDmode)
804         xop1 = copy_to_mode_reg (mode1, xop1);
805
806       if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
807         temp = gen_reg_rtx (mode);
808
809       pat = GEN_FCN (icode) (temp, xop0, xop1);
810       if (pat)
811         {
812           /* If PAT is composed of more than one insn, try to add an appropriate
813              REG_EQUAL note to it.  If we can't because TEMP conflicts with an
814              operand, call ourselves again, this time without a target.  */
815           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
816               && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
817             {
818               delete_insns_since (last);
819               return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
820                                    unsignedp, methods);
821             }
822
823           emit_insn (pat);
824           return temp;
825         }
826       else
827         delete_insns_since (last);
828     }
829
830   /* If this is a multiply, see if we can do a widening operation that
831      takes operands of this mode and makes a wider mode.  */
832
833   if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
834       && (((unsignedp ? umul_widen_optab : smul_widen_optab)
835            ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
836           != CODE_FOR_nothing))
837     {
838       temp = expand_binop (GET_MODE_WIDER_MODE (mode),
839                            unsignedp ? umul_widen_optab : smul_widen_optab,
840                            op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
841
842       if (temp != 0)
843         {
844           if (GET_MODE_CLASS (mode) == MODE_INT)
845             return gen_lowpart (mode, temp);
846           else
847             return convert_to_mode (mode, temp, unsignedp);
848         }
849     }
850
851   /* Look for a wider mode of the same class for which we think we
852      can open-code the operation.  Check for a widening multiply at the
853      wider mode as well.  */
854
855   if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
856       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
857     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
858          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
859       {
860         if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
861             || (binoptab == smul_optab
862                 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
863                 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
864                      ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
865                     != CODE_FOR_nothing)))
866           {
867             rtx xop0 = op0, xop1 = op1;
868             int no_extend = 0;
869
870             /* For certain integer operations, we need not actually extend
871                the narrow operands, as long as we will truncate
872                the results to the same narrowness.  */
873
874             if ((binoptab == ior_optab || binoptab == and_optab
875                  || binoptab == xor_optab
876                  || binoptab == add_optab || binoptab == sub_optab
877                  || binoptab == smul_optab || binoptab == ashl_optab)
878                 && class == MODE_INT)
879               no_extend = 1;
880
881             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
882
883             /* The second operand of a shift must always be extended.  */
884             xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
885                                   no_extend && binoptab != ashl_optab);
886
887             temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
888                                  unsignedp, OPTAB_DIRECT);
889             if (temp)
890               {
891                 if (class != MODE_INT)
892                   {
893                     if (target == 0)
894                       target = gen_reg_rtx (mode);
895                     convert_move (target, temp, 0);
896                     return target;
897                   }
898                 else
899                   return gen_lowpart (mode, temp);
900               }
901             else
902               delete_insns_since (last);
903           }
904       }
905
906   /* These can be done a word at a time.  */
907   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
908       && class == MODE_INT
909       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
910       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
911     {
912       int i;
913       rtx insns;
914       rtx equiv_value;
915
916       /* If TARGET is the same as one of the operands, the REG_EQUAL note
917          won't be accurate, so use a new target.  */
918       if (target == 0 || target == op0 || target == op1)
919         target = gen_reg_rtx (mode);
920
921       start_sequence ();
922
923       /* Do the actual arithmetic.  */
924       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
925         {
926           rtx target_piece = operand_subword (target, i, 1, mode);
927           rtx x = expand_binop (word_mode, binoptab,
928                                 operand_subword_force (op0, i, mode),
929                                 operand_subword_force (op1, i, mode),
930                                 target_piece, unsignedp, next_methods);
931
932           if (x == 0)
933             break;
934
935           if (target_piece != x)
936             emit_move_insn (target_piece, x);
937         }
938
939       insns = get_insns ();
940       end_sequence ();
941
942       if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
943         {
944           if (binoptab->code != UNKNOWN)
945             equiv_value
946               = gen_rtx_fmt_ee (binoptab->code, mode,
947                                 copy_rtx (op0), copy_rtx (op1));
948           else
949             equiv_value = 0;
950
951           emit_no_conflict_block (insns, target, op0, op1, equiv_value);
952           return target;
953         }
954     }
955
956   /* Synthesize double word shifts from single word shifts.  */
957   if ((binoptab == lshr_optab || binoptab == ashl_optab
958        || binoptab == ashr_optab)
959       && class == MODE_INT
960       && GET_CODE (op1) == CONST_INT
961       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
962       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
963       && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
964       && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
965     {
966       rtx insns, inter, equiv_value;
967       rtx into_target, outof_target;
968       rtx into_input, outof_input;
969       int shift_count, left_shift, outof_word;
970
971       /* If TARGET is the same as one of the operands, the REG_EQUAL note
972          won't be accurate, so use a new target.  */
973       if (target == 0 || target == op0 || target == op1)
974         target = gen_reg_rtx (mode);
975
976       start_sequence ();
977
978       shift_count = INTVAL (op1);
979
980       /* OUTOF_* is the word we are shifting bits away from, and
981          INTO_* is the word that we are shifting bits towards, thus
982          they differ depending on the direction of the shift and
983          WORDS_BIG_ENDIAN.  */
984
985       left_shift = binoptab == ashl_optab;
986       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
987
988       outof_target = operand_subword (target, outof_word, 1, mode);
989       into_target = operand_subword (target, 1 - outof_word, 1, mode);
990
991       outof_input = operand_subword_force (op0, outof_word, mode);
992       into_input = operand_subword_force (op0, 1 - outof_word, mode);
993
994       if (shift_count >= BITS_PER_WORD)
995         {
996           inter = expand_binop (word_mode, binoptab,
997                                outof_input,
998                                GEN_INT (shift_count - BITS_PER_WORD),
999                                into_target, unsignedp, next_methods);
1000
1001           if (inter != 0 && inter != into_target)
1002             emit_move_insn (into_target, inter);
1003
1004           /* For a signed right shift, we must fill the word we are shifting
1005              out of with copies of the sign bit.  Otherwise it is zeroed.  */
1006           if (inter != 0 && binoptab != ashr_optab)
1007             inter = CONST0_RTX (word_mode);
1008           else if (inter != 0)
1009             inter = expand_binop (word_mode, binoptab,
1010                                   outof_input,
1011                                   GEN_INT (BITS_PER_WORD - 1),
1012                                   outof_target, unsignedp, next_methods);
1013
1014           if (inter != 0 && inter != outof_target)
1015             emit_move_insn (outof_target, inter);
1016         }
1017       else
1018         {
1019           rtx carries;
1020           optab reverse_unsigned_shift, unsigned_shift;
1021
1022           /* For a shift of less then BITS_PER_WORD, to compute the carry,
1023              we must do a logical shift in the opposite direction of the
1024              desired shift.  */
1025
1026           reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1027
1028           /* For a shift of less than BITS_PER_WORD, to compute the word
1029              shifted towards, we need to unsigned shift the orig value of
1030              that word.  */
1031
1032           unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1033
1034           carries = expand_binop (word_mode, reverse_unsigned_shift,
1035                                   outof_input,
1036                                   GEN_INT (BITS_PER_WORD - shift_count),
1037                                   0, unsignedp, next_methods);
1038
1039           if (carries == 0)
1040             inter = 0;
1041           else
1042             inter = expand_binop (word_mode, unsigned_shift, into_input,
1043                                   op1, 0, unsignedp, next_methods);
1044
1045           if (inter != 0)
1046             inter = expand_binop (word_mode, ior_optab, carries, inter,
1047                                   into_target, unsignedp, next_methods);
1048
1049           if (inter != 0 && inter != into_target)
1050             emit_move_insn (into_target, inter);
1051
1052           if (inter != 0)
1053             inter = expand_binop (word_mode, binoptab, outof_input,
1054                                   op1, outof_target, unsignedp, next_methods);
1055
1056           if (inter != 0 && inter != outof_target)
1057             emit_move_insn (outof_target, inter);
1058         }
1059
1060       insns = get_insns ();
1061       end_sequence ();
1062
1063       if (inter != 0)
1064         {
1065           if (binoptab->code != UNKNOWN)
1066             equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1067           else
1068             equiv_value = 0;
1069
1070           emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1071           return target;
1072         }
1073     }
1074
1075   /* Synthesize double word rotates from single word shifts.  */
1076   if ((binoptab == rotl_optab || binoptab == rotr_optab)
1077       && class == MODE_INT
1078       && GET_CODE (op1) == CONST_INT
1079       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1080       && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1081       && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1082     {
1083       rtx insns, equiv_value;
1084       rtx into_target, outof_target;
1085       rtx into_input, outof_input;
1086       rtx inter;
1087       int shift_count, left_shift, outof_word;
1088
1089       /* If TARGET is the same as one of the operands, the REG_EQUAL note
1090          won't be accurate, so use a new target. Do this also if target is not
1091          a REG, first because having a register instead may open optimization
1092          opportunities, and second because if target and op0 happen to be MEMs
1093          designating the same location, we would risk clobbering it too early
1094          in the code sequence we generate below.  */
1095       if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1096         target = gen_reg_rtx (mode);
1097
1098       start_sequence ();
1099
1100       shift_count = INTVAL (op1);
1101
1102       /* OUTOF_* is the word we are shifting bits away from, and
1103          INTO_* is the word that we are shifting bits towards, thus
1104          they differ depending on the direction of the shift and
1105          WORDS_BIG_ENDIAN.  */
1106
1107       left_shift = (binoptab == rotl_optab);
1108       outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1109
1110       outof_target = operand_subword (target, outof_word, 1, mode);
1111       into_target = operand_subword (target, 1 - outof_word, 1, mode);
1112
1113       outof_input = operand_subword_force (op0, outof_word, mode);
1114       into_input = operand_subword_force (op0, 1 - outof_word, mode);
1115
1116       if (shift_count == BITS_PER_WORD)
1117         {
1118           /* This is just a word swap.  */
1119           emit_move_insn (outof_target, into_input);
1120           emit_move_insn (into_target, outof_input);
1121           inter = const0_rtx;
1122         }
1123       else
1124         {
1125           rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1126           rtx first_shift_count, second_shift_count;
1127           optab reverse_unsigned_shift, unsigned_shift;
1128
1129           reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1130                                     ? lshr_optab : ashl_optab);
1131
1132           unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1133                             ? ashl_optab : lshr_optab);
1134
1135           if (shift_count > BITS_PER_WORD)
1136             {
1137               first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1138               second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1139             }
1140           else
1141             {
1142               first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1143               second_shift_count = GEN_INT (shift_count);
1144             }
1145
1146           into_temp1 = expand_binop (word_mode, unsigned_shift,
1147                                      outof_input, first_shift_count,
1148                                      NULL_RTX, unsignedp, next_methods);
1149           into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1150                                      into_input, second_shift_count,
1151                                      NULL_RTX, unsignedp, next_methods);
1152
1153           if (into_temp1 != 0 && into_temp2 != 0)
1154             inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1155                                   into_target, unsignedp, next_methods);
1156           else
1157             inter = 0;
1158
1159           if (inter != 0 && inter != into_target)
1160             emit_move_insn (into_target, inter);
1161
1162           outof_temp1 = expand_binop (word_mode, unsigned_shift,
1163                                       into_input, first_shift_count,
1164                                       NULL_RTX, unsignedp, next_methods);
1165           outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1166                                       outof_input, second_shift_count,
1167                                       NULL_RTX, unsignedp, next_methods);
1168
1169           if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1170             inter = expand_binop (word_mode, ior_optab,
1171                                   outof_temp1, outof_temp2,
1172                                   outof_target, unsignedp, next_methods);
1173
1174           if (inter != 0 && inter != outof_target)
1175             emit_move_insn (outof_target, inter);
1176         }
1177
1178       insns = get_insns ();
1179       end_sequence ();
1180
1181       if (inter != 0)
1182         {
1183           if (binoptab->code != UNKNOWN)
1184             equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1185           else
1186             equiv_value = 0;
1187
1188           /* We can't make this a no conflict block if this is a word swap,
1189              because the word swap case fails if the input and output values
1190              are in the same register.  */
1191           if (shift_count != BITS_PER_WORD)
1192             emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1193           else
1194             emit_insn (insns);
1195
1196
1197           return target;
1198         }
1199     }
1200
1201   /* These can be done a word at a time by propagating carries.  */
1202   if ((binoptab == add_optab || binoptab == sub_optab)
1203       && class == MODE_INT
1204       && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1205       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1206     {
1207       unsigned int i;
1208       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1209       const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1210       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1211       rtx xop0, xop1, xtarget;
1212
1213       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1214          value is one of those, use it.  Otherwise, use 1 since it is the
1215          one easiest to get.  */
1216 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1217       int normalizep = STORE_FLAG_VALUE;
1218 #else
1219       int normalizep = 1;
1220 #endif
1221
1222       /* Prepare the operands.  */
1223       xop0 = force_reg (mode, op0);
1224       xop1 = force_reg (mode, op1);
1225
1226       xtarget = gen_reg_rtx (mode);
1227
1228       if (target == 0 || !REG_P (target))
1229         target = xtarget;
1230
1231       /* Indicate for flow that the entire target reg is being set.  */
1232       if (REG_P (target))
1233         emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1234
1235       /* Do the actual arithmetic.  */
1236       for (i = 0; i < nwords; i++)
1237         {
1238           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1239           rtx target_piece = operand_subword (xtarget, index, 1, mode);
1240           rtx op0_piece = operand_subword_force (xop0, index, mode);
1241           rtx op1_piece = operand_subword_force (xop1, index, mode);
1242           rtx x;
1243
1244           /* Main add/subtract of the input operands.  */
1245           x = expand_binop (word_mode, binoptab,
1246                             op0_piece, op1_piece,
1247                             target_piece, unsignedp, next_methods);
1248           if (x == 0)
1249             break;
1250
1251           if (i + 1 < nwords)
1252             {
1253               /* Store carry from main add/subtract.  */
1254               carry_out = gen_reg_rtx (word_mode);
1255               carry_out = emit_store_flag_force (carry_out,
1256                                                  (binoptab == add_optab
1257                                                   ? LT : GT),
1258                                                  x, op0_piece,
1259                                                  word_mode, 1, normalizep);
1260             }
1261
1262           if (i > 0)
1263             {
1264               rtx newx;
1265
1266               /* Add/subtract previous carry to main result.  */
1267               newx = expand_binop (word_mode,
1268                                    normalizep == 1 ? binoptab : otheroptab,
1269                                    x, carry_in,
1270                                    NULL_RTX, 1, next_methods);
1271
1272               if (i + 1 < nwords)
1273                 {
1274                   /* Get out carry from adding/subtracting carry in.  */
1275                   rtx carry_tmp = gen_reg_rtx (word_mode);
1276                   carry_tmp = emit_store_flag_force (carry_tmp,
1277                                                      (binoptab == add_optab
1278                                                       ? LT : GT),
1279                                                      newx, x,
1280                                                      word_mode, 1, normalizep);
1281
1282                   /* Logical-ior the two poss. carry together.  */
1283                   carry_out = expand_binop (word_mode, ior_optab,
1284                                             carry_out, carry_tmp,
1285                                             carry_out, 0, next_methods);
1286                   if (carry_out == 0)
1287                     break;
1288                 }
1289               emit_move_insn (target_piece, newx);
1290             }
1291
1292           carry_in = carry_out;
1293         }
1294
1295       if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1296         {
1297           if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1298               || ! rtx_equal_p (target, xtarget))
1299             {
1300               rtx temp = emit_move_insn (target, xtarget);
1301
1302               set_unique_reg_note (temp,
1303                                    REG_EQUAL,
1304                                    gen_rtx_fmt_ee (binoptab->code, mode,
1305                                                    copy_rtx (xop0),
1306                                                    copy_rtx (xop1)));
1307             }
1308           else
1309             target = xtarget;
1310
1311           return target;
1312         }
1313
1314       else
1315         delete_insns_since (last);
1316     }
1317
1318   /* If we want to multiply two two-word values and have normal and widening
1319      multiplies of single-word values, we can do this with three smaller
1320      multiplications.  Note that we do not make a REG_NO_CONFLICT block here
1321      because we are not operating on one word at a time.
1322
1323      The multiplication proceeds as follows:
1324                                  _______________________
1325                                 [__op0_high_|__op0_low__]
1326                                  _______________________
1327         *                       [__op1_high_|__op1_low__]
1328         _______________________________________________
1329                                  _______________________
1330     (1)                         [__op0_low__*__op1_low__]
1331                      _______________________
1332     (2a)            [__op0_low__*__op1_high_]
1333                      _______________________
1334     (2b)            [__op0_high_*__op1_low__]
1335          _______________________
1336     (3) [__op0_high_*__op1_high_]
1337
1338
1339     This gives a 4-word result.  Since we are only interested in the
1340     lower 2 words, partial result (3) and the upper words of (2a) and
1341     (2b) don't need to be calculated.  Hence (2a) and (2b) can be
1342     calculated using non-widening multiplication.
1343
1344     (1), however, needs to be calculated with an unsigned widening
1345     multiplication.  If this operation is not directly supported we
1346     try using a signed widening multiplication and adjust the result.
1347     This adjustment works as follows:
1348
1349       If both operands are positive then no adjustment is needed.
1350
1351       If the operands have different signs, for example op0_low < 0 and
1352       op1_low >= 0, the instruction treats the most significant bit of
1353       op0_low as a sign bit instead of a bit with significance
1354       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1355       with 2**BITS_PER_WORD - op0_low, and two's complements the
1356       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1357       the result.
1358
1359       Similarly, if both operands are negative, we need to add
1360       (op0_low + op1_low) * 2**BITS_PER_WORD.
1361
1362       We use a trick to adjust quickly.  We logically shift op0_low right
1363       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1364       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
1365       logical shift exists, we do an arithmetic right shift and subtract
1366       the 0 or -1.  */
1367
1368   if (binoptab == smul_optab
1369       && class == MODE_INT
1370       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1371       && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1372       && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1373       && ((umul_widen_optab->handlers[(int) mode].insn_code
1374            != CODE_FOR_nothing)
1375           || (smul_widen_optab->handlers[(int) mode].insn_code
1376               != CODE_FOR_nothing)))
1377     {
1378       int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1379       int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1380       rtx op0_high = operand_subword_force (op0, high, mode);
1381       rtx op0_low = operand_subword_force (op0, low, mode);
1382       rtx op1_high = operand_subword_force (op1, high, mode);
1383       rtx op1_low = operand_subword_force (op1, low, mode);
1384       rtx product = 0;
1385       rtx op0_xhigh = NULL_RTX;
1386       rtx op1_xhigh = NULL_RTX;
1387
1388       /* If the target is the same as one of the inputs, don't use it.  This
1389          prevents problems with the REG_EQUAL note.  */
1390       if (target == op0 || target == op1
1391           || (target != 0 && !REG_P (target)))
1392         target = 0;
1393
1394       /* Multiply the two lower words to get a double-word product.
1395          If unsigned widening multiplication is available, use that;
1396          otherwise use the signed form and compensate.  */
1397
1398       if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1399         {
1400           product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1401                                   target, 1, OPTAB_DIRECT);
1402
1403           /* If we didn't succeed, delete everything we did so far.  */
1404           if (product == 0)
1405             delete_insns_since (last);
1406           else
1407             op0_xhigh = op0_high, op1_xhigh = op1_high;
1408         }
1409
1410       if (product == 0
1411           && smul_widen_optab->handlers[(int) mode].insn_code
1412                != CODE_FOR_nothing)
1413         {
1414           rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1415           product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1416                                   target, 1, OPTAB_DIRECT);
1417           op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1418                                     NULL_RTX, 1, next_methods);
1419           if (op0_xhigh)
1420             op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1421                                       op0_xhigh, op0_xhigh, 0, next_methods);
1422           else
1423             {
1424               op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1425                                         NULL_RTX, 0, next_methods);
1426               if (op0_xhigh)
1427                 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1428                                           op0_xhigh, op0_xhigh, 0,
1429                                           next_methods);
1430             }
1431
1432           op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1433                                     NULL_RTX, 1, next_methods);
1434           if (op1_xhigh)
1435             op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1436                                       op1_xhigh, op1_xhigh, 0, next_methods);
1437           else
1438             {
1439               op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1440                                         NULL_RTX, 0, next_methods);
1441               if (op1_xhigh)
1442                 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1443                                           op1_xhigh, op1_xhigh, 0,
1444                                           next_methods);
1445             }
1446         }
1447
1448       /* If we have been able to directly compute the product of the
1449          low-order words of the operands and perform any required adjustments
1450          of the operands, we proceed by trying two more multiplications
1451          and then computing the appropriate sum.
1452
1453          We have checked above that the required addition is provided.
1454          Full-word addition will normally always succeed, especially if
1455          it is provided at all, so we don't worry about its failure.  The
1456          multiplication may well fail, however, so we do handle that.  */
1457
1458       if (product && op0_xhigh && op1_xhigh)
1459         {
1460           rtx product_high = operand_subword (product, high, 1, mode);
1461           rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1462                                    NULL_RTX, 0, OPTAB_DIRECT);
1463
1464           if (!REG_P (product_high))
1465             product_high = force_reg (word_mode, product_high);
1466
1467           if (temp != 0)
1468             temp = expand_binop (word_mode, add_optab, temp, product_high,
1469                                  product_high, 0, next_methods);
1470
1471           if (temp != 0 && temp != product_high)
1472             emit_move_insn (product_high, temp);
1473
1474           if (temp != 0)
1475             temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1476                                  NULL_RTX, 0, OPTAB_DIRECT);
1477
1478           if (temp != 0)
1479             temp = expand_binop (word_mode, add_optab, temp,
1480                                  product_high, product_high,
1481                                  0, next_methods);
1482
1483           if (temp != 0 && temp != product_high)
1484             emit_move_insn (product_high, temp);
1485
1486           emit_move_insn (operand_subword (product, high, 1, mode), product_high);
1487
1488           if (temp != 0)
1489             {
1490               if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1491                 {
1492                   temp = emit_move_insn (product, product);
1493                   set_unique_reg_note (temp,
1494                                        REG_EQUAL,
1495                                        gen_rtx_fmt_ee (MULT, mode,
1496                                                        copy_rtx (op0),
1497                                                        copy_rtx (op1)));
1498                 }
1499
1500               return product;
1501             }
1502         }
1503
1504       /* If we get here, we couldn't do it for some reason even though we
1505          originally thought we could.  Delete anything we've emitted in
1506          trying to do it.  */
1507
1508       delete_insns_since (last);
1509     }
1510
1511   /* Open-code the vector operations if we have no hardware support
1512      for them.  */
1513   if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT)
1514     return expand_vector_binop (mode, binoptab, op0, op1, target,
1515                                 unsignedp, methods);
1516
1517   /* We need to open-code the complex type operations: '+, -, * and /' */
1518
1519   /* At this point we allow operations between two similar complex
1520      numbers, and also if one of the operands is not a complex number
1521      but rather of MODE_FLOAT or MODE_INT. However, the caller
1522      must make sure that the MODE of the non-complex operand matches
1523      the SUBMODE of the complex operand.  */
1524
1525   if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1526     {
1527       rtx real0 = 0, imag0 = 0;
1528       rtx real1 = 0, imag1 = 0;
1529       rtx realr, imagr, res;
1530       rtx seq, result;
1531       int ok = 0;
1532
1533       /* Find the correct mode for the real and imaginary parts.  */
1534       enum machine_mode submode = GET_MODE_INNER (mode);
1535
1536       if (submode == BLKmode)
1537         abort ();
1538
1539       start_sequence ();
1540
1541       if (GET_MODE (op0) == mode)
1542         {
1543           real0 = gen_realpart (submode, op0);
1544           imag0 = gen_imagpart (submode, op0);
1545         }
1546       else
1547         real0 = op0;
1548
1549       if (GET_MODE (op1) == mode)
1550         {
1551           real1 = gen_realpart (submode, op1);
1552           imag1 = gen_imagpart (submode, op1);
1553         }
1554       else
1555         real1 = op1;
1556
1557       if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
1558         abort ();
1559
1560       result = gen_reg_rtx (mode);
1561       realr = gen_realpart (submode, result);
1562       imagr = gen_imagpart (submode, result);
1563
1564       switch (binoptab->code)
1565         {
1566         case PLUS:
1567           /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1568         case MINUS:
1569           /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1570           res = expand_binop (submode, binoptab, real0, real1,
1571                               realr, unsignedp, methods);
1572
1573           if (res == 0)
1574             break;
1575           else if (res != realr)
1576             emit_move_insn (realr, res);
1577
1578           if (imag0 != 0 && imag1 != 0)
1579             res = expand_binop (submode, binoptab, imag0, imag1,
1580                                 imagr, unsignedp, methods);
1581           else if (imag0 != 0)
1582             res = imag0;
1583           else if (binoptab->code == MINUS)
1584             res = expand_unop (submode,
1585                                 binoptab == subv_optab ? negv_optab : neg_optab,
1586                                 imag1, imagr, unsignedp);
1587           else
1588             res = imag1;
1589
1590           if (res == 0)
1591             break;
1592           else if (res != imagr)
1593             emit_move_insn (imagr, res);
1594
1595           ok = 1;
1596           break;
1597
1598         case MULT:
1599           /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1600
1601           if (imag0 != 0 && imag1 != 0)
1602             {
1603               rtx temp1, temp2;
1604
1605               /* Don't fetch these from memory more than once.  */
1606               real0 = force_reg (submode, real0);
1607               real1 = force_reg (submode, real1);
1608               imag0 = force_reg (submode, imag0);
1609               imag1 = force_reg (submode, imag1);
1610
1611               temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1612                                     unsignedp, methods);
1613
1614               temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1615                                     unsignedp, methods);
1616
1617               if (temp1 == 0 || temp2 == 0)
1618                 break;
1619
1620               res = (expand_binop
1621                      (submode,
1622                       binoptab == smulv_optab ? subv_optab : sub_optab,
1623                       temp1, temp2, realr, unsignedp, methods));
1624
1625               if (res == 0)
1626                 break;
1627               else if (res != realr)
1628                 emit_move_insn (realr, res);
1629
1630               temp1 = expand_binop (submode, binoptab, real0, imag1,
1631                                     NULL_RTX, unsignedp, methods);
1632
1633               /* Avoid expanding redundant multiplication for the common
1634                  case of squaring a complex number.  */
1635               if (rtx_equal_p (real0, real1) && rtx_equal_p (imag0, imag1))
1636                 temp2 = temp1;
1637               else
1638                 temp2 = expand_binop (submode, binoptab, real1, imag0,
1639                                       NULL_RTX, unsignedp, methods);
1640
1641               if (temp1 == 0 || temp2 == 0)
1642                 break;
1643
1644               res = (expand_binop
1645                      (submode,
1646                       binoptab == smulv_optab ? addv_optab : add_optab,
1647                       temp1, temp2, imagr, unsignedp, methods));
1648
1649               if (res == 0)
1650                 break;
1651               else if (res != imagr)
1652                 emit_move_insn (imagr, res);
1653
1654               ok = 1;
1655             }
1656           else
1657             {
1658               /* Don't fetch these from memory more than once.  */
1659               real0 = force_reg (submode, real0);
1660               real1 = force_reg (submode, real1);
1661
1662               res = expand_binop (submode, binoptab, real0, real1,
1663                                   realr, unsignedp, methods);
1664               if (res == 0)
1665                 break;
1666               else if (res != realr)
1667                 emit_move_insn (realr, res);
1668
1669               if (imag0 != 0)
1670                 res = expand_binop (submode, binoptab,
1671                                     real1, imag0, imagr, unsignedp, methods);
1672               else
1673                 res = expand_binop (submode, binoptab,
1674                                     real0, imag1, imagr, unsignedp, methods);
1675
1676               if (res == 0)
1677                 break;
1678               else if (res != imagr)
1679                 emit_move_insn (imagr, res);
1680
1681               ok = 1;
1682             }
1683           break;
1684
1685         case DIV:
1686           /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1687
1688           if (imag1 == 0)
1689             {
1690               /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1691
1692               /* Don't fetch these from memory more than once.  */
1693               real1 = force_reg (submode, real1);
1694
1695               /* Simply divide the real and imaginary parts by `c' */
1696               if (class == MODE_COMPLEX_FLOAT)
1697                 res = expand_binop (submode, binoptab, real0, real1,
1698                                     realr, unsignedp, methods);
1699               else
1700                 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1701                                      real0, real1, realr, unsignedp);
1702
1703               if (res == 0)
1704                 break;
1705               else if (res != realr)
1706                 emit_move_insn (realr, res);
1707
1708               if (class == MODE_COMPLEX_FLOAT)
1709                 res = expand_binop (submode, binoptab, imag0, real1,
1710                                     imagr, unsignedp, methods);
1711               else
1712                 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1713                                      imag0, real1, imagr, unsignedp);
1714
1715               if (res == 0)
1716                 break;
1717               else if (res != imagr)
1718                 emit_move_insn (imagr, res);
1719
1720               ok = 1;
1721             }
1722           else
1723             {
1724               switch (flag_complex_divide_method)
1725                 {
1726                 case 0:
1727                   ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1728                                                  realr, imagr, submode,
1729                                                  unsignedp, methods,
1730                                                  class, binoptab);
1731                   break;
1732
1733                 case 1:
1734                   ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1735                                              realr, imagr, submode,
1736                                              unsignedp, methods,
1737                                              class, binoptab);
1738                   break;
1739
1740                 default:
1741                   abort ();
1742                 }
1743             }
1744           break;
1745
1746         default:
1747           abort ();
1748         }
1749
1750       seq = get_insns ();
1751       end_sequence ();
1752
1753       if (ok)
1754         {
1755           rtx equiv = gen_rtx_fmt_ee (binoptab->code, mode,
1756                                       copy_rtx (op0), copy_rtx (op1));
1757           emit_no_conflict_block (seq, result, op0, op1, equiv);
1758           return result;
1759         }
1760     }
1761
1762   /* It can't be open-coded in this mode.
1763      Use a library call if one is available and caller says that's ok.  */
1764
1765   if (binoptab->handlers[(int) mode].libfunc
1766       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1767     {
1768       rtx insns;
1769       rtx op1x = op1;
1770       enum machine_mode op1_mode = mode;
1771       rtx value;
1772
1773       start_sequence ();
1774
1775       if (shift_op)
1776         {
1777           op1_mode = word_mode;
1778           /* Specify unsigned here,
1779              since negative shift counts are meaningless.  */
1780           op1x = convert_to_mode (word_mode, op1, 1);
1781         }
1782
1783       if (GET_MODE (op0) != VOIDmode
1784           && GET_MODE (op0) != mode)
1785         op0 = convert_to_mode (mode, op0, unsignedp);
1786
1787       /* Pass 1 for NO_QUEUE so we don't lose any increments
1788          if the libcall is cse'd or moved.  */
1789       value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1790                                        NULL_RTX, LCT_CONST, mode, 2,
1791                                        op0, mode, op1x, op1_mode);
1792
1793       insns = get_insns ();
1794       end_sequence ();
1795
1796       target = gen_reg_rtx (mode);
1797       emit_libcall_block (insns, target, value,
1798                           gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1799
1800       return target;
1801     }
1802
1803   delete_insns_since (last);
1804
1805   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1806
1807   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1808          || methods == OPTAB_MUST_WIDEN))
1809     {
1810       /* Caller says, don't even try.  */
1811       delete_insns_since (entry_last);
1812       return 0;
1813     }
1814
1815   /* Compute the value of METHODS to pass to recursive calls.
1816      Don't allow widening to be tried recursively.  */
1817
1818   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1819
1820   /* Look for a wider mode of the same class for which it appears we can do
1821      the operation.  */
1822
1823   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1824     {
1825       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1826            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1827         {
1828           if ((binoptab->handlers[(int) wider_mode].insn_code
1829                != CODE_FOR_nothing)
1830               || (methods == OPTAB_LIB
1831                   && binoptab->handlers[(int) wider_mode].libfunc))
1832             {
1833               rtx xop0 = op0, xop1 = op1;
1834               int no_extend = 0;
1835
1836               /* For certain integer operations, we need not actually extend
1837                  the narrow operands, as long as we will truncate
1838                  the results to the same narrowness.  */
1839
1840               if ((binoptab == ior_optab || binoptab == and_optab
1841                    || binoptab == xor_optab
1842                    || binoptab == add_optab || binoptab == sub_optab
1843                    || binoptab == smul_optab || binoptab == ashl_optab)
1844                   && class == MODE_INT)
1845                 no_extend = 1;
1846
1847               xop0 = widen_operand (xop0, wider_mode, mode,
1848                                     unsignedp, no_extend);
1849
1850               /* The second operand of a shift must always be extended.  */
1851               xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1852                                     no_extend && binoptab != ashl_optab);
1853
1854               temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1855                                    unsignedp, methods);
1856               if (temp)
1857                 {
1858                   if (class != MODE_INT)
1859                     {
1860                       if (target == 0)
1861                         target = gen_reg_rtx (mode);
1862                       convert_move (target, temp, 0);
1863                       return target;
1864                     }
1865                   else
1866                     return gen_lowpart (mode, temp);
1867                 }
1868               else
1869                 delete_insns_since (last);
1870             }
1871         }
1872     }
1873
1874   delete_insns_since (entry_last);
1875   return 0;
1876 }
1877
1878 /* Like expand_binop, but for open-coding vectors binops.  */
1879
1880 static rtx
1881 expand_vector_binop (enum machine_mode mode, optab binoptab, rtx op0,
1882                      rtx op1, rtx target, int unsignedp,
1883                      enum optab_methods methods)
1884 {
1885   enum machine_mode submode, tmode;
1886   int size, elts, subsize, subbitsize, i;
1887   rtx t, a, b, res, seq;
1888   enum mode_class class;
1889
1890   class = GET_MODE_CLASS (mode);
1891
1892   size = GET_MODE_SIZE (mode);
1893   submode = GET_MODE_INNER (mode);
1894
1895   /* Search for the widest vector mode with the same inner mode that is
1896      still narrower than MODE and that allows to open-code this operator.
1897      Note, if we find such a mode and the handler later decides it can't
1898      do the expansion, we'll be called recursively with the narrower mode.  */
1899   for (tmode = GET_CLASS_NARROWEST_MODE (class);
1900        GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
1901        tmode = GET_MODE_WIDER_MODE (tmode))
1902     {
1903       if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
1904           && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
1905         submode = tmode;
1906     }
1907
1908   switch (binoptab->code)
1909     {
1910     case AND:
1911     case IOR:
1912     case XOR:
1913       tmode = int_mode_for_mode (mode);
1914       if (tmode != BLKmode)
1915         submode = tmode;
1916     case PLUS:
1917     case MINUS:
1918     case MULT:
1919     case DIV:
1920       subsize = GET_MODE_SIZE (submode);
1921       subbitsize = GET_MODE_BITSIZE (submode);
1922       elts = size / subsize;
1923
1924       /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode,
1925          but that we operate on more than one element at a time.  */
1926       if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT)
1927         return 0;
1928
1929       start_sequence ();
1930
1931       /* Errors can leave us with a const0_rtx as operand.  */
1932       if (GET_MODE (op0) != mode)
1933         op0 = copy_to_mode_reg (mode, op0);
1934       if (GET_MODE (op1) != mode)
1935         op1 = copy_to_mode_reg (mode, op1);
1936
1937       if (!target)
1938         target = gen_reg_rtx (mode);
1939
1940       for (i = 0; i < elts; ++i)
1941         {
1942           /* If this is part of a register, and not the first item in the
1943              word, we can't store using a SUBREG - that would clobber
1944              previous results.
1945              And storing with a SUBREG is only possible for the least
1946              significant part, hence we can't do it for big endian
1947              (unless we want to permute the evaluation order.  */
1948           if (REG_P (target)
1949               && (BYTES_BIG_ENDIAN
1950                   ? subsize < UNITS_PER_WORD
1951                   : ((i * subsize) % UNITS_PER_WORD) != 0))
1952             t = NULL_RTX;
1953           else
1954             t = simplify_gen_subreg (submode, target, mode, i * subsize);
1955           if (CONSTANT_P (op0))
1956             a = simplify_gen_subreg (submode, op0, mode, i * subsize);
1957           else
1958             a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
1959                                    NULL_RTX, submode, submode);
1960           if (CONSTANT_P (op1))
1961             b = simplify_gen_subreg (submode, op1, mode, i * subsize);
1962           else
1963             b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp,
1964                                    NULL_RTX, submode, submode);
1965
1966           if (binoptab->code == DIV)
1967             {
1968               if (class == MODE_VECTOR_FLOAT)
1969                 res = expand_binop (submode, binoptab, a, b, t,
1970                                     unsignedp, methods);
1971               else
1972                 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1973                                      a, b, t, unsignedp);
1974             }
1975           else
1976             res = expand_binop (submode, binoptab, a, b, t,
1977                                 unsignedp, methods);
1978
1979           if (res == 0)
1980             break;
1981
1982           if (t)
1983             emit_move_insn (t, res);
1984           else
1985             store_bit_field (target, subbitsize, i * subbitsize, submode, res);
1986         }
1987       break;
1988
1989     default:
1990       abort ();
1991     }
1992
1993   seq = get_insns ();
1994   end_sequence ();
1995   emit_insn (seq);
1996
1997   return target;
1998 }
1999
2000 /* Like expand_unop but for open-coding vector unops.  */
2001
2002 static rtx
2003 expand_vector_unop (enum machine_mode mode, optab unoptab, rtx op0,
2004                     rtx target, int unsignedp)
2005 {
2006   enum machine_mode submode, tmode;
2007   int size, elts, subsize, subbitsize, i;
2008   rtx t, a, res, seq;
2009
2010   size = GET_MODE_SIZE (mode);
2011   submode = GET_MODE_INNER (mode);
2012
2013   /* Search for the widest vector mode with the same inner mode that is
2014      still narrower than MODE and that allows to open-code this operator.
2015      Note, if we find such a mode and the handler later decides it can't
2016      do the expansion, we'll be called recursively with the narrower mode.  */
2017   for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode));
2018        GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
2019        tmode = GET_MODE_WIDER_MODE (tmode))
2020     {
2021       if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
2022           && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
2023         submode = tmode;
2024     }
2025   /* If there is no negate operation, try doing a subtract from zero.  */
2026   if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT
2027       /* Avoid infinite recursion when an
2028          error has left us with the wrong mode.  */
2029       && GET_MODE (op0) == mode)
2030     {
2031       rtx temp;
2032       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2033                            target, unsignedp, OPTAB_DIRECT);
2034       if (temp)
2035         return temp;
2036     }
2037
2038   if (unoptab == one_cmpl_optab)
2039     {
2040       tmode = int_mode_for_mode (mode);
2041       if (tmode != BLKmode)
2042         submode = tmode;
2043     }
2044
2045   subsize = GET_MODE_SIZE (submode);
2046   subbitsize = GET_MODE_BITSIZE (submode);
2047   elts = size / subsize;
2048
2049   /* Errors can leave us with a const0_rtx as operand.  */
2050   if (GET_MODE (op0) != mode)
2051     op0 = copy_to_mode_reg (mode, op0);
2052
2053   if (!target)
2054     target = gen_reg_rtx (mode);
2055
2056   start_sequence ();
2057
2058   for (i = 0; i < elts; ++i)
2059     {
2060       /* If this is part of a register, and not the first item in the
2061          word, we can't store using a SUBREG - that would clobber
2062          previous results.
2063          And storing with a SUBREG is only possible for the least
2064          significant part, hence we can't do it for big endian
2065          (unless we want to permute the evaluation order.  */
2066       if (REG_P (target)
2067           && (BYTES_BIG_ENDIAN
2068               ?  subsize < UNITS_PER_WORD
2069               : ((i * subsize) % UNITS_PER_WORD) != 0))
2070         t = NULL_RTX;
2071       else
2072         t = simplify_gen_subreg (submode, target, mode, i * subsize);
2073       if (CONSTANT_P (op0))
2074         a = simplify_gen_subreg (submode, op0, mode, i * subsize);
2075       else
2076         a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
2077                                t, submode, submode);
2078
2079       res = expand_unop (submode, unoptab, a, t, unsignedp);
2080
2081       if (t)
2082         emit_move_insn (t, res);
2083       else
2084         store_bit_field (target, subbitsize, i * subbitsize, submode, res);
2085     }
2086
2087   seq = get_insns ();
2088   end_sequence ();
2089   emit_insn (seq);
2090
2091   return target;
2092 }
2093 \f
2094 /* Expand a binary operator which has both signed and unsigned forms.
2095    UOPTAB is the optab for unsigned operations, and SOPTAB is for
2096    signed operations.
2097
2098    If we widen unsigned operands, we may use a signed wider operation instead
2099    of an unsigned wider operation, since the result would be the same.  */
2100
2101 rtx
2102 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2103                    rtx op0, rtx op1, rtx target, int unsignedp,
2104                    enum optab_methods methods)
2105 {
2106   rtx temp;
2107   optab direct_optab = unsignedp ? uoptab : soptab;
2108   struct optab wide_soptab;
2109
2110   /* Do it without widening, if possible.  */
2111   temp = expand_binop (mode, direct_optab, op0, op1, target,
2112                        unsignedp, OPTAB_DIRECT);
2113   if (temp || methods == OPTAB_DIRECT)
2114     return temp;
2115
2116   /* Try widening to a signed int.  Make a fake signed optab that
2117      hides any signed insn for direct use.  */
2118   wide_soptab = *soptab;
2119   wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2120   wide_soptab.handlers[(int) mode].libfunc = 0;
2121
2122   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2123                        unsignedp, OPTAB_WIDEN);
2124
2125   /* For unsigned operands, try widening to an unsigned int.  */
2126   if (temp == 0 && unsignedp)
2127     temp = expand_binop (mode, uoptab, op0, op1, target,
2128                          unsignedp, OPTAB_WIDEN);
2129   if (temp || methods == OPTAB_WIDEN)
2130     return temp;
2131
2132   /* Use the right width lib call if that exists.  */
2133   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2134   if (temp || methods == OPTAB_LIB)
2135     return temp;
2136
2137   /* Must widen and use a lib call, use either signed or unsigned.  */
2138   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2139                        unsignedp, methods);
2140   if (temp != 0)
2141     return temp;
2142   if (unsignedp)
2143     return expand_binop (mode, uoptab, op0, op1, target,
2144                          unsignedp, methods);
2145   return 0;
2146 }
2147 \f
2148 /* Generate code to perform an operation specified by UNOPPTAB
2149    on operand OP0, with two results to TARG0 and TARG1.
2150    We assume that the order of the operands for the instruction
2151    is TARG0, TARG1, OP0.
2152
2153    Either TARG0 or TARG1 may be zero, but what that means is that
2154    the result is not actually wanted.  We will generate it into
2155    a dummy pseudo-reg and discard it.  They may not both be zero.
2156
2157    Returns 1 if this operation can be performed; 0 if not.  */
2158
2159 int
2160 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2161                     int unsignedp)
2162 {
2163   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2164   enum mode_class class;
2165   enum machine_mode wider_mode;
2166   rtx entry_last = get_last_insn ();
2167   rtx last;
2168
2169   class = GET_MODE_CLASS (mode);
2170
2171   op0 = protect_from_queue (op0, 0);
2172
2173   if (flag_force_mem)
2174     {
2175       op0 = force_not_mem (op0);
2176     }
2177
2178   if (targ0)
2179     targ0 = protect_from_queue (targ0, 1);
2180   else
2181     targ0 = gen_reg_rtx (mode);
2182   if (targ1)
2183     targ1 = protect_from_queue (targ1, 1);
2184   else
2185     targ1 = gen_reg_rtx (mode);
2186
2187   /* Record where to go back to if we fail.  */
2188   last = get_last_insn ();
2189
2190   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2191     {
2192       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2193       enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2194       rtx pat;
2195       rtx xop0 = op0;
2196
2197       if (GET_MODE (xop0) != VOIDmode
2198           && GET_MODE (xop0) != mode0)
2199         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2200
2201       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2202       if (! (*insn_data[icode].operand[2].predicate) (xop0, mode0))
2203         xop0 = copy_to_mode_reg (mode0, xop0);
2204
2205       /* We could handle this, but we should always be called with a pseudo
2206          for our targets and all insns should take them as outputs.  */
2207       if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2208           || ! (*insn_data[icode].operand[1].predicate) (targ1, mode))
2209         abort ();
2210
2211       pat = GEN_FCN (icode) (targ0, targ1, xop0);
2212       if (pat)
2213         {
2214           emit_insn (pat);
2215           return 1;
2216         }
2217       else
2218         delete_insns_since (last);
2219     }
2220
2221   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2222
2223   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2224     {
2225       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2226            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2227         {
2228           if (unoptab->handlers[(int) wider_mode].insn_code
2229               != CODE_FOR_nothing)
2230             {
2231               rtx t0 = gen_reg_rtx (wider_mode);
2232               rtx t1 = gen_reg_rtx (wider_mode);
2233               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2234
2235               if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2236                 {
2237                   convert_move (targ0, t0, unsignedp);
2238                   convert_move (targ1, t1, unsignedp);
2239                   return 1;
2240                 }
2241               else
2242                 delete_insns_since (last);
2243             }
2244         }
2245     }
2246
2247   delete_insns_since (entry_last);
2248   return 0;
2249 }
2250 \f
2251 /* Generate code to perform an operation specified by BINOPTAB
2252    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2253    We assume that the order of the operands for the instruction
2254    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2255    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2256
2257    Either TARG0 or TARG1 may be zero, but what that means is that
2258    the result is not actually wanted.  We will generate it into
2259    a dummy pseudo-reg and discard it.  They may not both be zero.
2260
2261    Returns 1 if this operation can be performed; 0 if not.  */
2262
2263 int
2264 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2265                      int unsignedp)
2266 {
2267   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2268   enum mode_class class;
2269   enum machine_mode wider_mode;
2270   rtx entry_last = get_last_insn ();
2271   rtx last;
2272
2273   class = GET_MODE_CLASS (mode);
2274
2275   op0 = protect_from_queue (op0, 0);
2276   op1 = protect_from_queue (op1, 0);
2277
2278   if (flag_force_mem)
2279     {
2280       op0 = force_not_mem (op0);
2281       op1 = force_not_mem (op1);
2282     }
2283
2284   /* If we are inside an appropriately-short loop and one operand is an
2285      expensive constant, force it into a register.  */
2286   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2287       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2288     op0 = force_reg (mode, op0);
2289
2290   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2291       && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2292     op1 = force_reg (mode, op1);
2293
2294   if (targ0)
2295     targ0 = protect_from_queue (targ0, 1);
2296   else
2297     targ0 = gen_reg_rtx (mode);
2298   if (targ1)
2299     targ1 = protect_from_queue (targ1, 1);
2300   else
2301     targ1 = gen_reg_rtx (mode);
2302
2303   /* Record where to go back to if we fail.  */
2304   last = get_last_insn ();
2305
2306   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2307     {
2308       int icode = (int) binoptab->handlers[(int) mode].insn_code;
2309       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2310       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2311       rtx pat;
2312       rtx xop0 = op0, xop1 = op1;
2313
2314       /* In case the insn wants input operands in modes different from
2315          those of the actual operands, convert the operands.  It would
2316          seem that we don't need to convert CONST_INTs, but we do, so
2317          that they're properly zero-extended, sign-extended or truncated
2318          for their mode.  */
2319
2320       if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2321         xop0 = convert_modes (mode0,
2322                               GET_MODE (op0) != VOIDmode
2323                               ? GET_MODE (op0)
2324                               : mode,
2325                               xop0, unsignedp);
2326
2327       if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2328         xop1 = convert_modes (mode1,
2329                               GET_MODE (op1) != VOIDmode
2330                               ? GET_MODE (op1)
2331                               : mode,
2332                               xop1, unsignedp);
2333
2334       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2335       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2336         xop0 = copy_to_mode_reg (mode0, xop0);
2337
2338       if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
2339         xop1 = copy_to_mode_reg (mode1, xop1);
2340
2341       /* We could handle this, but we should always be called with a pseudo
2342          for our targets and all insns should take them as outputs.  */
2343       if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2344           || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
2345         abort ();
2346
2347       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2348       if (pat)
2349         {
2350           emit_insn (pat);
2351           return 1;
2352         }
2353       else
2354         delete_insns_since (last);
2355     }
2356
2357   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2358
2359   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2360     {
2361       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2362            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2363         {
2364           if (binoptab->handlers[(int) wider_mode].insn_code
2365               != CODE_FOR_nothing)
2366             {
2367               rtx t0 = gen_reg_rtx (wider_mode);
2368               rtx t1 = gen_reg_rtx (wider_mode);
2369               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2370               rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2371
2372               if (expand_twoval_binop (binoptab, cop0, cop1,
2373                                        t0, t1, unsignedp))
2374                 {
2375                   convert_move (targ0, t0, unsignedp);
2376                   convert_move (targ1, t1, unsignedp);
2377                   return 1;
2378                 }
2379               else
2380                 delete_insns_since (last);
2381             }
2382         }
2383     }
2384
2385   delete_insns_since (entry_last);
2386   return 0;
2387 }
2388 \f
2389 /* Wrapper around expand_unop which takes an rtx code to specify
2390    the operation to perform, not an optab pointer.  All other
2391    arguments are the same.  */
2392 rtx
2393 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2394                     rtx target, int unsignedp)
2395 {
2396   optab unop = code_to_optab[(int) code];
2397   if (unop == 0)
2398     abort ();
2399
2400   return expand_unop (mode, unop, op0, target, unsignedp);
2401 }
2402
2403 /* Try calculating
2404         (clz:narrow x)
2405    as
2406         (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2407 static rtx
2408 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2409 {
2410   enum mode_class class = GET_MODE_CLASS (mode);
2411   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2412     {
2413       enum machine_mode wider_mode;
2414       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2415            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2416         {
2417           if (clz_optab->handlers[(int) wider_mode].insn_code
2418               != CODE_FOR_nothing)
2419             {
2420               rtx xop0, temp, last;
2421
2422               last = get_last_insn ();
2423
2424               if (target == 0)
2425                 target = gen_reg_rtx (mode);
2426               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2427               temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2428               if (temp != 0)
2429                 temp = expand_binop (wider_mode, sub_optab, temp,
2430                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2431                                               - GET_MODE_BITSIZE (mode)),
2432                                      target, true, OPTAB_DIRECT);
2433               if (temp == 0)
2434                 delete_insns_since (last);
2435
2436               return temp;
2437             }
2438         }
2439     }
2440   return 0;
2441 }
2442
2443 /* Try calculating (parity x) as (and (popcount x) 1), where
2444    popcount can also be done in a wider mode.  */
2445 static rtx
2446 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2447 {
2448   enum mode_class class = GET_MODE_CLASS (mode);
2449   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2450     {
2451       enum machine_mode wider_mode;
2452       for (wider_mode = mode; wider_mode != VOIDmode;
2453            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2454         {
2455           if (popcount_optab->handlers[(int) wider_mode].insn_code
2456               != CODE_FOR_nothing)
2457             {
2458               rtx xop0, temp, last;
2459
2460               last = get_last_insn ();
2461
2462               if (target == 0)
2463                 target = gen_reg_rtx (mode);
2464               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2465               temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2466                                   true);
2467               if (temp != 0)
2468                 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2469                                      target, true, OPTAB_DIRECT);
2470               if (temp == 0)
2471                 delete_insns_since (last);
2472
2473               return temp;
2474             }
2475         }
2476     }
2477   return 0;
2478 }
2479
2480 /* Generate code to perform an operation specified by UNOPTAB
2481    on operand OP0, with result having machine-mode MODE.
2482
2483    UNSIGNEDP is for the case where we have to widen the operands
2484    to perform the operation.  It says to use zero-extension.
2485
2486    If TARGET is nonzero, the value
2487    is generated there, if it is convenient to do so.
2488    In all cases an rtx is returned for the locus of the value;
2489    this may or may not be TARGET.  */
2490
2491 rtx
2492 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2493              int unsignedp)
2494 {
2495   enum mode_class class;
2496   enum machine_mode wider_mode;
2497   rtx temp;
2498   rtx last = get_last_insn ();
2499   rtx pat;
2500
2501   class = GET_MODE_CLASS (mode);
2502
2503   op0 = protect_from_queue (op0, 0);
2504
2505   if (flag_force_mem)
2506     {
2507       op0 = force_not_mem (op0);
2508     }
2509
2510   if (target)
2511     target = protect_from_queue (target, 1);
2512
2513   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2514     {
2515       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2516       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2517       rtx xop0 = op0;
2518
2519       if (target)
2520         temp = target;
2521       else
2522         temp = gen_reg_rtx (mode);
2523
2524       if (GET_MODE (xop0) != VOIDmode
2525           && GET_MODE (xop0) != mode0)
2526         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2527
2528       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2529
2530       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2531         xop0 = copy_to_mode_reg (mode0, xop0);
2532
2533       if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2534         temp = gen_reg_rtx (mode);
2535
2536       pat = GEN_FCN (icode) (temp, xop0);
2537       if (pat)
2538         {
2539           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2540               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2541             {
2542               delete_insns_since (last);
2543               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2544             }
2545
2546           emit_insn (pat);
2547
2548           return temp;
2549         }
2550       else
2551         delete_insns_since (last);
2552     }
2553
2554   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2555
2556   /* Widening clz needs special treatment.  */
2557   if (unoptab == clz_optab)
2558     {
2559       temp = widen_clz (mode, op0, target);
2560       if (temp)
2561         return temp;
2562       else
2563         goto try_libcall;
2564     }
2565
2566   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2567     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2568          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2569       {
2570         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2571           {
2572             rtx xop0 = op0;
2573
2574             /* For certain operations, we need not actually extend
2575                the narrow operand, as long as we will truncate the
2576                results to the same narrowness.  */
2577
2578             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2579                                   (unoptab == neg_optab
2580                                    || unoptab == one_cmpl_optab)
2581                                   && class == MODE_INT);
2582
2583             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2584                                 unsignedp);
2585
2586             if (temp)
2587               {
2588                 if (class != MODE_INT)
2589                   {
2590                     if (target == 0)
2591                       target = gen_reg_rtx (mode);
2592                     convert_move (target, temp, 0);
2593                     return target;
2594                   }
2595                 else
2596                   return gen_lowpart (mode, temp);
2597               }
2598             else
2599               delete_insns_since (last);
2600           }
2601       }
2602
2603   /* These can be done a word at a time.  */
2604   if (unoptab == one_cmpl_optab
2605       && class == MODE_INT
2606       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2607       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2608     {
2609       int i;
2610       rtx insns;
2611
2612       if (target == 0 || target == op0)
2613         target = gen_reg_rtx (mode);
2614
2615       start_sequence ();
2616
2617       /* Do the actual arithmetic.  */
2618       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2619         {
2620           rtx target_piece = operand_subword (target, i, 1, mode);
2621           rtx x = expand_unop (word_mode, unoptab,
2622                                operand_subword_force (op0, i, mode),
2623                                target_piece, unsignedp);
2624
2625           if (target_piece != x)
2626             emit_move_insn (target_piece, x);
2627         }
2628
2629       insns = get_insns ();
2630       end_sequence ();
2631
2632       emit_no_conflict_block (insns, target, op0, NULL_RTX,
2633                               gen_rtx_fmt_e (unoptab->code, mode,
2634                                              copy_rtx (op0)));
2635       return target;
2636     }
2637
2638   /* Open-code the complex negation operation.  */
2639   else if (unoptab->code == NEG
2640            && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2641     {
2642       rtx target_piece;
2643       rtx x;
2644       rtx seq;
2645
2646       /* Find the correct mode for the real and imaginary parts.  */
2647       enum machine_mode submode = GET_MODE_INNER (mode);
2648
2649       if (submode == BLKmode)
2650         abort ();
2651
2652       if (target == 0)
2653         target = gen_reg_rtx (mode);
2654
2655       start_sequence ();
2656
2657       target_piece = gen_imagpart (submode, target);
2658       x = expand_unop (submode, unoptab,
2659                        gen_imagpart (submode, op0),
2660                        target_piece, unsignedp);
2661       if (target_piece != x)
2662         emit_move_insn (target_piece, x);
2663
2664       target_piece = gen_realpart (submode, target);
2665       x = expand_unop (submode, unoptab,
2666                        gen_realpart (submode, op0),
2667                        target_piece, unsignedp);
2668       if (target_piece != x)
2669         emit_move_insn (target_piece, x);
2670
2671       seq = get_insns ();
2672       end_sequence ();
2673
2674       emit_no_conflict_block (seq, target, op0, 0,
2675                               gen_rtx_fmt_e (unoptab->code, mode,
2676                                              copy_rtx (op0)));
2677       return target;
2678     }
2679
2680   /* Try negating floating point values by flipping the sign bit.  */
2681   if (unoptab->code == NEG && class == MODE_FLOAT
2682       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2683     {
2684       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2685       enum machine_mode imode = int_mode_for_mode (mode);
2686       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2687
2688       if (imode != BLKmode && bitpos >= 0 && fmt->has_signed_zero)
2689         {
2690           HOST_WIDE_INT hi, lo;
2691           rtx last = get_last_insn ();
2692
2693           /* Handle targets with different FP word orders.  */
2694           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2695             {
2696               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2697               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2698               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2699             }
2700
2701           if (bitpos < HOST_BITS_PER_WIDE_INT)
2702             {
2703               hi = 0;
2704               lo = (HOST_WIDE_INT) 1 << bitpos;
2705             }
2706           else
2707             {
2708               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2709               lo = 0;
2710             }
2711           temp = expand_binop (imode, xor_optab,
2712                                gen_lowpart (imode, op0),
2713                                immed_double_const (lo, hi, imode),
2714                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2715           if (temp != 0)
2716             {
2717               rtx insn;
2718               if (target == 0)
2719                 target = gen_reg_rtx (mode);
2720               insn = emit_move_insn (target, gen_lowpart (mode, temp));
2721               set_unique_reg_note (insn, REG_EQUAL,
2722                                    gen_rtx_fmt_e (NEG, mode,
2723                                                   copy_rtx (op0)));
2724               return target;
2725             }
2726           delete_insns_since (last);
2727         }
2728     }
2729
2730   /* Try calculating parity (x) as popcount (x) % 2.  */
2731   if (unoptab == parity_optab)
2732     {
2733       temp = expand_parity (mode, op0, target);
2734       if (temp)
2735         return temp;
2736     }
2737
2738   /* If there is no negation pattern, try subtracting from zero.  */
2739   if (unoptab == neg_optab && class == MODE_INT)
2740     {
2741       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2742                            target, unsignedp, OPTAB_DIRECT);
2743       if (temp)
2744         return temp;
2745     }
2746
2747  try_libcall:
2748   /* Now try a library call in this mode.  */
2749   if (unoptab->handlers[(int) mode].libfunc)
2750     {
2751       rtx insns;
2752       rtx value;
2753       enum machine_mode outmode = mode;
2754
2755       /* All of these functions return small values.  Thus we choose to
2756          have them return something that isn't a double-word.  */
2757       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2758           || unoptab == popcount_optab || unoptab == parity_optab)
2759         outmode
2760             = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2761
2762       start_sequence ();
2763
2764       /* Pass 1 for NO_QUEUE so we don't lose any increments
2765          if the libcall is cse'd or moved.  */
2766       value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2767                                        NULL_RTX, LCT_CONST, outmode,
2768                                        1, op0, mode);
2769       insns = get_insns ();
2770       end_sequence ();
2771
2772       target = gen_reg_rtx (outmode);
2773       emit_libcall_block (insns, target, value,
2774                           gen_rtx_fmt_e (unoptab->code, mode, op0));
2775
2776       return target;
2777     }
2778
2779   if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
2780     return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
2781
2782   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2783
2784   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2785     {
2786       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2787            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2788         {
2789           if ((unoptab->handlers[(int) wider_mode].insn_code
2790                != CODE_FOR_nothing)
2791               || unoptab->handlers[(int) wider_mode].libfunc)
2792             {
2793               rtx xop0 = op0;
2794
2795               /* For certain operations, we need not actually extend
2796                  the narrow operand, as long as we will truncate the
2797                  results to the same narrowness.  */
2798
2799               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2800                                     (unoptab == neg_optab
2801                                      || unoptab == one_cmpl_optab)
2802                                     && class == MODE_INT);
2803
2804               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2805                                   unsignedp);
2806
2807               /* If we are generating clz using wider mode, adjust the
2808                  result.  */
2809               if (unoptab == clz_optab && temp != 0)
2810                 temp = expand_binop (wider_mode, sub_optab, temp,
2811                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2812                                               - GET_MODE_BITSIZE (mode)),
2813                                      target, true, OPTAB_DIRECT);
2814
2815               if (temp)
2816                 {
2817                   if (class != MODE_INT)
2818                     {
2819                       if (target == 0)
2820                         target = gen_reg_rtx (mode);
2821                       convert_move (target, temp, 0);
2822                       return target;
2823                     }
2824                   else
2825                     return gen_lowpart (mode, temp);
2826                 }
2827               else
2828                 delete_insns_since (last);
2829             }
2830         }
2831     }
2832
2833   /* If there is no negate operation, try doing a subtract from zero.
2834      The US Software GOFAST library needs this.  */
2835   if (unoptab->code == NEG)
2836     {
2837       rtx temp;
2838       temp = expand_binop (mode,
2839                            unoptab == negv_optab ? subv_optab : sub_optab,
2840                            CONST0_RTX (mode), op0,
2841                            target, unsignedp, OPTAB_LIB_WIDEN);
2842       if (temp)
2843         return temp;
2844     }
2845
2846   return 0;
2847 }
2848 \f
2849 /* Emit code to compute the absolute value of OP0, with result to
2850    TARGET if convenient.  (TARGET may be 0.)  The return value says
2851    where the result actually is to be found.
2852
2853    MODE is the mode of the operand; the mode of the result is
2854    different but can be deduced from MODE.
2855
2856  */
2857
2858 rtx
2859 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2860                    int result_unsignedp)
2861 {
2862   rtx temp;
2863
2864   if (! flag_trapv)
2865     result_unsignedp = 1;
2866
2867   /* First try to do it with a special abs instruction.  */
2868   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2869                       op0, target, 0);
2870   if (temp != 0)
2871     return temp;
2872
2873   /* For floating point modes, try clearing the sign bit.  */
2874   if (GET_MODE_CLASS (mode) == MODE_FLOAT
2875       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2876     {
2877       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2878       enum machine_mode imode = int_mode_for_mode (mode);
2879       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2880
2881       if (imode != BLKmode && bitpos >= 0)
2882         {
2883           HOST_WIDE_INT hi, lo;
2884           rtx last = get_last_insn ();
2885
2886           /* Handle targets with different FP word orders.  */
2887           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2888             {
2889               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2890               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2891               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2892             }
2893
2894           if (bitpos < HOST_BITS_PER_WIDE_INT)
2895             {
2896               hi = 0;
2897               lo = (HOST_WIDE_INT) 1 << bitpos;
2898             }
2899           else
2900             {
2901               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2902               lo = 0;
2903             }
2904           temp = expand_binop (imode, and_optab,
2905                                gen_lowpart (imode, op0),
2906                                immed_double_const (~lo, ~hi, imode),
2907                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2908           if (temp != 0)
2909             {
2910               rtx insn;
2911               if (target == 0)
2912                 target = gen_reg_rtx (mode);
2913               insn = emit_move_insn (target, gen_lowpart (mode, temp));
2914               set_unique_reg_note (insn, REG_EQUAL,
2915                                    gen_rtx_fmt_e (ABS, mode,
2916                                                   copy_rtx (op0)));
2917               return target;
2918             }
2919           delete_insns_since (last);
2920         }
2921     }
2922
2923   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
2924   if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2925     {
2926       rtx last = get_last_insn ();
2927
2928       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2929       if (temp != 0)
2930         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2931                              OPTAB_WIDEN);
2932
2933       if (temp != 0)
2934         return temp;
2935
2936       delete_insns_since (last);
2937     }
2938
2939   /* If this machine has expensive jumps, we can do integer absolute
2940      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2941      where W is the width of MODE.  */
2942
2943   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2944     {
2945       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2946                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2947                                    NULL_RTX, 0);
2948
2949       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2950                            OPTAB_LIB_WIDEN);
2951       if (temp != 0)
2952         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2953                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
2954
2955       if (temp != 0)
2956         return temp;
2957     }
2958
2959   return NULL_RTX;
2960 }
2961
2962 rtx
2963 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2964             int result_unsignedp, int safe)
2965 {
2966   rtx temp, op1;
2967
2968   if (! flag_trapv)
2969     result_unsignedp = 1;
2970
2971   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2972   if (temp != 0)
2973     return temp;
2974
2975   /* If that does not win, use conditional jump and negate.  */
2976
2977   /* It is safe to use the target if it is the same
2978      as the source if this is also a pseudo register */
2979   if (op0 == target && REG_P (op0)
2980       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2981     safe = 1;
2982
2983   op1 = gen_label_rtx ();
2984   if (target == 0 || ! safe
2985       || GET_MODE (target) != mode
2986       || (MEM_P (target) && MEM_VOLATILE_P (target))
2987       || (REG_P (target)
2988           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2989     target = gen_reg_rtx (mode);
2990
2991   emit_move_insn (target, op0);
2992   NO_DEFER_POP;
2993
2994   /* If this mode is an integer too wide to compare properly,
2995      compare word by word.  Rely on CSE to optimize constant cases.  */
2996   if (GET_MODE_CLASS (mode) == MODE_INT
2997       && ! can_compare_p (GE, mode, ccp_jump))
2998     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2999                                   NULL_RTX, op1);
3000   else
3001     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3002                              NULL_RTX, NULL_RTX, op1);
3003
3004   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3005                      target, target, 0);
3006   if (op0 != target)
3007     emit_move_insn (target, op0);
3008   emit_label (op1);
3009   OK_DEFER_POP;
3010   return target;
3011 }
3012 \f
3013 /* Emit code to compute the absolute value of OP0, with result to
3014    TARGET if convenient.  (TARGET may be 0.)  The return value says
3015    where the result actually is to be found.
3016
3017    MODE is the mode of the operand; the mode of the result is
3018    different but can be deduced from MODE.
3019
3020    UNSIGNEDP is relevant for complex integer modes.  */
3021
3022 rtx
3023 expand_complex_abs (enum machine_mode mode, rtx op0, rtx target,
3024                     int unsignedp)
3025 {
3026   enum mode_class class = GET_MODE_CLASS (mode);
3027   enum machine_mode wider_mode;
3028   rtx temp;
3029   rtx entry_last = get_last_insn ();
3030   rtx last;
3031   rtx pat;
3032   optab this_abs_optab;
3033
3034   /* Find the correct mode for the real and imaginary parts.  */
3035   enum machine_mode submode = GET_MODE_INNER (mode);
3036
3037   if (submode == BLKmode)
3038     abort ();
3039
3040   op0 = protect_from_queue (op0, 0);
3041
3042   if (flag_force_mem)
3043     {
3044       op0 = force_not_mem (op0);
3045     }
3046
3047   last = get_last_insn ();
3048
3049   if (target)
3050     target = protect_from_queue (target, 1);
3051
3052   this_abs_optab = ! unsignedp && flag_trapv
3053                    && (GET_MODE_CLASS(mode) == MODE_INT)
3054                    ? absv_optab : abs_optab;
3055
3056   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3057     {
3058       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
3059       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3060       rtx xop0 = op0;
3061
3062       if (target)
3063         temp = target;
3064       else
3065         temp = gen_reg_rtx (submode);
3066
3067       if (GET_MODE (xop0) != VOIDmode
3068           && GET_MODE (xop0) != mode0)
3069         xop0 = convert_to_mode (mode0, xop0, unsignedp);
3070
3071       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
3072
3073       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
3074         xop0 = copy_to_mode_reg (mode0, xop0);
3075
3076       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
3077         temp = gen_reg_rtx (submode);
3078
3079       pat = GEN_FCN (icode) (temp, xop0);
3080       if (pat)
3081         {
3082           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3083               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
3084                                    NULL_RTX))
3085             {
3086               delete_insns_since (last);
3087               return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
3088                                   unsignedp);
3089             }
3090
3091           emit_insn (pat);
3092
3093           return temp;
3094         }
3095       else
3096         delete_insns_since (last);
3097     }
3098
3099   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
3100
3101   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3102        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3103     {
3104       if (this_abs_optab->handlers[(int) wider_mode].insn_code
3105           != CODE_FOR_nothing)
3106         {
3107           rtx xop0 = op0;
3108
3109           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3110           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3111
3112           if (temp)
3113             {
3114               if (class != MODE_COMPLEX_INT)
3115                 {
3116                   if (target == 0)
3117                     target = gen_reg_rtx (submode);
3118                   convert_move (target, temp, 0);
3119                   return target;
3120                 }
3121               else
3122                 return gen_lowpart (submode, temp);
3123             }
3124           else
3125             delete_insns_since (last);
3126         }
3127     }
3128
3129   /* Open-code the complex absolute-value operation
3130      if we can open-code sqrt.  Otherwise it's not worth while.  */
3131   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
3132       && ! flag_trapv)
3133     {
3134       rtx real, imag, total;
3135
3136       real = gen_realpart (submode, op0);
3137       imag = gen_imagpart (submode, op0);
3138
3139       /* Square both parts.  */
3140       real = expand_mult (submode, real, real, NULL_RTX, 0);
3141       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
3142
3143       /* Sum the parts.  */
3144       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
3145                             0, OPTAB_LIB_WIDEN);
3146
3147       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
3148       target = expand_unop (submode, sqrt_optab, total, target, 0);
3149       if (target == 0)
3150         delete_insns_since (last);
3151       else
3152         return target;
3153     }
3154
3155   /* Now try a library call in this mode.  */
3156   if (this_abs_optab->handlers[(int) mode].libfunc)
3157     {
3158       rtx insns;
3159       rtx value;
3160
3161       start_sequence ();
3162
3163       /* Pass 1 for NO_QUEUE so we don't lose any increments
3164          if the libcall is cse'd or moved.  */
3165       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
3166                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
3167       insns = get_insns ();
3168       end_sequence ();
3169
3170       target = gen_reg_rtx (submode);
3171       emit_libcall_block (insns, target, value,
3172                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
3173
3174       return target;
3175     }
3176
3177   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3178
3179   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3180        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3181     {
3182       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
3183            != CODE_FOR_nothing)
3184           || this_abs_optab->handlers[(int) wider_mode].libfunc)
3185         {
3186           rtx xop0 = op0;
3187
3188           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3189
3190           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3191
3192           if (temp)
3193             {
3194               if (class != MODE_COMPLEX_INT)
3195                 {
3196                   if (target == 0)
3197                     target = gen_reg_rtx (submode);
3198                   convert_move (target, temp, 0);
3199                   return target;
3200                 }
3201               else
3202                 return gen_lowpart (submode, temp);
3203             }
3204           else
3205             delete_insns_since (last);
3206         }
3207     }
3208
3209   delete_insns_since (entry_last);
3210   return 0;
3211 }
3212 \f
3213 /* Generate an instruction whose insn-code is INSN_CODE,
3214    with two operands: an output TARGET and an input OP0.
3215    TARGET *must* be nonzero, and the output is always stored there.
3216    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3217    the value that is stored into TARGET.  */
3218
3219 void
3220 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3221 {
3222   rtx temp;
3223   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3224   rtx pat;
3225
3226   temp = target = protect_from_queue (target, 1);
3227
3228   op0 = protect_from_queue (op0, 0);
3229
3230   /* Sign and zero extension from memory is often done specially on
3231      RISC machines, so forcing into a register here can pessimize
3232      code.  */
3233   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
3234     op0 = force_not_mem (op0);
3235
3236   /* Now, if insn does not accept our operands, put them into pseudos.  */
3237
3238   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3239     op0 = copy_to_mode_reg (mode0, op0);
3240
3241   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
3242       || (flag_force_mem && MEM_P (temp)))
3243     temp = gen_reg_rtx (GET_MODE (temp));
3244
3245   pat = GEN_FCN (icode) (temp, op0);
3246
3247   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3248     add_equal_note (pat, temp, code, op0, NULL_RTX);
3249
3250   emit_insn (pat);
3251
3252   if (temp != target)
3253     emit_move_insn (target, temp);
3254 }
3255 \f
3256 /* Emit code to perform a series of operations on a multi-word quantity, one
3257    word at a time.
3258
3259    Such a block is preceded by a CLOBBER of the output, consists of multiple
3260    insns, each setting one word of the output, and followed by a SET copying
3261    the output to itself.
3262
3263    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3264    note indicating that it doesn't conflict with the (also multi-word)
3265    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3266    notes.
3267
3268    INSNS is a block of code generated to perform the operation, not including
3269    the CLOBBER and final copy.  All insns that compute intermediate values
3270    are first emitted, followed by the block as described above.
3271
3272    TARGET, OP0, and OP1 are the output and inputs of the operations,
3273    respectively.  OP1 may be zero for a unary operation.
3274
3275    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3276    on the last insn.
3277
3278    If TARGET is not a register, INSNS is simply emitted with no special
3279    processing.  Likewise if anything in INSNS is not an INSN or if
3280    there is a libcall block inside INSNS.
3281
3282    The final insn emitted is returned.  */
3283
3284 rtx
3285 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3286 {
3287   rtx prev, next, first, last, insn;
3288
3289   if (!REG_P (target) || reload_in_progress)
3290     return emit_insn (insns);
3291   else
3292     for (insn = insns; insn; insn = NEXT_INSN (insn))
3293       if (!NONJUMP_INSN_P (insn)
3294           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3295         return emit_insn (insns);
3296
3297   /* First emit all insns that do not store into words of the output and remove
3298      these from the list.  */
3299   for (insn = insns; insn; insn = next)
3300     {
3301       rtx set = 0, note;
3302       int i;
3303
3304       next = NEXT_INSN (insn);
3305
3306       /* Some ports (cris) create a libcall regions at their own.  We must
3307          avoid any potential nesting of LIBCALLs.  */
3308       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3309         remove_note (insn, note);
3310       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3311         remove_note (insn, note);
3312
3313       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3314           || GET_CODE (PATTERN (insn)) == CLOBBER)
3315         set = PATTERN (insn);
3316       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3317         {
3318           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3319             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3320               {
3321                 set = XVECEXP (PATTERN (insn), 0, i);
3322                 break;
3323               }
3324         }
3325
3326       if (set == 0)
3327         abort ();
3328
3329       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3330         {
3331           if (PREV_INSN (insn))
3332             NEXT_INSN (PREV_INSN (insn)) = next;
3333           else
3334             insns = next;
3335
3336           if (next)
3337             PREV_INSN (next) = PREV_INSN (insn);
3338
3339           add_insn (insn);
3340         }
3341     }
3342
3343   prev = get_last_insn ();
3344
3345   /* Now write the CLOBBER of the output, followed by the setting of each
3346      of the words, followed by the final copy.  */
3347   if (target != op0 && target != op1)
3348     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3349
3350   for (insn = insns; insn; insn = next)
3351     {
3352       next = NEXT_INSN (insn);
3353       add_insn (insn);
3354
3355       if (op1 && REG_P (op1))
3356         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3357                                               REG_NOTES (insn));
3358
3359       if (op0 && REG_P (op0))
3360         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3361                                               REG_NOTES (insn));
3362     }
3363
3364   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3365       != CODE_FOR_nothing)
3366     {
3367       last = emit_move_insn (target, target);
3368       if (equiv)
3369         set_unique_reg_note (last, REG_EQUAL, equiv);
3370     }
3371   else
3372     {
3373       last = get_last_insn ();
3374
3375       /* Remove any existing REG_EQUAL note from "last", or else it will
3376          be mistaken for a note referring to the full contents of the
3377          alleged libcall value when found together with the REG_RETVAL
3378          note added below.  An existing note can come from an insn
3379          expansion at "last".  */
3380       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3381     }
3382
3383   if (prev == 0)
3384     first = get_insns ();
3385   else
3386     first = NEXT_INSN (prev);
3387
3388   /* Encapsulate the block so it gets manipulated as a unit.  */
3389   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3390                                          REG_NOTES (first));
3391   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3392
3393   return last;
3394 }
3395 \f
3396 /* Emit code to make a call to a constant function or a library call.
3397
3398    INSNS is a list containing all insns emitted in the call.
3399    These insns leave the result in RESULT.  Our block is to copy RESULT
3400    to TARGET, which is logically equivalent to EQUIV.
3401
3402    We first emit any insns that set a pseudo on the assumption that these are
3403    loading constants into registers; doing so allows them to be safely cse'ed
3404    between blocks.  Then we emit all the other insns in the block, followed by
3405    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3406    note with an operand of EQUIV.
3407
3408    Moving assignments to pseudos outside of the block is done to improve
3409    the generated code, but is not required to generate correct code,
3410    hence being unable to move an assignment is not grounds for not making
3411    a libcall block.  There are two reasons why it is safe to leave these
3412    insns inside the block: First, we know that these pseudos cannot be
3413    used in generated RTL outside the block since they are created for
3414    temporary purposes within the block.  Second, CSE will not record the
3415    values of anything set inside a libcall block, so we know they must
3416    be dead at the end of the block.
3417
3418    Except for the first group of insns (the ones setting pseudos), the
3419    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3420
3421 void
3422 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3423 {
3424   rtx final_dest = target;
3425   rtx prev, next, first, last, insn;
3426
3427   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3428      into a MEM later.  Protect the libcall block from this change.  */
3429   if (! REG_P (target) || REG_USERVAR_P (target))
3430     target = gen_reg_rtx (GET_MODE (target));
3431
3432   /* If we're using non-call exceptions, a libcall corresponding to an
3433      operation that may trap may also trap.  */
3434   if (flag_non_call_exceptions && may_trap_p (equiv))
3435     {
3436       for (insn = insns; insn; insn = NEXT_INSN (insn))
3437         if (CALL_P (insn))
3438           {
3439             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3440
3441             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3442               remove_note (insn, note);
3443           }
3444     }
3445   else
3446   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3447      reg note to indicate that this call cannot throw or execute a nonlocal
3448      goto (unless there is already a REG_EH_REGION note, in which case
3449      we update it).  */
3450     for (insn = insns; insn; insn = NEXT_INSN (insn))
3451       if (CALL_P (insn))
3452         {
3453           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3454
3455           if (note != 0)
3456             XEXP (note, 0) = constm1_rtx;
3457           else
3458             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3459                                                   REG_NOTES (insn));
3460         }
3461
3462   /* First emit all insns that set pseudos.  Remove them from the list as
3463      we go.  Avoid insns that set pseudos which were referenced in previous
3464      insns.  These can be generated by move_by_pieces, for example,
3465      to update an address.  Similarly, avoid insns that reference things
3466      set in previous insns.  */
3467
3468   for (insn = insns; insn; insn = next)
3469     {
3470       rtx set = single_set (insn);
3471       rtx note;
3472
3473       /* Some ports (cris) create a libcall regions at their own.  We must
3474          avoid any potential nesting of LIBCALLs.  */
3475       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3476         remove_note (insn, note);
3477       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3478         remove_note (insn, note);
3479
3480       next = NEXT_INSN (insn);
3481
3482       if (set != 0 && REG_P (SET_DEST (set))
3483           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3484           && (insn == insns
3485               || ((! INSN_P(insns)
3486                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3487                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
3488                   && ! modified_in_p (SET_SRC (set), insns)
3489                   && ! modified_between_p (SET_SRC (set), insns, insn))))
3490         {
3491           if (PREV_INSN (insn))
3492             NEXT_INSN (PREV_INSN (insn)) = next;
3493           else
3494             insns = next;
3495
3496           if (next)
3497             PREV_INSN (next) = PREV_INSN (insn);
3498
3499           add_insn (insn);
3500         }
3501
3502       /* Some ports use a loop to copy large arguments onto the stack.
3503          Don't move anything outside such a loop.  */
3504       if (LABEL_P (insn))
3505         break;
3506     }
3507
3508   prev = get_last_insn ();
3509
3510   /* Write the remaining insns followed by the final copy.  */
3511
3512   for (insn = insns; insn; insn = next)
3513     {
3514       next = NEXT_INSN (insn);
3515
3516       add_insn (insn);
3517     }
3518
3519   last = emit_move_insn (target, result);
3520   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3521       != CODE_FOR_nothing)
3522     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3523   else
3524     {
3525       /* Remove any existing REG_EQUAL note from "last", or else it will
3526          be mistaken for a note referring to the full contents of the
3527          libcall value when found together with the REG_RETVAL note added
3528          below.  An existing note can come from an insn expansion at
3529          "last".  */
3530       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3531     }
3532
3533   if (final_dest != target)
3534     emit_move_insn (final_dest, target);
3535
3536   if (prev == 0)
3537     first = get_insns ();
3538   else
3539     first = NEXT_INSN (prev);
3540
3541   /* Encapsulate the block so it gets manipulated as a unit.  */
3542   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3543     {
3544       /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3545          when the encapsulated region would not be in one basic block,
3546          i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3547        */
3548       bool attach_libcall_retval_notes = true;
3549       next = NEXT_INSN (last);
3550       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3551         if (control_flow_insn_p (insn))
3552           {
3553             attach_libcall_retval_notes = false;
3554             break;
3555           }
3556
3557       if (attach_libcall_retval_notes)
3558         {
3559           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3560                                                  REG_NOTES (first));
3561           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3562                                                 REG_NOTES (last));
3563         }
3564     }
3565 }
3566 \f
3567 /* Generate code to store zero in X.  */
3568
3569 void
3570 emit_clr_insn (rtx x)
3571 {
3572   emit_move_insn (x, const0_rtx);
3573 }
3574
3575 /* Generate code to store 1 in X
3576    assuming it contains zero beforehand.  */
3577
3578 void
3579 emit_0_to_1_insn (rtx x)
3580 {
3581   emit_move_insn (x, const1_rtx);
3582 }
3583
3584 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3585    PURPOSE describes how this comparison will be used.  CODE is the rtx
3586    comparison code we will be using.
3587
3588    ??? Actually, CODE is slightly weaker than that.  A target is still
3589    required to implement all of the normal bcc operations, but not
3590    required to implement all (or any) of the unordered bcc operations.  */
3591
3592 int
3593 can_compare_p (enum rtx_code code, enum machine_mode mode,
3594                enum can_compare_purpose purpose)
3595 {
3596   do
3597     {
3598       if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3599         {
3600           if (purpose == ccp_jump)
3601             return bcc_gen_fctn[(int) code] != NULL;
3602           else if (purpose == ccp_store_flag)
3603             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3604           else
3605             /* There's only one cmov entry point, and it's allowed to fail.  */
3606             return 1;
3607         }
3608       if (purpose == ccp_jump
3609           && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3610         return 1;
3611       if (purpose == ccp_cmov
3612           && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3613         return 1;
3614       if (purpose == ccp_store_flag
3615           && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3616         return 1;
3617
3618       mode = GET_MODE_WIDER_MODE (mode);
3619     }
3620   while (mode != VOIDmode);
3621
3622   return 0;
3623 }
3624
3625 /* This function is called when we are going to emit a compare instruction that
3626    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3627
3628    *PMODE is the mode of the inputs (in case they are const_int).
3629    *PUNSIGNEDP nonzero says that the operands are unsigned;
3630    this matters if they need to be widened.
3631
3632    If they have mode BLKmode, then SIZE specifies the size of both operands.
3633
3634    This function performs all the setup necessary so that the caller only has
3635    to emit a single comparison insn.  This setup can involve doing a BLKmode
3636    comparison or emitting a library call to perform the comparison if no insn
3637    is available to handle it.
3638    The values which are passed in through pointers can be modified; the caller
3639    should perform the comparison on the modified values.  */
3640
3641 static void
3642 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3643                   enum machine_mode *pmode, int *punsignedp,
3644                   enum can_compare_purpose purpose)
3645 {
3646   enum machine_mode mode = *pmode;
3647   rtx x = *px, y = *py;
3648   int unsignedp = *punsignedp;
3649   enum mode_class class;
3650
3651   class = GET_MODE_CLASS (mode);
3652
3653   /* They could both be VOIDmode if both args are immediate constants,
3654      but we should fold that at an earlier stage.
3655      With no special code here, this will call abort,
3656      reminding the programmer to implement such folding.  */
3657
3658   if (mode != BLKmode && flag_force_mem)
3659     {
3660       /* Load duplicate non-volatile operands once.  */
3661       if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
3662         {
3663           x = force_not_mem (x);
3664           y = x;
3665         }
3666       else
3667         {
3668           x = force_not_mem (x);
3669           y = force_not_mem (y);
3670         }
3671     }
3672
3673   /* If we are inside an appropriately-short loop and one operand is an
3674      expensive constant, force it into a register.  */
3675   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3676       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3677     x = force_reg (mode, x);
3678
3679   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3680       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3681     y = force_reg (mode, y);
3682
3683 #ifdef HAVE_cc0
3684   /* Abort if we have a non-canonical comparison.  The RTL documentation
3685      states that canonical comparisons are required only for targets which
3686      have cc0.  */
3687   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3688     abort ();
3689 #endif
3690
3691   /* Don't let both operands fail to indicate the mode.  */
3692   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3693     x = force_reg (mode, x);
3694
3695   /* Handle all BLKmode compares.  */
3696
3697   if (mode == BLKmode)
3698     {
3699       enum machine_mode cmp_mode, result_mode;
3700       enum insn_code cmp_code;
3701       tree length_type;
3702       rtx libfunc;
3703       rtx result;
3704       rtx opalign
3705         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3706
3707       if (size == 0)
3708         abort ();
3709
3710       emit_queue ();
3711       x = protect_from_queue (x, 0);
3712       y = protect_from_queue (y, 0);
3713       size = protect_from_queue (size, 0);
3714
3715       /* Try to use a memory block compare insn - either cmpstr
3716          or cmpmem will do.  */
3717       for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3718            cmp_mode != VOIDmode;
3719            cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3720         {
3721           cmp_code = cmpmem_optab[cmp_mode];
3722           if (cmp_code == CODE_FOR_nothing)
3723             cmp_code = cmpstr_optab[cmp_mode];
3724           if (cmp_code == CODE_FOR_nothing)
3725             continue;
3726
3727           /* Must make sure the size fits the insn's mode.  */
3728           if ((GET_CODE (size) == CONST_INT
3729                && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3730               || (GET_MODE_BITSIZE (GET_MODE (size))
3731                   > GET_MODE_BITSIZE (cmp_mode)))
3732             continue;
3733
3734           result_mode = insn_data[cmp_code].operand[0].mode;
3735           result = gen_reg_rtx (result_mode);
3736           size = convert_to_mode (cmp_mode, size, 1);
3737           emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3738
3739           *px = result;
3740           *py = const0_rtx;
3741           *pmode = result_mode;
3742           return;
3743         }
3744
3745       /* Otherwise call a library function, memcmp.  */
3746       libfunc = memcmp_libfunc;
3747       length_type = sizetype;
3748       result_mode = TYPE_MODE (integer_type_node);
3749       cmp_mode = TYPE_MODE (length_type);
3750       size = convert_to_mode (TYPE_MODE (length_type), size,
3751                               TYPE_UNSIGNED (length_type));
3752
3753       result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3754                                         result_mode, 3,
3755                                         XEXP (x, 0), Pmode,
3756                                         XEXP (y, 0), Pmode,
3757                                         size, cmp_mode);
3758       *px = result;
3759       *py = const0_rtx;
3760       *pmode = result_mode;
3761       return;
3762     }
3763
3764   /* Don't allow operands to the compare to trap, as that can put the
3765      compare and branch in different basic blocks.  */
3766   if (flag_non_call_exceptions)
3767     {
3768       if (may_trap_p (x))
3769         x = force_reg (mode, x);
3770       if (may_trap_p (y))
3771         y = force_reg (mode, y);
3772     }
3773
3774   *px = x;
3775   *py = y;
3776   if (can_compare_p (*pcomparison, mode, purpose))
3777     return;
3778
3779   /* Handle a lib call just for the mode we are using.  */
3780
3781   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3782     {
3783       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3784       rtx result;
3785
3786       /* If we want unsigned, and this mode has a distinct unsigned
3787          comparison routine, use that.  */
3788       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3789         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3790
3791       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3792                                         word_mode, 2, x, mode, y, mode);
3793
3794       /* Integer comparison returns a result that must be compared against 1,
3795          so that even if we do an unsigned compare afterward,
3796          there is still a value that can represent the result "less than".  */
3797       *px = result;
3798       *py = const1_rtx;
3799       *pmode = word_mode;
3800       return;
3801     }
3802
3803   if (class == MODE_FLOAT)
3804     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3805
3806   else
3807     abort ();
3808 }
3809
3810 /* Before emitting an insn with code ICODE, make sure that X, which is going
3811    to be used for operand OPNUM of the insn, is converted from mode MODE to
3812    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3813    that it is accepted by the operand predicate.  Return the new value.  */
3814
3815 rtx
3816 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3817                  enum machine_mode wider_mode, int unsignedp)
3818 {
3819   x = protect_from_queue (x, 0);
3820
3821   if (mode != wider_mode)
3822     x = convert_modes (wider_mode, mode, x, unsignedp);
3823
3824   if (! (*insn_data[icode].operand[opnum].predicate)
3825       (x, insn_data[icode].operand[opnum].mode))
3826     {
3827       if (no_new_pseudos)
3828         return NULL_RTX;
3829       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3830     }
3831
3832   return x;
3833 }
3834
3835 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3836    we can do the comparison.
3837    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3838    be NULL_RTX which indicates that only a comparison is to be generated.  */
3839
3840 static void
3841 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3842                           enum rtx_code comparison, int unsignedp, rtx label)
3843 {
3844   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3845   enum mode_class class = GET_MODE_CLASS (mode);
3846   enum machine_mode wider_mode = mode;
3847
3848   /* Try combined insns first.  */
3849   do
3850     {
3851       enum insn_code icode;
3852       PUT_MODE (test, wider_mode);
3853
3854       if (label)
3855         {
3856           icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3857
3858           if (icode != CODE_FOR_nothing
3859               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3860             {
3861               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3862               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3863               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3864               return;
3865             }
3866         }
3867
3868       /* Handle some compares against zero.  */
3869       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3870       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3871         {
3872           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3873           emit_insn (GEN_FCN (icode) (x));
3874           if (label)
3875             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3876           return;
3877         }
3878
3879       /* Handle compares for which there is a directly suitable insn.  */
3880
3881       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3882       if (icode != CODE_FOR_nothing)
3883         {
3884           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3885           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3886           emit_insn (GEN_FCN (icode) (x, y));
3887           if (label)
3888             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3889           return;
3890         }
3891
3892       if (class != MODE_INT && class != MODE_FLOAT
3893           && class != MODE_COMPLEX_FLOAT)
3894         break;
3895
3896       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3897     }
3898   while (wider_mode != VOIDmode);
3899
3900   abort ();
3901 }
3902
3903 /* Generate code to compare X with Y so that the condition codes are
3904    set and to jump to LABEL if the condition is true.  If X is a
3905    constant and Y is not a constant, then the comparison is swapped to
3906    ensure that the comparison RTL has the canonical form.
3907
3908    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3909    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3910    the proper branch condition code.
3911
3912    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3913
3914    MODE is the mode of the inputs (in case they are const_int).
3915
3916    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3917    be passed unchanged to emit_cmp_insn, then potentially converted into an
3918    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3919
3920 void
3921 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3922                          enum machine_mode mode, int unsignedp, rtx label)
3923 {
3924   rtx op0 = x, op1 = y;
3925
3926   /* Swap operands and condition to ensure canonical RTL.  */
3927   if (swap_commutative_operands_p (x, y))
3928     {
3929       /* If we're not emitting a branch, this means some caller
3930          is out of sync.  */
3931       if (! label)
3932         abort ();
3933
3934       op0 = y, op1 = x;
3935       comparison = swap_condition (comparison);
3936     }
3937
3938 #ifdef HAVE_cc0
3939   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3940      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3941      RTL.  */
3942   if (CONSTANT_P (op0))
3943     op0 = force_reg (mode, op0);
3944 #endif
3945
3946   emit_queue ();
3947   if (unsignedp)
3948     comparison = unsigned_condition (comparison);
3949
3950   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3951                     ccp_jump);
3952   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3953 }
3954
3955 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3956
3957 void
3958 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3959                enum machine_mode mode, int unsignedp)
3960 {
3961   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3962 }
3963 \f
3964 /* Emit a library call comparison between floating point X and Y.
3965    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3966
3967 static void
3968 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3969                        enum machine_mode *pmode, int *punsignedp)
3970 {
3971   enum rtx_code comparison = *pcomparison;
3972   enum rtx_code swapped = swap_condition (comparison);
3973   rtx x = protect_from_queue (*px, 0);
3974   rtx y = protect_from_queue (*py, 0);
3975   enum machine_mode orig_mode = GET_MODE (x);
3976   enum machine_mode mode;
3977   rtx value, target, insns, equiv;
3978   rtx libfunc = 0;
3979
3980   for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
3981     {
3982       if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3983         break;
3984
3985       if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3986         {
3987           rtx tmp;
3988           tmp = x; x = y; y = tmp;
3989           comparison = swapped;
3990           break;
3991         }
3992     }
3993
3994   if (mode == VOIDmode)
3995     abort ();
3996
3997   if (mode != orig_mode)
3998     {
3999       x = convert_to_mode (mode, x, 0);
4000       y = convert_to_mode (mode, y, 0);
4001     }
4002
4003   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4004      the RTL.  The allows the RTL optimizers to delete the libcall if the
4005      condition can be determined at compile-time.  */
4006   if (comparison == UNORDERED)
4007     {
4008       rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
4009       equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
4010       equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
4011                                     temp, const_true_rtx, equiv);
4012     }
4013   else
4014     {