OSDN Git Service

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