OSDN Git Service

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