OSDN Git Service

Daily bump.
[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       && ! flag_trapv)
2510     {
2511       rtx real, imag, total;
2512
2513       real = gen_realpart (submode, op0);
2514       imag = gen_imagpart (submode, op0);
2515
2516       /* Square both parts.  */
2517       real = expand_mult (submode, real, real, NULL_RTX, 0);
2518       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2519
2520       /* Sum the parts.  */
2521       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2522                             0, OPTAB_LIB_WIDEN);
2523
2524       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
2525       target = expand_unop (submode, sqrt_optab, total, target, 0);
2526       if (target == 0)
2527         delete_insns_since (last);
2528       else
2529         return target;
2530     }
2531
2532   /* Now try a library call in this mode.  */
2533   if (this_abs_optab->handlers[(int) mode].libfunc)
2534     {
2535       rtx insns;
2536       rtx value;
2537
2538       start_sequence ();
2539
2540       /* Pass 1 for NO_QUEUE so we don't lose any increments
2541          if the libcall is cse'd or moved.  */
2542       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2543                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2544       insns = get_insns ();
2545       end_sequence ();
2546
2547       target = gen_reg_rtx (submode);
2548       emit_libcall_block (insns, target, value,
2549                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2550
2551       return target;
2552     }
2553
2554   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2555
2556   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2557        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2558     {
2559       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2560            != CODE_FOR_nothing)
2561           || this_abs_optab->handlers[(int) wider_mode].libfunc)
2562         {
2563           rtx xop0 = op0;
2564
2565           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2566
2567           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2568
2569           if (temp)
2570             {
2571               if (class != MODE_COMPLEX_INT)
2572                 {
2573                   if (target == 0)
2574                     target = gen_reg_rtx (submode);
2575                   convert_move (target, temp, 0);
2576                   return target;
2577                 }
2578               else
2579                 return gen_lowpart (submode, temp);
2580             }
2581           else
2582             delete_insns_since (last);
2583         }
2584     }
2585
2586   delete_insns_since (entry_last);
2587   return 0;
2588 }
2589 \f
2590 /* Generate an instruction whose insn-code is INSN_CODE,
2591    with two operands: an output TARGET and an input OP0.
2592    TARGET *must* be nonzero, and the output is always stored there.
2593    CODE is an rtx code such that (CODE OP0) is an rtx that describes
2594    the value that is stored into TARGET.  */
2595
2596 void
2597 emit_unop_insn (icode, target, op0, code)
2598      int icode;
2599      rtx target;
2600      rtx op0;
2601      enum rtx_code code;
2602 {
2603   register rtx temp;
2604   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2605   rtx pat;
2606
2607   temp = target = protect_from_queue (target, 1);
2608
2609   op0 = protect_from_queue (op0, 0);
2610
2611   /* Sign and zero extension from memory is often done specially on
2612      RISC machines, so forcing into a register here can pessimize
2613      code.  */
2614   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2615     op0 = force_not_mem (op0);
2616
2617   /* Now, if insn does not accept our operands, put them into pseudos.  */
2618
2619   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2620     op0 = copy_to_mode_reg (mode0, op0);
2621
2622   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2623       || (flag_force_mem && GET_CODE (temp) == MEM))
2624     temp = gen_reg_rtx (GET_MODE (temp));
2625
2626   pat = GEN_FCN (icode) (temp, op0);
2627
2628   if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2629     add_equal_note (pat, temp, code, op0, NULL_RTX);
2630   
2631   emit_insn (pat);
2632
2633   if (temp != target)
2634     emit_move_insn (target, temp);
2635 }
2636 \f
2637 /* Emit code to perform a series of operations on a multi-word quantity, one
2638    word at a time.
2639
2640    Such a block is preceded by a CLOBBER of the output, consists of multiple
2641    insns, each setting one word of the output, and followed by a SET copying
2642    the output to itself.
2643
2644    Each of the insns setting words of the output receives a REG_NO_CONFLICT
2645    note indicating that it doesn't conflict with the (also multi-word)
2646    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2647    notes.
2648
2649    INSNS is a block of code generated to perform the operation, not including
2650    the CLOBBER and final copy.  All insns that compute intermediate values
2651    are first emitted, followed by the block as described above.  
2652
2653    TARGET, OP0, and OP1 are the output and inputs of the operations,
2654    respectively.  OP1 may be zero for a unary operation.
2655
2656    EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2657    on the last insn.
2658
2659    If TARGET is not a register, INSNS is simply emitted with no special
2660    processing.  Likewise if anything in INSNS is not an INSN or if
2661    there is a libcall block inside INSNS.
2662
2663    The final insn emitted is returned.  */
2664
2665 rtx
2666 emit_no_conflict_block (insns, target, op0, op1, equiv)
2667      rtx insns;
2668      rtx target;
2669      rtx op0, op1;
2670      rtx equiv;
2671 {
2672   rtx prev, next, first, last, insn;
2673
2674   if (GET_CODE (target) != REG || reload_in_progress)
2675     return emit_insns (insns);
2676   else
2677     for (insn = insns; insn; insn = NEXT_INSN (insn))
2678       if (GET_CODE (insn) != INSN
2679           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2680         return emit_insns (insns);
2681
2682   /* First emit all insns that do not store into words of the output and remove
2683      these from the list.  */
2684   for (insn = insns; insn; insn = next)
2685     {
2686       rtx set = 0;
2687       int i;
2688
2689       next = NEXT_INSN (insn);
2690
2691       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2692           || GET_CODE (PATTERN (insn)) == CLOBBER)
2693         set = PATTERN (insn);
2694       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2695         {
2696           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2697             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2698               {
2699                 set = XVECEXP (PATTERN (insn), 0, i);
2700                 break;
2701               }
2702         }
2703
2704       if (set == 0)
2705         abort ();
2706
2707       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2708         {
2709           if (PREV_INSN (insn))
2710             NEXT_INSN (PREV_INSN (insn)) = next;
2711           else
2712             insns = next;
2713
2714           if (next)
2715             PREV_INSN (next) = PREV_INSN (insn);
2716
2717           add_insn (insn);
2718         }
2719     }
2720
2721   prev = get_last_insn ();
2722
2723   /* Now write the CLOBBER of the output, followed by the setting of each
2724      of the words, followed by the final copy.  */
2725   if (target != op0 && target != op1)
2726     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2727
2728   for (insn = insns; insn; insn = next)
2729     {
2730       next = NEXT_INSN (insn);
2731       add_insn (insn);
2732
2733       if (op1 && GET_CODE (op1) == REG)
2734         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2735                                               REG_NOTES (insn));
2736
2737       if (op0 && GET_CODE (op0) == REG)
2738         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2739                                               REG_NOTES (insn));
2740     }
2741
2742   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2743       != CODE_FOR_nothing)
2744     {
2745       last = emit_move_insn (target, target);
2746       if (equiv)
2747         set_unique_reg_note (last, REG_EQUAL, equiv);
2748     }
2749   else
2750     {
2751       last = get_last_insn ();
2752
2753       /* Remove any existing REG_EQUAL note from "last", or else it will
2754          be mistaken for a note referring to the full contents of the
2755          alleged libcall value when found together with the REG_RETVAL
2756          note added below.  An existing note can come from an insn
2757          expansion at "last".  */
2758       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2759     }
2760
2761   if (prev == 0)
2762     first = get_insns ();
2763   else
2764     first = NEXT_INSN (prev);
2765
2766   /* Encapsulate the block so it gets manipulated as a unit.  */
2767   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2768                                          REG_NOTES (first));
2769   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2770
2771   return last;
2772 }
2773 \f
2774 /* Emit code to make a call to a constant function or a library call.
2775
2776    INSNS is a list containing all insns emitted in the call.
2777    These insns leave the result in RESULT.  Our block is to copy RESULT
2778    to TARGET, which is logically equivalent to EQUIV.
2779
2780    We first emit any insns that set a pseudo on the assumption that these are
2781    loading constants into registers; doing so allows them to be safely cse'ed
2782    between blocks.  Then we emit all the other insns in the block, followed by
2783    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
2784    note with an operand of EQUIV.
2785
2786    Moving assignments to pseudos outside of the block is done to improve
2787    the generated code, but is not required to generate correct code,
2788    hence being unable to move an assignment is not grounds for not making
2789    a libcall block.  There are two reasons why it is safe to leave these
2790    insns inside the block: First, we know that these pseudos cannot be
2791    used in generated RTL outside the block since they are created for
2792    temporary purposes within the block.  Second, CSE will not record the
2793    values of anything set inside a libcall block, so we know they must
2794    be dead at the end of the block.
2795
2796    Except for the first group of insns (the ones setting pseudos), the
2797    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
2798
2799 void
2800 emit_libcall_block (insns, target, result, equiv)
2801      rtx insns;
2802      rtx target;
2803      rtx result;
2804      rtx equiv;
2805 {
2806   rtx final_dest = target;
2807   rtx prev, next, first, last, insn;
2808
2809   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2810      into a MEM later.  Protect the libcall block from this change.  */
2811   if (! REG_P (target) || REG_USERVAR_P (target))
2812     target = gen_reg_rtx (GET_MODE (target));
2813
2814   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2815      reg note to indicate that this call cannot throw or execute a nonlocal
2816      goto (unless there is already a REG_EH_REGION note, in which case
2817      we update it).  Also set the CONST_CALL_P flag.  */
2818
2819   for (insn = insns; insn; insn = NEXT_INSN (insn))
2820     if (GET_CODE (insn) == CALL_INSN)
2821       {
2822         rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2823
2824         CONST_CALL_P (insn) = 1;
2825         if (note != 0)
2826           XEXP (note, 0) = GEN_INT (-1);
2827         else
2828           REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2829                                                 REG_NOTES (insn));
2830       }
2831
2832   /* First emit all insns that set pseudos.  Remove them from the list as
2833      we go.  Avoid insns that set pseudos which were referenced in previous
2834      insns.  These can be generated by move_by_pieces, for example,
2835      to update an address.  Similarly, avoid insns that reference things
2836      set in previous insns.  */
2837
2838   for (insn = insns; insn; insn = next)
2839     {
2840       rtx set = single_set (insn);
2841
2842       next = NEXT_INSN (insn);
2843
2844       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2845           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2846           && (insn == insns
2847               || ((! INSN_P(insns)
2848                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2849                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
2850                   && ! modified_in_p (SET_SRC (set), insns)
2851                   && ! modified_between_p (SET_SRC (set), insns, insn))))
2852         {
2853           if (PREV_INSN (insn))
2854             NEXT_INSN (PREV_INSN (insn)) = next;
2855           else
2856             insns = next;
2857
2858           if (next)
2859             PREV_INSN (next) = PREV_INSN (insn);
2860
2861           add_insn (insn);
2862         }
2863     }
2864
2865   prev = get_last_insn ();
2866
2867   /* Write the remaining insns followed by the final copy.  */
2868
2869   for (insn = insns; insn; insn = next)
2870     {
2871       next = NEXT_INSN (insn);
2872
2873       add_insn (insn);
2874     }
2875
2876   last = emit_move_insn (target, result);
2877   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2878       != CODE_FOR_nothing)
2879     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2880   else
2881     {
2882       /* Remove any existing REG_EQUAL note from "last", or else it will
2883          be mistaken for a note referring to the full contents of the
2884          libcall value when found together with the REG_RETVAL note added
2885          below.  An existing note can come from an insn expansion at
2886          "last".  */
2887       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2888     }
2889
2890   if (final_dest != target)
2891     emit_move_insn (final_dest, target);
2892
2893   if (prev == 0)
2894     first = get_insns ();
2895   else
2896     first = NEXT_INSN (prev);
2897
2898   /* Encapsulate the block so it gets manipulated as a unit.  */
2899   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2900                                          REG_NOTES (first));
2901   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2902 }
2903 \f
2904 /* Generate code to store zero in X.  */
2905
2906 void
2907 emit_clr_insn (x)
2908      rtx x;
2909 {
2910   emit_move_insn (x, const0_rtx);
2911 }
2912
2913 /* Generate code to store 1 in X
2914    assuming it contains zero beforehand.  */
2915
2916 void
2917 emit_0_to_1_insn (x)
2918      rtx x;
2919 {
2920   emit_move_insn (x, const1_rtx);
2921 }
2922
2923 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2924    PURPOSE describes how this comparison will be used.  CODE is the rtx
2925    comparison code we will be using.
2926
2927    ??? Actually, CODE is slightly weaker than that.  A target is still
2928    required to implement all of the normal bcc operations, but not 
2929    required to implement all (or any) of the unordered bcc operations.  */
2930   
2931 int
2932 can_compare_p (code, mode, purpose)
2933      enum rtx_code code;
2934      enum machine_mode mode;
2935      enum can_compare_purpose purpose;
2936 {
2937   do
2938     {
2939       if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2940         {
2941           if (purpose == ccp_jump)
2942             return bcc_gen_fctn[(int)code] != NULL;
2943           else if (purpose == ccp_store_flag)
2944             return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2945           else
2946             /* There's only one cmov entry point, and it's allowed to fail.  */
2947             return 1;
2948         }
2949       if (purpose == ccp_jump
2950           && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2951         return 1;
2952       if (purpose == ccp_cmov
2953           && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2954         return 1;
2955       if (purpose == ccp_store_flag
2956           && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2957         return 1;
2958
2959       mode = GET_MODE_WIDER_MODE (mode);
2960     }
2961   while (mode != VOIDmode);
2962
2963   return 0;
2964 }
2965
2966 /* This function is called when we are going to emit a compare instruction that
2967    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2968
2969    *PMODE is the mode of the inputs (in case they are const_int).
2970    *PUNSIGNEDP nonzero says that the operands are unsigned;
2971    this matters if they need to be widened.
2972
2973    If they have mode BLKmode, then SIZE specifies the size of both operands,
2974    and ALIGN specifies the known shared alignment of the operands.
2975
2976    This function performs all the setup necessary so that the caller only has
2977    to emit a single comparison insn.  This setup can involve doing a BLKmode
2978    comparison or emitting a library call to perform the comparison if no insn
2979    is available to handle it.
2980    The values which are passed in through pointers can be modified; the caller
2981    should perform the comparison on the modified values.  */
2982
2983 void
2984 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2985                   purpose)
2986      rtx *px, *py;
2987      enum rtx_code *pcomparison;
2988      rtx size;
2989      enum machine_mode *pmode;
2990      int *punsignedp;
2991      int align ATTRIBUTE_UNUSED;
2992      enum can_compare_purpose purpose;
2993 {
2994   enum machine_mode mode = *pmode;
2995   rtx x = *px, y = *py;
2996   int unsignedp = *punsignedp;
2997   enum mode_class class;
2998   rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
2999
3000   class = GET_MODE_CLASS (mode);
3001
3002   /* They could both be VOIDmode if both args are immediate constants,
3003      but we should fold that at an earlier stage.
3004      With no special code here, this will call abort,
3005      reminding the programmer to implement such folding.  */
3006
3007   if (mode != BLKmode && flag_force_mem)
3008     {
3009       x = force_not_mem (x);
3010       y = force_not_mem (y);
3011     }
3012
3013   /* If we are inside an appropriately-short loop and one operand is an
3014      expensive constant, force it into a register.  */
3015   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3016       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3017     x = force_reg (mode, x);
3018
3019   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3020       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3021     y = force_reg (mode, y);
3022
3023 #ifdef HAVE_cc0
3024   /* Abort if we have a non-canonical comparison.  The RTL documentation
3025      states that canonical comparisons are required only for targets which
3026      have cc0.  */
3027   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3028     abort();
3029 #endif
3030
3031   /* Don't let both operands fail to indicate the mode.  */
3032   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3033     x = force_reg (mode, x);
3034
3035   /* Handle all BLKmode compares.  */
3036
3037   if (mode == BLKmode)
3038     {
3039       rtx result;
3040       enum machine_mode result_mode;
3041
3042       emit_queue ();
3043       x = protect_from_queue (x, 0);
3044       y = protect_from_queue (y, 0);
3045
3046       if (size == 0)
3047         abort ();
3048 #ifdef HAVE_cmpstrqi
3049       if (HAVE_cmpstrqi
3050           && GET_CODE (size) == CONST_INT
3051           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3052         {
3053           result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3054           result = gen_reg_rtx (result_mode);
3055           emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3056         }
3057       else
3058 #endif
3059 #ifdef HAVE_cmpstrhi
3060       if (HAVE_cmpstrhi
3061           && GET_CODE (size) == CONST_INT
3062           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3063         {
3064           result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3065           result = gen_reg_rtx (result_mode);
3066           emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3067         }
3068       else
3069 #endif
3070 #ifdef HAVE_cmpstrsi
3071       if (HAVE_cmpstrsi)
3072         {
3073           result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3074           result = gen_reg_rtx (result_mode);
3075           size = protect_from_queue (size, 0);
3076           emit_insn (gen_cmpstrsi (result, x, y,
3077                                    convert_to_mode (SImode, size, 1),
3078                                    opalign));
3079         }
3080       else
3081 #endif
3082         {
3083 #ifdef TARGET_MEM_FUNCTIONS
3084           emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3085                              TYPE_MODE (integer_type_node), 3,
3086                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3087                              convert_to_mode (TYPE_MODE (sizetype), size,
3088                                               TREE_UNSIGNED (sizetype)),
3089                              TYPE_MODE (sizetype));
3090 #else
3091           emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3092                              TYPE_MODE (integer_type_node), 3,
3093                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3094                              convert_to_mode (TYPE_MODE (integer_type_node),
3095                                               size,
3096                                               TREE_UNSIGNED (integer_type_node)),
3097                              TYPE_MODE (integer_type_node));
3098 #endif
3099
3100           /* Immediately move the result of the libcall into a pseudo
3101              register so reload doesn't clobber the value if it needs
3102              the return register for a spill reg.  */
3103           result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3104           result_mode = TYPE_MODE (integer_type_node);
3105           emit_move_insn (result,
3106                           hard_libcall_value (result_mode));
3107         }
3108       *px = result;
3109       *py = const0_rtx;
3110       *pmode = result_mode;
3111       return;
3112     }
3113
3114   *px = x;
3115   *py = y;
3116   if (can_compare_p (*pcomparison, mode, purpose))
3117     return;
3118
3119   /* Handle a lib call just for the mode we are using.  */
3120
3121   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3122     {
3123       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3124       rtx result;
3125
3126       /* If we want unsigned, and this mode has a distinct unsigned
3127          comparison routine, use that.  */
3128       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3129         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3130
3131       emit_library_call (libfunc, 1,
3132                          word_mode, 2, x, mode, y, mode);
3133
3134       /* Immediately move the result of the libcall into a pseudo
3135          register so reload doesn't clobber the value if it needs
3136          the return register for a spill reg.  */
3137       result = gen_reg_rtx (word_mode);
3138       emit_move_insn (result, hard_libcall_value (word_mode));
3139
3140       /* Integer comparison returns a result that must be compared against 1,
3141          so that even if we do an unsigned compare afterward,
3142          there is still a value that can represent the result "less than".  */
3143       *px = result;
3144       *py = const1_rtx;
3145       *pmode = word_mode;
3146       return;
3147     }
3148
3149   if (class == MODE_FLOAT)
3150     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3151
3152   else
3153     abort ();
3154 }
3155
3156 /* Before emitting an insn with code ICODE, make sure that X, which is going
3157    to be used for operand OPNUM of the insn, is converted from mode MODE to
3158    WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3159    that it is accepted by the operand predicate.  Return the new value.  */
3160
3161 rtx
3162 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3163      int icode;
3164      rtx x;
3165      int opnum;
3166      enum machine_mode mode, wider_mode;
3167      int unsignedp;
3168 {
3169   x = protect_from_queue (x, 0);
3170
3171   if (mode != wider_mode)
3172     x = convert_modes (wider_mode, mode, x, unsignedp);
3173
3174   if (! (*insn_data[icode].operand[opnum].predicate)
3175       (x, insn_data[icode].operand[opnum].mode))
3176     x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3177   return x;
3178 }
3179
3180 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3181    we can do the comparison.
3182    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3183    be NULL_RTX which indicates that only a comparison is to be generated.  */
3184
3185 static void
3186 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3187      rtx x, y;
3188      enum machine_mode mode;
3189      enum rtx_code comparison;
3190      int unsignedp;
3191      rtx label;
3192 {
3193   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3194   enum mode_class class = GET_MODE_CLASS (mode);
3195   enum machine_mode wider_mode = mode;
3196
3197   /* Try combined insns first.  */
3198   do
3199     {
3200       enum insn_code icode;
3201       PUT_MODE (test, wider_mode);
3202
3203       if (label)
3204         {         
3205           icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3206           
3207           if (icode != CODE_FOR_nothing
3208               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3209             {
3210               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3211               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3212               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3213               return;
3214             }
3215         }
3216
3217       /* Handle some compares against zero.  */
3218       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3219       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3220         {
3221           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3222           emit_insn (GEN_FCN (icode) (x));
3223           if (label)
3224             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3225           return;
3226         }
3227
3228       /* Handle compares for which there is a directly suitable insn.  */
3229
3230       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3231       if (icode != CODE_FOR_nothing)
3232         {
3233           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3234           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3235           emit_insn (GEN_FCN (icode) (x, y));
3236           if (label)
3237             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3238           return;
3239         }
3240
3241       if (class != MODE_INT && class != MODE_FLOAT
3242           && class != MODE_COMPLEX_FLOAT)
3243         break;
3244
3245       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3246     } while (wider_mode != VOIDmode);
3247
3248   abort ();
3249 }
3250
3251 /* Generate code to compare X with Y so that the condition codes are
3252    set and to jump to LABEL if the condition is true.  If X is a
3253    constant and Y is not a constant, then the comparison is swapped to
3254    ensure that the comparison RTL has the canonical form.
3255
3256    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3257    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3258    the proper branch condition code.
3259
3260    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3261    and ALIGN specifies the known shared alignment of X and Y. 
3262
3263    MODE is the mode of the inputs (in case they are const_int).
3264
3265    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3266    be passed unchanged to emit_cmp_insn, then potentially converted into an
3267    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3268
3269 void
3270 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3271      rtx x, y;
3272      enum rtx_code comparison;
3273      rtx size;
3274      enum machine_mode mode;
3275      int unsignedp;
3276      unsigned int align;
3277      rtx label;
3278 {
3279   rtx op0;
3280   rtx op1;
3281           
3282   if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3283       || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3284     {
3285       /* Swap operands and condition to ensure canonical RTL.  */
3286       op0 = y;
3287       op1 = x;
3288       comparison = swap_condition (comparison);
3289     }
3290   else
3291     {
3292       op0 = x;
3293       op1 = y;
3294     }
3295
3296 #ifdef HAVE_cc0
3297   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3298      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3299      RTL.  */
3300   if (CONSTANT_P (op0))
3301     op0 = force_reg (mode, op0);
3302 #endif
3303
3304   emit_queue ();
3305   if (unsignedp)
3306     comparison = unsigned_condition (comparison);
3307   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3308                     ccp_jump);
3309   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3310 }
3311
3312 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3313
3314 void
3315 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3316      rtx x, y;
3317      enum rtx_code comparison;
3318      rtx size;
3319      enum machine_mode mode;
3320      int unsignedp;
3321      unsigned int align;
3322 {
3323   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3324 }
3325 \f
3326 /* Emit a library call comparison between floating point X and Y.
3327    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3328
3329 static void
3330 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3331      rtx *px, *py;
3332      enum rtx_code *pcomparison;
3333      enum machine_mode *pmode;
3334      int *punsignedp;
3335 {
3336   enum rtx_code comparison = *pcomparison;
3337   rtx x = *px = protect_from_queue (*px, 0);
3338   rtx y = *py = protect_from_queue (*py, 0);
3339   enum machine_mode mode = GET_MODE (x);
3340   rtx libfunc = 0;
3341   rtx result;
3342
3343   if (mode == HFmode)
3344     switch (comparison)
3345       {
3346       case EQ:
3347         libfunc = eqhf2_libfunc;
3348         break;
3349
3350       case NE:
3351         libfunc = nehf2_libfunc;
3352         break;
3353
3354       case GT:
3355         libfunc = gthf2_libfunc;
3356         break;
3357
3358       case GE:
3359         libfunc = gehf2_libfunc;
3360         break;
3361
3362       case LT:
3363         libfunc = lthf2_libfunc;
3364         break;
3365
3366       case LE:
3367         libfunc = lehf2_libfunc;
3368         break;
3369
3370       case UNORDERED:
3371         libfunc = unordhf2_libfunc;
3372         break;
3373
3374       default:
3375         break;
3376       }
3377   else if (mode == SFmode)
3378     switch (comparison)
3379       {
3380       case EQ:
3381         libfunc = eqsf2_libfunc;
3382         break;
3383
3384       case NE:
3385         libfunc = nesf2_libfunc;
3386         break;
3387
3388       case GT:
3389         libfunc = gtsf2_libfunc;
3390         break;
3391
3392       case GE:
3393         libfunc = gesf2_libfunc;
3394         break;
3395
3396       case LT:
3397         libfunc = ltsf2_libfunc;
3398         break;
3399
3400       case LE:
3401         libfunc = lesf2_libfunc;
3402         break;
3403
3404       case UNORDERED:
3405         libfunc = unordsf2_libfunc;
3406         break;
3407
3408       default:
3409         break;
3410       }
3411   else if (mode == DFmode)
3412     switch (comparison)
3413       {
3414       case EQ:
3415         libfunc = eqdf2_libfunc;
3416         break;
3417
3418       case NE:
3419         libfunc = nedf2_libfunc;
3420         break;
3421
3422       case GT:
3423         libfunc = gtdf2_libfunc;
3424         break;
3425
3426       case GE:
3427         libfunc = gedf2_libfunc;
3428         break;
3429
3430       case LT:
3431         libfunc = ltdf2_libfunc;
3432         break;
3433
3434       case LE:
3435         libfunc = ledf2_libfunc;
3436         break;
3437
3438       case UNORDERED:
3439         libfunc = unorddf2_libfunc;
3440         break;
3441
3442       default:
3443         break;
3444       }
3445   else if (mode == XFmode)
3446     switch (comparison)
3447       {
3448       case EQ:
3449         libfunc = eqxf2_libfunc;
3450         break;
3451
3452       case NE:
3453         libfunc = nexf2_libfunc;
3454         break;
3455
3456       case GT:
3457         libfunc = gtxf2_libfunc;
3458         break;
3459
3460       case GE:
3461         libfunc = gexf2_libfunc;
3462         break;
3463
3464       case LT:
3465         libfunc = ltxf2_libfunc;
3466         break;
3467
3468       case LE:
3469         libfunc = lexf2_libfunc;
3470         break;
3471
3472       case UNORDERED:
3473         libfunc = unordxf2_libfunc;
3474         break;
3475
3476       default:
3477         break;
3478       }
3479   else if (mode == TFmode)
3480     switch (comparison)
3481       {
3482       case EQ:
3483         libfunc = eqtf2_libfunc;
3484         break;
3485
3486       case NE:
3487         libfunc = netf2_libfunc;
3488         break;
3489
3490       case GT:
3491         libfunc = gttf2_libfunc;
3492         break;
3493
3494       case GE:
3495         libfunc = getf2_libfunc;
3496         break;
3497
3498       case LT:
3499         libfunc = lttf2_libfunc;
3500         break;
3501
3502       case LE:
3503         libfunc = letf2_libfunc;
3504         break;
3505
3506       case UNORDERED:
3507         libfunc = unordtf2_libfunc;
3508         break;
3509
3510       default:
3511         break;
3512       }
3513   else
3514     {
3515       enum machine_mode wider_mode;
3516
3517       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3518            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3519         {
3520           if ((cmp_optab->handlers[(int) wider_mode].insn_code
3521                != CODE_FOR_nothing)
3522               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3523             {
3524               x = protect_from_queue (x, 0);
3525               y = protect_from_queue (y, 0);
3526               *px = convert_to_mode (wider_mode, x, 0);
3527               *py = convert_to_mode (wider_mode, y, 0);
3528               prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3529               return;
3530             }
3531         }
3532       abort ();
3533     }
3534
3535   if (libfunc == 0)
3536     abort ();
3537
3538   emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3539                      mode);
3540
3541   /* Immediately move the result of the libcall into a pseudo
3542      register so reload doesn't clobber the value if it needs
3543      the return register for a spill reg.  */
3544   result = gen_reg_rtx (word_mode);
3545   emit_move_insn (result, hard_libcall_value (word_mode));
3546   *px = result;
3547   *py = const0_rtx;
3548   *pmode = word_mode;
3549   if (comparison == UNORDERED)
3550     *pcomparison = NE;
3551 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3552   else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3553     *pcomparison = NE;
3554 #endif
3555   *punsignedp = 0;
3556 }
3557 \f
3558 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
3559
3560 void
3561 emit_indirect_jump (loc)
3562      rtx loc;
3563 {
3564   if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3565          (loc, Pmode)))
3566     loc = copy_to_mode_reg (Pmode, loc);
3567
3568   emit_jump_insn (gen_indirect_jump (loc));
3569   emit_barrier ();
3570 }
3571 \f
3572 #ifdef HAVE_conditional_move
3573
3574 /* Emit a conditional move instruction if the machine supports one for that
3575    condition and machine mode.
3576
3577    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
3578    the mode to use should they be constants.  If it is VOIDmode, they cannot
3579    both be constants.
3580
3581    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3582    should be stored there.  MODE is the mode to use should they be constants.
3583    If it is VOIDmode, they cannot both be constants.
3584
3585    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3586    is not supported.  */
3587
3588 rtx
3589 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3590                        unsignedp)
3591      rtx target;
3592      enum rtx_code code;
3593      rtx op0, op1;
3594      enum machine_mode cmode;
3595      rtx op2, op3;
3596      enum machine_mode mode;
3597      int unsignedp;
3598 {
3599   rtx tem, subtarget, comparison, insn;
3600   enum insn_code icode;
3601
3602   /* If one operand is constant, make it the second one.  Only do this
3603      if the other operand is not constant as well.  */
3604
3605   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3606       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3607     {
3608       tem = op0;
3609       op0 = op1;
3610       op1 = tem;
3611       code = swap_condition (code);
3612     }
3613
3614   /* get_condition will prefer to generate LT and GT even if the old
3615      comparison was against zero, so undo that canonicalization here since
3616      comparisons against zero are cheaper.  */
3617   if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3618     code = LE, op1 = const0_rtx;
3619   else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3620     code = GE, op1 = const0_rtx;
3621
3622   if (cmode == VOIDmode)
3623     cmode = GET_MODE (op0);
3624
3625   if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3626        || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3627       && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3628           || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3629     {
3630       tem = op2;
3631       op2 = op3;
3632       op3 = tem;
3633       code = reverse_condition (code);
3634     }
3635
3636   if (mode == VOIDmode)
3637     mode = GET_MODE (op2);
3638
3639   icode = movcc_gen_code[mode];
3640
3641   if (icode == CODE_FOR_nothing)
3642     return 0;
3643
3644   if (flag_force_mem)
3645     {
3646       op2 = force_not_mem (op2);
3647       op3 = force_not_mem (op3);
3648     }
3649
3650   if (target)
3651     target = protect_from_queue (target, 1);
3652   else
3653     target = gen_reg_rtx (mode);
3654
3655   subtarget = target;
3656
3657   emit_queue ();
3658
3659   op2 = protect_from_queue (op2, 0);
3660   op3 = protect_from_queue (op3, 0);
3661
3662   /* If the insn doesn't accept these operands, put them in pseudos.  */
3663
3664   if (! (*insn_data[icode].operand[0].predicate)
3665       (subtarget, insn_data[icode].operand[0].mode))
3666     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3667
3668   if (! (*insn_data[icode].operand[2].predicate)
3669       (op2, insn_data[icode].operand[2].mode))
3670     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3671
3672   if (! (*insn_data[icode].operand[3].predicate)
3673       (op3, insn_data[icode].operand[3].mode))
3674     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3675
3676   /* Everything should now be in the suitable form, so emit the compare insn
3677      and then the conditional move.  */
3678
3679   comparison 
3680     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3681
3682   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
3683   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
3684      return NULL and let the caller figure out how best to deal with this
3685      situation.  */
3686   if (GET_CODE (comparison) != code)
3687     return NULL_RTX;
3688   
3689   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3690
3691   /* If that failed, then give up.  */
3692   if (insn == 0)
3693     return 0;
3694
3695   emit_insn (insn);
3696
3697   if (subtarget != target)
3698     convert_move (target, subtarget, 0);
3699
3700   return target;
3701 }
3702
3703 /* Return non-zero if a conditional move of mode MODE is supported.
3704
3705    This function is for combine so it can tell whether an insn that looks
3706    like a conditional move is actually supported by the hardware.  If we
3707    guess wrong we lose a bit on optimization, but that's it.  */
3708 /* ??? sparc64 supports conditionally moving integers values based on fp
3709    comparisons, and vice versa.  How do we handle them?  */
3710
3711 int
3712 can_conditionally_move_p (mode)
3713      enum machine_mode mode;
3714 {
3715   if (movcc_gen_code[mode] != CODE_FOR_nothing)
3716     return 1;
3717
3718   return 0;
3719 }
3720
3721 #endif /* HAVE_conditional_move */
3722 \f
3723 /* These three functions generate an insn body and return it
3724    rather than emitting the insn.
3725
3726    They do not protect from queued increments,
3727    because they may be used 1) in protect_from_queue itself
3728    and 2) in other passes where there is no queue.  */
3729
3730 /* Generate and return an insn body to add Y to X.  */
3731
3732 rtx
3733 gen_add2_insn (x, y)
3734      rtx x, y;
3735 {
3736   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
3737
3738   if (! ((*insn_data[icode].operand[0].predicate)
3739          (x, insn_data[icode].operand[0].mode))
3740       || ! ((*insn_data[icode].operand[1].predicate)
3741             (x, insn_data[icode].operand[1].mode))
3742       || ! ((*insn_data[icode].operand[2].predicate)
3743             (y, insn_data[icode].operand[2].mode)))
3744     abort ();
3745
3746   return (GEN_FCN (icode) (x, x, y));
3747 }
3748
3749 int
3750 have_add2_insn (mode)
3751      enum machine_mode mode;
3752 {
3753   return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3754 }
3755
3756 /* Generate and return an insn body to subtract Y from X.  */
3757
3758 rtx
3759 gen_sub2_insn (x, y)
3760      rtx x, y;
3761 {
3762   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
3763
3764   if (! ((*insn_data[icode].operand[0].predicate)
3765          (x, insn_data[icode].operand[0].mode))
3766       || ! ((*insn_data[icode].operand[1].predicate)
3767             (x, insn_data[icode].operand[1].mode))
3768       || ! ((*insn_data[icode].operand[2].predicate)
3769             (y, insn_data[icode].operand[2].mode)))
3770     abort ();
3771
3772   return (GEN_FCN (icode) (x, x, y));
3773 }
3774
3775 int
3776 have_sub2_insn (mode)
3777      enum machine_mode mode;
3778 {
3779   return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3780 }
3781
3782 /* Generate the body of an instruction to copy Y into X.
3783    It may be a SEQUENCE, if one insn isn't enough.  */
3784
3785 rtx
3786 gen_move_insn (x, y)
3787      rtx x, y;
3788 {
3789   register enum machine_mode mode = GET_MODE (x);
3790   enum insn_code insn_code;
3791   rtx seq;
3792
3793   if (mode == VOIDmode)
3794     mode = GET_MODE (y); 
3795
3796   insn_code = mov_optab->handlers[(int) mode].insn_code;
3797
3798   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
3799      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
3800      find the MODE_INT mode of the same width.  */
3801
3802   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3803     {
3804       enum machine_mode tmode = VOIDmode;
3805       rtx x1 = x, y1 = y;
3806
3807       if (mode != CCmode
3808           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3809         tmode = CCmode;
3810       else
3811         for (tmode = QImode; tmode != VOIDmode;
3812              tmode = GET_MODE_WIDER_MODE (tmode))
3813           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3814             break;
3815
3816       if (tmode == VOIDmode)
3817         abort ();
3818
3819       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
3820          may call change_address which is not appropriate if we were
3821          called when a reload was in progress.  We don't have to worry
3822          about changing the address since the size in bytes is supposed to
3823          be the same.  Copy the MEM to change the mode and move any
3824          substitutions from the old MEM to the new one.  */
3825
3826       if (reload_in_progress)
3827         {
3828           x = gen_lowpart_common (tmode, x1);
3829           if (x == 0 && GET_CODE (x1) == MEM)
3830             {
3831               x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3832               MEM_COPY_ATTRIBUTES (x, x1);
3833               copy_replacements (x1, x);
3834             }
3835
3836           y = gen_lowpart_common (tmode, y1);
3837           if (y == 0 && GET_CODE (y1) == MEM)
3838             {
3839               y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3840               MEM_COPY_ATTRIBUTES (y, y1);
3841               copy_replacements (y1, y);
3842             }
3843         }
3844       else
3845         {
3846           x = gen_lowpart (tmode, x);
3847           y = gen_lowpart (tmode, y);
3848         }
3849           
3850       insn_code = mov_optab->handlers[(int) tmode].insn_code;
3851       return (GEN_FCN (insn_code) (x, y));
3852     }
3853
3854   start_sequence ();
3855   emit_move_insn_1 (x, y);
3856   seq = gen_sequence ();
3857   end_sequence ();
3858   return seq;
3859 }
3860 \f
3861 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3862    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
3863    no such operation exists, CODE_FOR_nothing will be returned.  */
3864
3865 enum insn_code
3866 can_extend_p (to_mode, from_mode, unsignedp)
3867      enum machine_mode to_mode, from_mode;
3868      int unsignedp;
3869 {
3870   return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3871 }
3872
3873 /* Generate the body of an insn to extend Y (with mode MFROM)
3874    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
3875
3876 rtx
3877 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3878      rtx x, y;
3879      enum machine_mode mto, mfrom;
3880      int unsignedp;
3881 {
3882   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3883 }
3884 \f
3885 /* can_fix_p and can_float_p say whether the target machine
3886    can directly convert a given fixed point type to
3887    a given floating point type, or vice versa.
3888    The returned value is the CODE_FOR_... value to use,
3889    or CODE_FOR_nothing if these modes cannot be directly converted.
3890
3891    *TRUNCP_PTR is set to 1 if it is necessary to output
3892    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
3893
3894 static enum insn_code
3895 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3896      enum machine_mode fltmode, fixmode;
3897      int unsignedp;
3898      int *truncp_ptr;
3899 {
3900   *truncp_ptr = 0;
3901   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3902       != CODE_FOR_nothing)
3903     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3904
3905   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3906     {
3907       *truncp_ptr = 1;
3908       return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3909     }
3910   return CODE_FOR_nothing;
3911 }
3912
3913 static enum insn_code
3914 can_float_p (fltmode, fixmode, unsignedp)
3915      enum machine_mode fixmode, fltmode;
3916      int unsignedp;
3917 {
3918   return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3919 }
3920 \f
3921 /* Generate code to convert FROM to floating point
3922    and store in TO.  FROM must be fixed point and not VOIDmode.
3923    UNSIGNEDP nonzero means regard FROM as unsigned.
3924    Normally this is done by correcting the final value
3925    if it is negative.  */
3926
3927 void
3928 expand_float (to, from, unsignedp)
3929      rtx to, from;
3930      int unsignedp;
3931 {
3932   enum insn_code icode;
3933   register rtx target = to;
3934   enum machine_mode fmode, imode;
3935
3936   /* Crash now, because we won't be able to decide which mode to use.  */
3937   if (GET_MODE (from) == VOIDmode)
3938     abort ();
3939
3940   /* Look for an insn to do the conversion.  Do it in the specified
3941      modes if possible; otherwise convert either input, output or both to
3942      wider mode.  If the integer mode is wider than the mode of FROM,
3943      we can do the conversion signed even if the input is unsigned.  */
3944
3945   for (imode = GET_MODE (from); imode != VOIDmode;
3946        imode = GET_MODE_WIDER_MODE (imode))
3947     for (fmode = GET_MODE (to); fmode != VOIDmode;
3948          fmode = GET_MODE_WIDER_MODE (fmode))
3949       {
3950         int doing_unsigned = unsignedp;
3951
3952         if (fmode != GET_MODE (to)
3953             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3954           continue;
3955
3956         icode = can_float_p (fmode, imode, unsignedp);
3957         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3958           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3959
3960         if (icode != CODE_FOR_nothing)
3961           {
3962             to = protect_from_queue (to, 1);
3963             from = protect_from_queue (from, 0);
3964
3965             if (imode != GET_MODE (from))
3966               from = convert_to_mode (imode, from, unsignedp);
3967
3968             if (fmode != GET_MODE (to))
3969               target = gen_reg_rtx (fmode);
3970
3971             emit_unop_insn (icode, target, from,
3972                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3973
3974             if (target != to)
3975               convert_move (to, target, 0);
3976             return;
3977           }
3978     }
3979
3980 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3981
3982   /* Unsigned integer, and no way to convert directly.
3983      Convert as signed, then conditionally adjust the result.  */
3984   if (unsignedp)
3985     {
3986       rtx label = gen_label_rtx ();
3987       rtx temp;
3988       REAL_VALUE_TYPE offset;
3989
3990       emit_queue ();
3991
3992       to = protect_from_queue (to, 1);
3993       from = protect_from_queue (from, 0);
3994
3995       if (flag_force_mem)
3996         from = force_not_mem (from);
3997
3998       /* Look for a usable floating mode FMODE wider than the source and at
3999          least as wide as the target.  Using FMODE will avoid rounding woes
4000          with unsigned values greater than the signed maximum value.  */
4001
4002       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4003            fmode = GET_MODE_WIDER_MODE (fmode))
4004         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4005             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4006           break;
4007
4008       if (fmode == VOIDmode)
4009         {
4010           /* There is no such mode.  Pretend the target is wide enough.  */
4011           fmode = GET_MODE (to);
4012
4013           /* Avoid double-rounding when TO is narrower than FROM.  */
4014           if ((significand_size (fmode) + 1)
4015               < GET_MODE_BITSIZE (GET_MODE (from)))
4016             {
4017               rtx temp1;
4018               rtx neglabel = gen_label_rtx ();
4019
4020               /* Don't use TARGET if it isn't a register, is a hard register, 
4021                  or is the wrong mode.  */
4022               if (GET_CODE (target) != REG
4023                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4024                   || GET_MODE (target) != fmode)
4025                 target = gen_reg_rtx (fmode);
4026
4027               imode = GET_MODE (from);
4028               do_pending_stack_adjust ();
4029
4030               /* Test whether the sign bit is set.  */
4031               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4032                                        0, 0, neglabel);
4033
4034               /* The sign bit is not set.  Convert as signed.  */
4035               expand_float (target, from, 0);
4036               emit_jump_insn (gen_jump (label));
4037               emit_barrier ();
4038
4039               /* The sign bit is set.
4040                  Convert to a usable (positive signed) value by shifting right
4041                  one bit, while remembering if a nonzero bit was shifted
4042                  out; i.e., compute  (from & 1) | (from >> 1).  */
4043
4044               emit_label (neglabel);
4045               temp = expand_binop (imode, and_optab, from, const1_rtx,
4046                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4047               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4048                                     NULL_RTX, 1);
4049               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
4050                                    OPTAB_LIB_WIDEN);
4051               expand_float (target, temp, 0);
4052
4053               /* Multiply by 2 to undo the shift above.  */
4054               temp = expand_binop (fmode, add_optab, target, target,
4055                                      target, 0, OPTAB_LIB_WIDEN);
4056               if (temp != target)
4057                 emit_move_insn (target, temp);
4058
4059               do_pending_stack_adjust ();
4060               emit_label (label);
4061               goto done;
4062             }
4063         }
4064
4065       /* If we are about to do some arithmetic to correct for an
4066          unsigned operand, do it in a pseudo-register.  */
4067
4068       if (GET_MODE (to) != fmode
4069           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4070         target = gen_reg_rtx (fmode);
4071
4072       /* Convert as signed integer to floating.  */
4073       expand_float (target, from, 0);
4074
4075       /* If FROM is negative (and therefore TO is negative),
4076          correct its value by 2**bitwidth.  */
4077
4078       do_pending_stack_adjust ();
4079       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4080                                 0, 0, label);
4081
4082       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4083          Rather than setting up a dconst_dot_5, let's hope SCO
4084          fixes the bug.  */
4085       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4086       temp = expand_binop (fmode, add_optab, target,
4087                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4088                            target, 0, OPTAB_LIB_WIDEN);
4089       if (temp != target)
4090         emit_move_insn (target, temp);
4091
4092       do_pending_stack_adjust ();
4093       emit_label (label);
4094       goto done;
4095     }
4096 #endif
4097
4098   /* No hardware instruction available; call a library routine to convert from
4099      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4100     {
4101       rtx libfcn;
4102       rtx insns;
4103       rtx value;
4104
4105       to = protect_from_queue (to, 1);
4106       from = protect_from_queue (from, 0);
4107
4108       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4109         from = convert_to_mode (SImode, from, unsignedp);
4110
4111       if (flag_force_mem)
4112         from = force_not_mem (from);
4113
4114       if (GET_MODE (to) == SFmode)
4115         {
4116           if (GET_MODE (from) == SImode)
4117             libfcn = floatsisf_libfunc;
4118           else if (GET_MODE (from) == DImode)
4119             libfcn = floatdisf_libfunc;
4120           else if (GET_MODE (from) == TImode)
4121             libfcn = floattisf_libfunc;
4122           else
4123             abort ();
4124         }
4125       else if (GET_MODE (to) == DFmode)
4126         {
4127           if (GET_MODE (from) == SImode)
4128             libfcn = floatsidf_libfunc;
4129           else if (GET_MODE (from) == DImode)
4130             libfcn = floatdidf_libfunc;
4131           else if (GET_MODE (from) == TImode)
4132             libfcn = floattidf_libfunc;
4133           else
4134             abort ();
4135         }
4136       else if (GET_MODE (to) == XFmode)
4137         {
4138           if (GET_MODE (from) == SImode)
4139             libfcn = floatsixf_libfunc;
4140           else if (GET_MODE (from) == DImode)
4141             libfcn = floatdixf_libfunc;
4142           else if (GET_MODE (from) == TImode)
4143             libfcn = floattixf_libfunc;
4144           else
4145             abort ();
4146         }
4147       else if (GET_MODE (to) == TFmode)
4148         {
4149           if (GET_MODE (from) == SImode)
4150             libfcn = floatsitf_libfunc;
4151           else if (GET_MODE (from) == DImode)
4152             libfcn = floatditf_libfunc;
4153           else if (GET_MODE (from) == TImode)
4154             libfcn = floattitf_libfunc;
4155           else
4156             abort ();
4157         }
4158       else
4159         abort ();
4160
4161       start_sequence ();
4162
4163       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4164                                        GET_MODE (to), 1, from,
4165                                        GET_MODE (from));
4166       insns = get_insns ();
4167       end_sequence ();
4168
4169       emit_libcall_block (insns, target, value,
4170                           gen_rtx_FLOAT (GET_MODE (to), from));
4171     }
4172
4173  done:
4174
4175   /* Copy result to requested destination
4176      if we have been computing in a temp location.  */
4177
4178   if (target != to)
4179     {
4180       if (GET_MODE (target) == GET_MODE (to))
4181         emit_move_insn (to, target);
4182       else
4183         convert_move (to, target, 0);
4184     }
4185 }
4186 \f
4187 /* expand_fix: generate code to convert FROM to fixed point
4188    and store in TO.  FROM must be floating point.  */
4189
4190 static rtx
4191 ftruncify (x)
4192      rtx x;
4193 {
4194   rtx temp = gen_reg_rtx (GET_MODE (x));
4195   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4196 }
4197
4198 void
4199 expand_fix (to, from, unsignedp)
4200      register rtx to, from;
4201      int unsignedp;
4202 {
4203   enum insn_code icode;
4204   register rtx target = to;
4205   enum machine_mode fmode, imode;
4206   int must_trunc = 0;
4207   rtx libfcn = 0;
4208
4209   /* We first try to find a pair of modes, one real and one integer, at
4210      least as wide as FROM and TO, respectively, in which we can open-code
4211      this conversion.  If the integer mode is wider than the mode of TO,
4212      we can do the conversion either signed or unsigned.  */
4213
4214   for (imode = GET_MODE (to); imode != VOIDmode;
4215        imode = GET_MODE_WIDER_MODE (imode))
4216     for (fmode = GET_MODE (from); fmode != VOIDmode;
4217          fmode = GET_MODE_WIDER_MODE (fmode))
4218       {
4219         int doing_unsigned = unsignedp;
4220
4221         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4222         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4223           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4224
4225         if (icode != CODE_FOR_nothing)
4226           {
4227             to = protect_from_queue (to, 1);
4228             from = protect_from_queue (from, 0);
4229
4230             if (fmode != GET_MODE (from))
4231               from = convert_to_mode (fmode, from, 0);
4232
4233             if (must_trunc)
4234               from = ftruncify (from);
4235
4236             if (imode != GET_MODE (to))
4237               target = gen_reg_rtx (imode);
4238
4239             emit_unop_insn (icode, target, from,
4240                             doing_unsigned ? UNSIGNED_FIX : FIX);
4241             if (target != to)
4242               convert_move (to, target, unsignedp);
4243             return;
4244           }
4245       }
4246
4247 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4248   /* For an unsigned conversion, there is one more way to do it.
4249      If we have a signed conversion, we generate code that compares
4250      the real value to the largest representable positive number.  If if
4251      is smaller, the conversion is done normally.  Otherwise, subtract
4252      one plus the highest signed number, convert, and add it back.
4253
4254      We only need to check all real modes, since we know we didn't find
4255      anything with a wider integer mode.  */
4256
4257   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4258     for (fmode = GET_MODE (from); fmode != VOIDmode;
4259          fmode = GET_MODE_WIDER_MODE (fmode))
4260       /* Make sure we won't lose significant bits doing this.  */
4261       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4262           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4263                                             &must_trunc))
4264         {
4265           int bitsize;
4266           REAL_VALUE_TYPE offset;
4267           rtx limit, lab1, lab2, insn;
4268
4269           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4270           offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4271           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4272           lab1 = gen_label_rtx ();
4273           lab2 = gen_label_rtx ();
4274
4275           emit_queue ();
4276           to = protect_from_queue (to, 1);
4277           from = protect_from_queue (from, 0);
4278
4279           if (flag_force_mem)
4280             from = force_not_mem (from);
4281
4282           if (fmode != GET_MODE (from))
4283             from = convert_to_mode (fmode, from, 0);
4284
4285           /* See if we need to do the subtraction.  */
4286           do_pending_stack_adjust ();
4287           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4288                                    0, 0, lab1);
4289
4290           /* If not, do the signed "fix" and branch around fixup code.  */
4291           expand_fix (to, from, 0);
4292           emit_jump_insn (gen_jump (lab2));
4293           emit_barrier ();
4294
4295           /* Otherwise, subtract 2**(N-1), convert to signed number,
4296              then add 2**(N-1).  Do the addition using XOR since this
4297              will often generate better code.  */
4298           emit_label (lab1);
4299           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4300                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
4301           expand_fix (to, target, 0);
4302           target = expand_binop (GET_MODE (to), xor_optab, to,
4303                                  GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4304                                  to, 1, OPTAB_LIB_WIDEN);
4305
4306           if (target != to)
4307             emit_move_insn (to, target);
4308
4309           emit_label (lab2);
4310
4311           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4312               != CODE_FOR_nothing)
4313             {
4314               /* Make a place for a REG_NOTE and add it.  */
4315               insn = emit_move_insn (to, to);
4316               set_unique_reg_note (insn,
4317                                    REG_EQUAL,
4318                                    gen_rtx_fmt_e (UNSIGNED_FIX,
4319                                                   GET_MODE (to),
4320                                                   copy_rtx (from)));
4321             }
4322
4323           return;
4324         }
4325 #endif
4326
4327   /* We can't do it with an insn, so use a library call.  But first ensure
4328      that the mode of TO is at least as wide as SImode, since those are the
4329      only library calls we know about.  */
4330
4331   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4332     {
4333       target = gen_reg_rtx (SImode);
4334
4335       expand_fix (target, from, unsignedp);
4336     }
4337   else if (GET_MODE (from) == SFmode)
4338     {
4339       if (GET_MODE (to) == SImode)
4340         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4341       else if (GET_MODE (to) == DImode)
4342         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4343       else if (GET_MODE (to) == TImode)
4344         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4345       else
4346         abort ();
4347     }
4348   else if (GET_MODE (from) == DFmode)
4349     {
4350       if (GET_MODE (to) == SImode)
4351         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4352       else if (GET_MODE (to) == DImode)
4353         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4354       else if (GET_MODE (to) == TImode)
4355         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4356       else
4357         abort ();
4358     }
4359   else if (GET_MODE (from) == XFmode)
4360     {
4361       if (GET_MODE (to) == SImode)
4362         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4363       else if (GET_MODE (to) == DImode)
4364         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4365       else if (GET_MODE (to) == TImode)
4366         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4367       else
4368         abort ();
4369     }
4370   else if (GET_MODE (from) == TFmode)
4371     {
4372       if (GET_MODE (to) == SImode)
4373         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4374       else if (GET_MODE (to) == DImode)
4375         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4376       else if (GET_MODE (to) == TImode)
4377         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4378       else
4379         abort ();
4380     }
4381   else
4382     abort ();
4383
4384   if (libfcn)
4385     {
4386       rtx insns;
4387       rtx value;
4388
4389       to = protect_from_queue (to, 1);
4390       from = protect_from_queue (from, 0);
4391
4392       if (flag_force_mem)
4393         from = force_not_mem (from);
4394
4395       start_sequence ();
4396
4397       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4398                                        GET_MODE (to), 1, from,
4399                                        GET_MODE (from));
4400       insns = get_insns ();
4401       end_sequence ();
4402
4403       emit_libcall_block (insns, target, value,
4404                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4405                                          GET_MODE (to), from));
4406     }
4407       
4408   if (target != to)
4409     {
4410       if (GET_MODE (to) == GET_MODE (target))
4411         emit_move_insn (to, target);
4412       else
4413         convert_move (to, target, 0);
4414     }
4415 }
4416 \f
4417 static optab
4418 init_optab (code)
4419      enum rtx_code code;
4420 {
4421   int i;
4422   optab op = (optab) xmalloc (sizeof (struct optab));
4423   op->code = code;
4424   for (i = 0; i < NUM_MACHINE_MODES; i++)
4425     {
4426       op->handlers[i].insn_code = CODE_FOR_nothing;
4427       op->handlers[i].libfunc = 0;
4428     }
4429
4430   if (code != UNKNOWN)
4431     code_to_optab[(int) code] = op;
4432
4433   return op;
4434 }
4435
4436 /* Initialize the libfunc fields of an entire group of entries in some
4437    optab.  Each entry is set equal to a string consisting of a leading
4438    pair of underscores followed by a generic operation name followed by
4439    a mode name (downshifted to lower case) followed by a single character
4440    representing the number of operands for the given operation (which is
4441    usually one of the characters '2', '3', or '4').
4442
4443    OPTABLE is the table in which libfunc fields are to be initialized.
4444    FIRST_MODE is the first machine mode index in the given optab to
4445      initialize.
4446    LAST_MODE is the last machine mode index in the given optab to
4447      initialize.
4448    OPNAME is the generic (string) name of the operation.
4449    SUFFIX is the character which specifies the number of operands for
4450      the given generic operation.
4451 */
4452
4453 static void
4454 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4455     register optab optable;
4456     register int first_mode;
4457     register int last_mode;
4458     register const char *opname;
4459     register int suffix;
4460 {
4461   register int mode;
4462   register unsigned opname_len = strlen (opname);
4463
4464   for (mode = first_mode; (int) mode <= (int) last_mode;
4465        mode = (enum machine_mode) ((int) mode + 1))
4466     {
4467       register const char *mname = GET_MODE_NAME(mode);
4468       register unsigned mname_len = strlen (mname);
4469       register char *libfunc_name = alloca (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, ggc_alloc_string (libfunc_name,
4485                                                        p - libfunc_name));
4486     }
4487 }
4488
4489 /* Initialize the libfunc fields of an entire group of entries in some
4490    optab which correspond to all integer mode operations.  The parameters
4491    have the same meaning as similarly named ones for the `init_libfuncs'
4492    routine.  (See above).  */
4493
4494 static void
4495 init_integral_libfuncs (optable, opname, suffix)
4496     register optab optable;
4497     register const char *opname;
4498     register int suffix;
4499 {
4500   init_libfuncs (optable, SImode, TImode, opname, suffix);
4501 }
4502
4503 /* Initialize the libfunc fields of an entire group of entries in some
4504    optab which correspond to all real mode operations.  The parameters
4505    have the same meaning as similarly named ones for the `init_libfuncs'
4506    routine.  (See above).  */
4507
4508 static void
4509 init_floating_libfuncs (optable, opname, suffix)
4510     register optab optable;
4511     register const char *opname;
4512     register int suffix;
4513 {
4514   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4515 }
4516
4517 rtx
4518 init_one_libfunc (name)
4519      register const char *name;
4520 {
4521   name = ggc_strdup (name);
4522
4523   return gen_rtx_SYMBOL_REF (Pmode, name);
4524 }
4525
4526 /* Mark ARG (which is really an OPTAB *) for GC.  */
4527
4528 void
4529 mark_optab (arg)
4530      void *arg;
4531 {
4532   optab o = *(optab *) arg;
4533   int i;
4534
4535   for (i = 0; i < NUM_MACHINE_MODES; ++i)
4536     ggc_mark_rtx (o->handlers[i].libfunc);
4537 }
4538
4539 /* Call this once to initialize the contents of the optabs
4540    appropriately for the current target machine.  */
4541
4542 void
4543 init_optabs ()
4544 {
4545   unsigned int i, j, k;
4546
4547   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
4548
4549   for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4550     for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4551       for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4552         fixtab[i][j][k] = CODE_FOR_nothing;
4553
4554   for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4555     for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4556       for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4557         fixtrunctab[i][j][k] = CODE_FOR_nothing;
4558
4559   for (i = 0; i < ARRAY_SIZE (floattab); i++)
4560     for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4561       for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4562         floattab[i][j][k] = CODE_FOR_nothing;
4563
4564   for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4565     for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4566       for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4567         extendtab[i][j][k] = CODE_FOR_nothing;
4568
4569   for (i = 0; i < NUM_RTX_CODE; i++)
4570     setcc_gen_code[i] = CODE_FOR_nothing;
4571
4572 #ifdef HAVE_conditional_move
4573   for (i = 0; i < NUM_MACHINE_MODES; i++)
4574     movcc_gen_code[i] = CODE_FOR_nothing;
4575 #endif
4576
4577   add_optab = init_optab (PLUS);
4578   addv_optab = init_optab (PLUS);
4579   sub_optab = init_optab (MINUS);
4580   subv_optab = init_optab (MINUS);
4581   smul_optab = init_optab (MULT);
4582   smulv_optab = init_optab (MULT);
4583   smul_highpart_optab = init_optab (UNKNOWN);
4584   umul_highpart_optab = init_optab (UNKNOWN);
4585   smul_widen_optab = init_optab (UNKNOWN);
4586   umul_widen_optab = init_optab (UNKNOWN);
4587   sdiv_optab = init_optab (DIV);
4588   sdivv_optab = init_optab (DIV);
4589   sdivmod_optab = init_optab (UNKNOWN);
4590   udiv_optab = init_optab (UDIV);
4591   udivmod_optab = init_optab (UNKNOWN);
4592   smod_optab = init_optab (MOD);
4593   umod_optab = init_optab (UMOD);
4594   flodiv_optab = init_optab (DIV);
4595   ftrunc_optab = init_optab (UNKNOWN);
4596   and_optab = init_optab (AND);
4597   ior_optab = init_optab (IOR);
4598   xor_optab = init_optab (XOR);
4599   ashl_optab = init_optab (ASHIFT);
4600   ashr_optab = init_optab (ASHIFTRT);
4601   lshr_optab = init_optab (LSHIFTRT);
4602   rotl_optab = init_optab (ROTATE);
4603   rotr_optab = init_optab (ROTATERT);
4604   smin_optab = init_optab (SMIN);
4605   smax_optab = init_optab (SMAX);
4606   umin_optab = init_optab (UMIN);
4607   umax_optab = init_optab (UMAX);
4608   mov_optab = init_optab (UNKNOWN);
4609   movstrict_optab = init_optab (UNKNOWN);
4610   cmp_optab = init_optab (UNKNOWN);
4611   ucmp_optab = init_optab (UNKNOWN);
4612   tst_optab = init_optab (UNKNOWN);
4613   neg_optab = init_optab (NEG);
4614   negv_optab = init_optab (NEG);
4615   abs_optab = init_optab (ABS);
4616   absv_optab = init_optab (ABS);
4617   one_cmpl_optab = init_optab (NOT);
4618   ffs_optab = init_optab (FFS);
4619   sqrt_optab = init_optab (SQRT);
4620   sin_optab = init_optab (UNKNOWN);
4621   cos_optab = init_optab (UNKNOWN);
4622   strlen_optab = init_optab (UNKNOWN);
4623   cbranch_optab = init_optab (UNKNOWN);
4624   cmov_optab = init_optab (UNKNOWN);
4625   cstore_optab = init_optab (UNKNOWN);
4626
4627   for (i = 0; i < NUM_MACHINE_MODES; i++)
4628     {
4629       movstr_optab[i] = CODE_FOR_nothing;
4630       clrstr_optab[i] = CODE_FOR_nothing;
4631
4632 #ifdef HAVE_SECONDARY_RELOADS
4633       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4634 #endif
4635     }
4636
4637   /* Fill in the optabs with the insns we support.  */
4638   init_all_optabs ();
4639
4640 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4641   /* This flag says the same insns that convert to a signed fixnum
4642      also convert validly to an unsigned one.  */
4643   for (i = 0; i < NUM_MACHINE_MODES; i++)
4644     for (j = 0; j < NUM_MACHINE_MODES; j++)
4645       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4646 #endif
4647
4648   /* Initialize the optabs with the names of the library functions.  */
4649   init_integral_libfuncs (add_optab, "add", '3');
4650   init_floating_libfuncs (add_optab, "add", '3');
4651   init_integral_libfuncs (addv_optab, "addv", '3');
4652   init_floating_libfuncs (addv_optab, "add", '3');
4653   init_integral_libfuncs (sub_optab, "sub", '3');
4654   init_floating_libfuncs (sub_optab, "sub", '3');
4655   init_integral_libfuncs (subv_optab, "subv", '3');
4656   init_floating_libfuncs (subv_optab, "sub", '3');
4657   init_integral_libfuncs (smul_optab, "mul", '3');
4658   init_floating_libfuncs (smul_optab, "mul", '3');
4659   init_integral_libfuncs (smulv_optab, "mulv", '3');
4660   init_floating_libfuncs (smulv_optab, "mul", '3');
4661   init_integral_libfuncs (sdiv_optab, "div", '3');
4662   init_integral_libfuncs (sdivv_optab, "divv", '3');
4663   init_integral_libfuncs (udiv_optab, "udiv", '3');
4664   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4665   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4666   init_integral_libfuncs (smod_optab, "mod", '3');
4667   init_integral_libfuncs (umod_optab, "umod", '3');
4668   init_floating_libfuncs (flodiv_optab, "div", '3');
4669   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4670   init_integral_libfuncs (and_optab, "and", '3');
4671   init_integral_libfuncs (ior_optab, "ior", '3');
4672   init_integral_libfuncs (xor_optab, "xor", '3');
4673   init_integral_libfuncs (ashl_optab, "ashl", '3');
4674   init_integral_libfuncs (ashr_optab, "ashr", '3');
4675   init_integral_libfuncs (lshr_optab, "lshr", '3');
4676   init_integral_libfuncs (smin_optab, "min", '3');
4677   init_floating_libfuncs (smin_optab, "min", '3');
4678   init_integral_libfuncs (smax_optab, "max", '3');
4679   init_floating_libfuncs (smax_optab, "max", '3');
4680   init_integral_libfuncs (umin_optab, "umin", '3');
4681   init_integral_libfuncs (umax_optab, "umax", '3');
4682   init_integral_libfuncs (neg_optab, "neg", '2');
4683   init_floating_libfuncs (neg_optab, "neg", '2');
4684   init_integral_libfuncs (negv_optab, "negv", '2');
4685   init_floating_libfuncs (negv_optab, "neg", '2');
4686   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4687   init_integral_libfuncs (ffs_optab, "ffs", '2');
4688
4689   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4690   init_integral_libfuncs (cmp_optab, "cmp", '2');
4691   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4692   init_floating_libfuncs (cmp_optab, "cmp", '2');
4693
4694 #ifdef MULSI3_LIBCALL
4695   smul_optab->handlers[(int) SImode].libfunc
4696     = init_one_libfunc (MULSI3_LIBCALL);
4697 #endif
4698 #ifdef MULDI3_LIBCALL
4699   smul_optab->handlers[(int) DImode].libfunc
4700     = init_one_libfunc (MULDI3_LIBCALL);
4701 #endif
4702
4703 #ifdef DIVSI3_LIBCALL
4704   sdiv_optab->handlers[(int) SImode].libfunc
4705     = init_one_libfunc (DIVSI3_LIBCALL);
4706 #endif
4707 #ifdef DIVDI3_LIBCALL
4708   sdiv_optab->handlers[(int) DImode].libfunc
4709     = init_one_libfunc (DIVDI3_LIBCALL);
4710 #endif
4711
4712 #ifdef UDIVSI3_LIBCALL
4713   udiv_optab->handlers[(int) SImode].libfunc
4714     = init_one_libfunc (UDIVSI3_LIBCALL);
4715 #endif
4716 #ifdef UDIVDI3_LIBCALL
4717   udiv_optab->handlers[(int) DImode].libfunc
4718     = init_one_libfunc (UDIVDI3_LIBCALL);
4719 #endif
4720
4721 #ifdef MODSI3_LIBCALL
4722   smod_optab->handlers[(int) SImode].libfunc
4723     = init_one_libfunc (MODSI3_LIBCALL);
4724 #endif
4725 #ifdef MODDI3_LIBCALL
4726   smod_optab->handlers[(int) DImode].libfunc
4727     = init_one_libfunc (MODDI3_LIBCALL);
4728 #endif
4729
4730 #ifdef UMODSI3_LIBCALL
4731   umod_optab->handlers[(int) SImode].libfunc
4732     = init_one_libfunc (UMODSI3_LIBCALL);
4733 #endif
4734 #ifdef UMODDI3_LIBCALL
4735   umod_optab->handlers[(int) DImode].libfunc
4736     = init_one_libfunc (UMODDI3_LIBCALL);
4737 #endif
4738
4739   /* Use cabs for DC complex abs, since systems generally have cabs.
4740      Don't define any libcall for SCmode, so that cabs will be used.  */
4741   abs_optab->handlers[(int) DCmode].libfunc
4742     = init_one_libfunc ("cabs");
4743
4744   /* The ffs function operates on `int'.  */
4745   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4746     = init_one_libfunc ("ffs");
4747
4748   extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4749   extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4750   extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4751   extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4752   extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4753
4754   truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4755   truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4756   trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4757   truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4758   trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4759
4760   memcpy_libfunc = init_one_libfunc ("memcpy");
4761   bcopy_libfunc = init_one_libfunc ("bcopy");
4762   memcmp_libfunc = init_one_libfunc ("memcmp");
4763   bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4764   memset_libfunc = init_one_libfunc ("memset");
4765   bzero_libfunc = init_one_libfunc ("bzero");
4766
4767   throw_libfunc = init_one_libfunc ("__throw");
4768   rethrow_libfunc = init_one_libfunc ("__rethrow");
4769   sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4770   sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4771   terminate_libfunc = init_one_libfunc ("__terminate");
4772   eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4773 #ifndef DONT_USE_BUILTIN_SETJMP
4774   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4775   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4776 #else
4777   setjmp_libfunc = init_one_libfunc ("setjmp");
4778   longjmp_libfunc = init_one_libfunc ("longjmp");
4779 #endif
4780
4781   eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4782   nehf2_libfunc = init_one_libfunc ("__nehf2");
4783   gthf2_libfunc = init_one_libfunc ("__gthf2");
4784   gehf2_libfunc = init_one_libfunc ("__gehf2");
4785   lthf2_libfunc = init_one_libfunc ("__lthf2");
4786   lehf2_libfunc = init_one_libfunc ("__lehf2");
4787   unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4788
4789   eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4790   nesf2_libfunc = init_one_libfunc ("__nesf2");
4791   gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4792   gesf2_libfunc = init_one_libfunc ("__gesf2");
4793   ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4794   lesf2_libfunc = init_one_libfunc ("__lesf2");
4795   unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4796
4797   eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4798   nedf2_libfunc = init_one_libfunc ("__nedf2");
4799   gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4800   gedf2_libfunc = init_one_libfunc ("__gedf2");
4801   ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4802   ledf2_libfunc = init_one_libfunc ("__ledf2");
4803   unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4804
4805   eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4806   nexf2_libfunc = init_one_libfunc ("__nexf2");
4807   gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4808   gexf2_libfunc = init_one_libfunc ("__gexf2");
4809   ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4810   lexf2_libfunc = init_one_libfunc ("__lexf2");
4811   unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4812
4813   eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4814   netf2_libfunc = init_one_libfunc ("__netf2");
4815   gttf2_libfunc = init_one_libfunc ("__gttf2");
4816   getf2_libfunc = init_one_libfunc ("__getf2");
4817   lttf2_libfunc = init_one_libfunc ("__lttf2");
4818   letf2_libfunc = init_one_libfunc ("__letf2");
4819   unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4820
4821   floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4822   floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4823   floattisf_libfunc = init_one_libfunc ("__floattisf");
4824
4825   floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4826   floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4827   floattidf_libfunc = init_one_libfunc ("__floattidf");
4828
4829   floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4830   floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4831   floattixf_libfunc = init_one_libfunc ("__floattixf");
4832
4833   floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4834   floatditf_libfunc = init_one_libfunc ("__floatditf");
4835   floattitf_libfunc = init_one_libfunc ("__floattitf");
4836
4837   fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4838   fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4839   fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4840
4841   fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4842   fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4843   fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4844
4845   fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4846   fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4847   fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4848
4849   fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4850   fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4851   fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4852
4853   fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4854   fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4855   fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4856
4857   fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4858   fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4859   fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4860
4861   fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4862   fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4863   fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4864
4865   fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4866   fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4867   fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4868
4869   /* For check-memory-usage.  */
4870   chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4871   chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4872   chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4873   chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4874   chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4875
4876   /* For function entry/exit instrumentation.  */
4877   profile_function_entry_libfunc
4878     = init_one_libfunc ("__cyg_profile_func_enter");
4879   profile_function_exit_libfunc
4880     = init_one_libfunc ("__cyg_profile_func_exit");
4881
4882 #ifdef HAVE_conditional_trap
4883   init_traps ();
4884 #endif
4885
4886 #ifdef INIT_TARGET_OPTABS
4887   /* Allow the target to add more libcalls or rename some, etc.  */
4888   INIT_TARGET_OPTABS;
4889 #endif
4890
4891   /* Add these GC roots.  */
4892   ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4893   ggc_add_rtx_root (libfunc_table, LTI_MAX);
4894 }
4895 \f
4896 #ifdef BROKEN_LDEXP
4897
4898 /* SCO 3.2 apparently has a broken ldexp.  */
4899
4900 double
4901 ldexp(x,n)
4902      double x;
4903      int n;
4904 {
4905   if (n > 0)
4906     while (n--)
4907       x *= 2;
4908
4909   return x;
4910 }
4911 #endif /* BROKEN_LDEXP */
4912 \f
4913 #ifdef HAVE_conditional_trap
4914 /* The insn generating function can not take an rtx_code argument.
4915    TRAP_RTX is used as an rtx argument.  Its code is replaced with
4916    the code to be used in the trap insn and all other fields are
4917    ignored.  */
4918 static rtx trap_rtx;
4919
4920 static void
4921 init_traps ()
4922 {
4923   if (HAVE_conditional_trap)
4924     {
4925       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4926       ggc_add_rtx_root (&trap_rtx, 1);
4927     }
4928 }
4929 #endif
4930
4931 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4932    CODE.  Return 0 on failure.  */
4933
4934 rtx
4935 gen_cond_trap (code, op1, op2, tcode)
4936   enum rtx_code code ATTRIBUTE_UNUSED;
4937   rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4938 {
4939   enum machine_mode mode = GET_MODE (op1);
4940
4941   if (mode == VOIDmode)
4942     return 0;
4943
4944 #ifdef HAVE_conditional_trap
4945   if (HAVE_conditional_trap
4946       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4947     {
4948       rtx insn;
4949       start_sequence();
4950       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4951       PUT_CODE (trap_rtx, code);
4952       insn = gen_conditional_trap (trap_rtx, tcode);
4953       if (insn)
4954         {
4955           emit_insn (insn);
4956           insn = gen_sequence ();
4957         }
4958       end_sequence();
4959       return insn;
4960     }
4961 #endif
4962
4963   return 0;
4964 }