OSDN Git Service

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