OSDN Git Service

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