OSDN Git Service

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