OSDN Git Service

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