OSDN Git Service

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