OSDN Git Service

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