OSDN Git Service

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