OSDN Git Service

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