OSDN Git Service

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