OSDN Git Service

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