OSDN Git Service

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