OSDN Git Service

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