OSDN Git Service

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