OSDN Git Service

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