OSDN Git Service

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